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
。
第一个将为我们提供静态结果。而第二个将逐个流式传输令牌。以下是如何生成类似聊天的补全。
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?
上面看起来很有趣吧?我将我的默认 launchpad 系统提示设置为: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 中使用它们来使您的应用程序使用这些提示运行。您可以在此处阅读有关提示模板的更多信息。
要使用 LangChain 本机使用 Prem 模板,您需要在 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 流式传输令牌。这是您可以使用的方式。
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 以获得结果。