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
。但請確保您使用您的 project-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
時,您可能會覆寫在啟動板中連接的儲存庫。
現在,我們將儲存庫與我們的聊天物件連接起來,以叫用基於 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,編寫和管理提示詞變得超級容易。 啟動面板內的 Templates 標籤可以幫助您編寫所需的提示詞,並在 SDK 內使用它們,讓您的應用程式利用這些提示詞運行。您可以在這裡閱讀更多關於提示詞範本的資訊。
若要使用 LangChain 原生 Prem 範本,您需要傳遞一個 id 給 HumanMessage
。這個 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.
與上述類似,如果您想覆寫 system-prompt 和生成參數,您需要添加以下內容:
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 支援工具/函數呼叫。工具/函數呼叫允許模型通過生成符合使用者定義 schema 的輸出來回應給定的提示詞。
注意: 目前版本的 LangChain ChatPremAI 不支援具有串流支援的函數/工具呼叫。具有函數呼叫的串流支援即將推出。
將工具傳遞給模型
為了傳遞工具並讓 LLM 選擇它需要呼叫的工具,我們需要傳遞一個工具 schema。工具 schema 是函數定義以及適當的 docstring,說明函數的功能、函數的每個參數是什麼等等。以下是一些簡單的算術函數及其 schema。
注意: 在定義函數/工具 schema 時,不要忘記添加有關函數參數的資訊,否則會引發錯誤。
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
將工具 schema 與我們的 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
定義工具 schema:Pydantic class
上面我們展示了如何使用 tool
裝飾器定義 schema,但是我們可以等效地使用 Pydantic 定義 schema。當您的工具輸入更複雜時,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 以獲得結果。