ChatPremAI
PremAI 是一個多合一平台,可簡化由生成式 AI 驅動、穩健且可投入生產環境的應用程式的建立。透過簡化開發流程,PremAI 讓您可以專注於提升使用者體驗並推動應用程式的整體成長。您可以在此處快速開始使用我們的平台。
本範例說明如何使用 LangChain 與 ChatPremAI
互動,以使用不同的聊天模型
安裝與設定
我們先安裝 langchain
和 premai-sdk
。您可以輸入以下命令來安裝
pip install premai langchain
在繼續之前,請確認您已在 PremAI 上建立帳戶並已建立專案。如果沒有,請參考快速入門指南,以開始使用 PremAI 平台。建立您的第一個專案並取得您的 API 金鑰。
from langchain_community.chat_models import ChatPremAI
from langchain_core.messages import HumanMessage, SystemMessage
在 LangChain 中設定 PremAI 用戶端
匯入所需的模組後,讓我們設定用戶端。現在,假設我們的 project_id
是 8
。但請務必使用您的專案 ID,否則會擲回錯誤。
若要將 langchain 與 prem 搭配使用,您不需要傳遞任何模型名稱或使用我們的聊天用戶端設定任何參數。依預設,它會使用 LaunchPad 中使用的模型名稱和參數。
注意:如果您在設定用戶端時變更
model
或任何其他參數 (例如temperature
或max_tokens
),它將覆寫 LaunchPad 中使用的現有預設組態。
import getpass
import os
# First step is to set up the env variable.
# you can also pass the API key while instantiating the model but this
# comes under a best practices to set it as env variable.
if os.environ.get("PREMAI_API_KEY") is None:
os.environ["PREMAI_API_KEY"] = getpass.getpass("PremAI API Key:")
# By default it will use the model which was deployed through the platform
# in my case it will is "gpt-4o"
chat = ChatPremAI(project_id=1234, model_name="gpt-4o")
聊天完成
ChatPremAI
支援兩種方法:invoke
(與 generate
相同) 和 stream
。
第一種方法會提供靜態結果。而第二種方法會逐一串流 token。以下說明如何產生類似聊天的完成。
human_message = HumanMessage(content="Who are you?")
response = chat.invoke([human_message])
print(response.content)
I am an AI language model created by OpenAI, designed to assist with answering questions and providing information based on the context provided. How can I help you today?
以上看起來很有趣,對吧?我將預設的 lanchpad 系統提示設定為:Always sound like a pirate
您也可以覆寫預設的系統提示 (如果需要)。以下說明如何執行此操作。
system_message = SystemMessage(content="You are a friendly assistant.")
human_message = HumanMessage(content="Who are you?")
chat.invoke([system_message, human_message])
AIMessage(content="I'm your friendly assistant! How can I help you today?", response_metadata={'document_chunks': [{'repository_id': 1985, 'document_id': 1306, 'chunk_id': 173899, 'document_name': '[D] Difference between sparse and dense informati…', 'similarity_score': 0.3209080100059509, 'content': "with the difference or anywhere\nwhere I can read about it?\n\n\n 17 9\n\n\n u/ScotiabankCanada • Promoted\n\n\n Accelerate your study permit process\n with Scotiabank's Student GIC\n Program. We're here to help you tur…\n\n\n startright.scotiabank.com Learn More\n\n\n Add a Comment\n\n\nSort by: Best\n\n\n DinosParkour • 1y ago\n\n\n Dense Retrieval (DR) m"}]}, id='run-510bbd0e-3f8f-4095-9b1f-c2d29fd89719-0')
您可以在此處提供系統提示,如下所示
chat.invoke([system_message, human_message], temperature=0.7, max_tokens=10, top_p=0.95)
/home/anindya/prem/langchain/libs/community/langchain_community/chat_models/premai.py:355: UserWarning: WARNING: Parameter top_p is not supported in kwargs.
warnings.warn(f"WARNING: Parameter {key} is not supported in kwargs.")
AIMessage(content="Hello! I'm your friendly assistant. How can I", response_metadata={'document_chunks': [{'repository_id': 1985, 'document_id': 1306, 'chunk_id': 173899, 'document_name': '[D] Difference between sparse and dense informati…', 'similarity_score': 0.3209080100059509, 'content': "with the difference or anywhere\nwhere I can read about it?\n\n\n 17 9\n\n\n u/ScotiabankCanada • Promoted\n\n\n Accelerate your study permit process\n with Scotiabank's Student GIC\n Program. We're here to help you tur…\n\n\n startright.scotiabank.com Learn More\n\n\n Add a Comment\n\n\nSort by: Best\n\n\n DinosParkour • 1y ago\n\n\n Dense Retrieval (DR) m"}]}, id='run-c4b06b98-4161-4cca-8495-fd2fc98fa8f8-0')
如果您要在此處放置系統提示,則會覆寫從平台部署應用程式時固定的系統提示。
透過 Prem 儲存庫提供原生 RAG 支援
Prem 儲存庫允許使用者上傳文件 (.txt、.pdf 等),並將這些儲存庫連接到 LLM。您可以將 Prem 儲存庫視為原生 RAG,其中每個儲存庫都可以視為向量資料庫。您可以連接多個儲存庫。您可以在此處深入瞭解儲存庫。
langchain premai 也支援儲存庫。以下說明如何執行此操作。
query = "Which models are used for dense retrieval"
repository_ids = [
1985,
]
repositories = dict(ids=repository_ids, similarity_threshold=0.3, limit=3)
首先,我們從定義具有一些儲存庫 ID 的儲存庫開始。請確認這些 ID 是有效的儲存庫 ID。您可以在此處深入瞭解如何取得儲存庫 ID。
請注意:與
model_name
類似,當您叫用引數repositories
時,您可能會覆寫 launchpad 中連接的儲存庫。
現在,我們將儲存庫與聊天物件連接,以叫用基於 RAG 的產生。
import json
response = chat.invoke(query, max_tokens=100, repositories=repositories)
print(response.content)
print(json.dumps(response.response_metadata, indent=4))
Dense retrieval models typically include:
1. **BERT-based Models**: Such as DPR (Dense Passage Retrieval) which uses BERT for encoding queries and passages.
2. **ColBERT**: A model that combines BERT with late interaction mechanisms.
3. **ANCE (Approximate Nearest Neighbor Negative Contrastive Estimation)**: Uses BERT and focuses on efficient retrieval.
4. **TCT-ColBERT**: A variant of ColBERT that uses a two-tower
{
"document_chunks": [
{
"repository_id": 1985,
"document_id": 1306,
"chunk_id": 173899,
"document_name": "[D] Difference between sparse and dense informati\u2026",
"similarity_score": 0.3209080100059509,
"content": "with the difference or anywhere\nwhere I can read about it?\n\n\n 17 9\n\n\n u/ScotiabankCanada \u2022 Promoted\n\n\n Accelerate your study permit process\n with Scotiabank's Student GIC\n Program. We're here to help you tur\u2026\n\n\n startright.scotiabank.com Learn More\n\n\n Add a Comment\n\n\nSort by: Best\n\n\n DinosParkour \u2022 1y ago\n\n\n Dense Retrieval (DR) m"
}
]
}
理想情況下,您不需要在此處連接儲存庫 ID 即可取得檢索增強產生。如果您已在 prem 平台中連接儲存庫,仍然可以獲得相同的結果。
Prem 範本
撰寫提示範本可能非常雜亂。提示範本很長、難以管理,而且必須不斷調整以改進並在整個應用程式中保持一致。
使用 Prem,撰寫和管理提示可能非常容易。 launchpad 內的 Templates 標籤可協助您撰寫所需的任意數量的提示,並在 SDK 內使用它來讓您的應用程式使用這些提示執行。您可以在此處閱讀更多關於提示範本的資訊。
若要將 Prem 範本與 LangChain 原生搭配使用,您需要傳遞 HumanMessage
的 ID。此 ID 應為提示範本的變數名稱。HumanMessage
中的 content
應為該變數的值。
假設您的提示範本如下
Say hello to my name and say a feel-good quote
from my age. My name is: {name} and age is {age}
現在,您的 human_messages 應如下所示
human_messages = [
HumanMessage(content="Shawn", id="name"),
HumanMessage(content="22", id="age"),
]
將此 human_messages
傳遞至 ChatPremAI 用戶端。請注意:請勿忘記傳遞額外的 template_id
,以使用 Prem 範本叫用產生。如果您不知道 template_id
,可以在我們的文件中深入瞭解。以下範例
template_id = "78069ce8-xxxxx-xxxxx-xxxx-xxx"
response = chat.invoke([human_messages], template_id=template_id)
print(response.content)
串流中也提供 Prem 範本功能。
串流
在本節中,讓我們看看如何使用 langchain 和 PremAI 串流 token。以下說明如何執行此操作。
import sys
for chunk in chat.stream("hello how are you"):
sys.stdout.write(chunk.content)
sys.stdout.flush()
It looks like your message got cut off. If you need information about Dense Retrieval (DR) or any other topic, please provide more details or clarify your question.
與上述類似,如果您想要覆寫系統提示和產生參數,則需要新增以下內容
import sys
# For some experimental reasons if you want to override the system prompt then you
# can pass that here too. However it is not recommended to override system prompt
# of an already deployed model.
for chunk in chat.stream(
"hello how are you",
system_prompt="act like a dog",
temperature=0.7,
max_tokens=200,
):
sys.stdout.write(chunk.content)
sys.stdout.flush()
Woof! 🐾 How can I help you today? Want to play fetch or maybe go for a walk 🐶🦴
工具/函式呼叫
LangChain PremAI 支援工具/函式呼叫。工具/函式呼叫允許模型透過產生符合使用者定義結構描述的輸出來回應給定的提示。
注意: 目前版本的 LangChain ChatPremAI 不支援具有串流支援的函式/工具呼叫。具有函式呼叫的串流支援即將推出。
將工具傳遞至模型
為了傳遞工具並讓 LLM 選擇它需要呼叫的工具,我們需要傳遞工具結構描述。工具結構描述是函式定義以及關於函式的作用、函式的每個引數是什麼等的正確文件字串。以下是一些具有其結構描述的簡單算術函式。
注意: 定義函式/工具結構描述時,請勿忘記新增關於函式引數的資訊,否則會擲回錯誤。
from langchain_core.tools import tool
from pydantic import BaseModel, Field
# Define the schema for function arguments
class OperationInput(BaseModel):
a: int = Field(description="First number")
b: int = Field(description="Second number")
# Now define the function where schema for argument will be OperationInput
@tool("add", args_schema=OperationInput, return_direct=True)
def add(a: int, b: int) -> int:
"""Adds a and b.
Args:
a: first int
b: second int
"""
return a + b
@tool("multiply", args_schema=OperationInput, return_direct=True)
def multiply(a: int, b: int) -> int:
"""Multiplies a and b.
Args:
a: first int
b: second int
"""
return a * b
將工具結構描述與我們的 LLM 繫結
我們現在將使用 bind_tools
方法將上述函式轉換為「工具」,並將其與模型繫結。這表示我們每次叫用模型時都會傳遞這些工具資訊。
tools = [add, multiply]
llm_with_tools = chat.bind_tools(tools)
在此之後,我們會從模型取得回應,該模型現在已與工具繫結。
query = "What is 3 * 12? Also, what is 11 + 49?"
messages = [HumanMessage(query)]
ai_msg = llm_with_tools.invoke(messages)
如我們所見,當我們的聊天模型與工具繫結時,它會根據給定的提示依序呼叫正確的工具集。
ai_msg.tool_calls
[{'name': 'multiply',
'args': {'a': 3, 'b': 12},
'id': 'call_A9FL20u12lz6TpOLaiS6rFa8'},
{'name': 'add',
'args': {'a': 11, 'b': 49},
'id': 'call_MPKYGLHbf39csJIyb5BZ9xIk'}]
我們將上面顯示的訊息附加到 LLM,作為上下文並讓 LLM 知道它已呼叫的所有函式。
messages.append(ai_msg)
由於工具呼叫分為兩個階段,其中
-
在第一次呼叫中,我們收集了 LLM 決定使用的所有工具,以便它可以取得結果作為新增的上下文,以提供更準確且無幻覺的結果。
-
在第二次呼叫中,我們將剖析 LLM 決定的這些工具集並執行它們 (在我們的例子中,它將是我們定義的函式,以及 LLM 擷取的引數) 並將此結果傳遞給 LLM
from langchain_core.messages import ToolMessage
for tool_call in ai_msg.tool_calls:
selected_tool = {"add": add, "multiply": multiply}[tool_call["name"].lower()]
tool_output = selected_tool.invoke(tool_call["args"])
messages.append(ToolMessage(tool_output, tool_call_id=tool_call["id"]))
最後,我們使用新增到其上下文中的函式回應來呼叫 LLM (與工具繫結)。
response = llm_with_tools.invoke(messages)
print(response.content)
The final answers are:
- 3 * 12 = 36
- 11 + 49 = 60
定義工具結構描述:Pydantic 類別
上面我們展示了如何使用 tool
裝飾器定義結構描述,但是我們可以等效地使用 Pydantic 定義結構描述。當您的工具輸入更複雜時,Pydantic 會很有用
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
class add(BaseModel):
"""Add two integers together."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
class multiply(BaseModel):
"""Multiply two integers together."""
a: int = Field(..., description="First integer")
b: int = Field(..., description="Second integer")
tools = [add, multiply]
現在,我們可以將它們繫結到聊天模型並直接取得結果
chain = llm_with_tools | PydanticToolsParser(tools=[multiply, add])
chain.invoke(query)
[multiply(a=3, b=12), add(a=11, b=49)]
現在,如上所述,我們剖析並執行此函式,然後再次呼叫 LLM 以取得結果。