跳到主要内容
Open on GitHub

PremAI

PremAI 是一个一体化平台,可简化由生成式 AI 驱动的强大、可用于生产的应用程序的创建。通过简化开发过程,PremAI 使您可以专注于增强用户体验并推动应用程序的整体增长。您可以在此处快速开始使用我们的平台。

ChatPremAI

此示例介绍了如何使用 LangChain 通过 ChatPremAI 与不同的聊天模型进行交互

安装和设置

我们首先安装 langchainpremai-sdk。您可以输入以下命令进行安装

pip install premai langchain

在继续之前,请确保您已在 PremAI 上创建帐户并已创建一个项目。如果还没有,请参阅快速入门指南以开始使用 PremAI 平台。创建您的第一个项目并获取您的 API 密钥。

from langchain_core.messages import HumanMessage, SystemMessage
from langchain_community.chat_models import ChatPremAI

在 LangChain 中设置 PremAI 客户端

导入所需的模块后,让我们设置我们的客户端。现在,我们假设我们的 project_id8。但请确保使用您的项目 ID,否则会抛出错误。

要将 langchain 与 prem 一起使用,您无需传递任何模型名称或使用我们的聊天客户端设置任何参数。默认情况下,它将使用 LaunchPad 中使用的模型名称和参数。

注意:如果您在设置客户端时更改 model 或任何其他参数(如 temperaturemax_tokens),它将覆盖 LaunchPad 中使用的现有默认配置。

import os
import getpass

if "PREMAI_API_KEY" not in os.environ:
os.environ["PREMAI_API_KEY"] = getpass.getpass("PremAI API Key:")

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)

您可以在此处提供系统提示,如下所示

system_message = SystemMessage(content="You are a friendly assistant.")
human_message = HumanMessage(content="Who are you?")

chat.invoke([system_message, human_message])

您还可以在调用模型时更改生成参数。以下是如何做到这一点

chat.invoke(
[system_message, human_message],
temperature = 0.7, max_tokens = 20, top_p = 0.95
)

如果您要在此处放置系统提示,则它将覆盖您从平台部署应用程序时固定的系统提示。

您可以在此处找到所有可选参数。除这些支持的参数之外的任何参数将在调用模型之前自动删除。

通过 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 information\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"
}
]
}

因此,这也意味着当您使用 Prem 平台时,您无需构建自己的 RAG 管道。Prem 使用其自己的 RAG 技术来为检索增强生成提供一流的性能。

理想情况下,您无需在此处连接存储库 ID 即可获得检索增强生成。如果您已在 prem 平台中连接了存储库,您仍然可以获得相同的结果。

流式传输

在本节中,让我们看看如何使用 langchain 和 PremAI 流式传输令牌。以下是如何做到这一点。

import sys

for chunk in chat.stream("hello how are you"):
sys.stdout.write(chunk.content)
sys.stdout.flush()

与上面类似,如果您想覆盖 system-prompt 和生成参数,您需要添加以下内容

import sys

for chunk in chat.stream(
"hello how are you",
system_prompt = "You are an helpful assistant", temperature = 0.7, max_tokens = 20
):
sys.stdout.write(chunk.content)
sys.stdout.flush()

这将逐个流式传输令牌。

请注意:截至目前,不支持使用流式传输的 RAG。但是,我们仍然通过我们的 API 支持它。您可以在此处了解更多相关信息。

Prem 模板

编写 Prompt 模板可能非常混乱。Prompt 模板很长,难以管理,并且必须不断调整以改进并在整个应用程序中保持一致。

使用 Prem,编写和管理提示可以非常容易。 启动面板内的 模板 选项卡可帮助您编写所需的任意数量的提示,并在 SDK 内部使用它来使您的应用程序使用这些提示运行。您可以在此处阅读有关 Prompt 模板的更多信息。

要将 Prem 模板与 LangChain 原生结合使用,您需要在 HumanMessage 中传递一个 ID。此 ID 应该是您的 Prompt 模板的变量名称。 HumanMessage 中的 content 应该是该变量的值。

例如,假设您的 prompt 模板是这样的

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 Client。请注意:不要忘记传递额外的 template_id 以使用 Prem 模板调用生成。如果您不了解 template_id,您可以在我们的文档中了解更多信息。这是一个示例

template_id = "78069ce8-xxxxx-xxxxx-xxxx-xxx"
response = chat.invoke([human_message], template_id=template_id)

Prem 模板也适用于流式传输。

Prem 嵌入

在本节中,我们将介绍如何使用 LangChain 的 PremEmbeddings 访问不同的嵌入模型。让我们从导入我们的模块并设置我们的 API 密钥开始。

import os
import getpass
from langchain_community.embeddings import PremEmbeddings


if os.environ.get("PREMAI_API_KEY") is None:
os.environ["PREMAI_API_KEY"] = getpass.getpass("PremAI API Key:")

我们支持许多最先进的嵌入模型。您可以在此处查看我们支持的 LLM 和嵌入模型列表。现在,让我们以 text-embedding-3-large 模型为例。


model = "text-embedding-3-large"
embedder = PremEmbeddings(project_id=8, model=model)

query = "Hello, this is a test query"
query_result = embedder.embed_query(query)

# Let's print the first five elements of the query embedding vector

print(query_result[:5])
注意

与聊天不同,对于 PremAIEmbeddings,model_name 参数的设置是强制性的。

最后,让我们嵌入一些示例文档

documents = [
"This is document1",
"This is document2",
"This is document3"
]

doc_result = embedder.embed_documents(documents)

# Similar to the previous result, let's print the first five element
# of the first document vector

print(doc_result[0][:5])
print(f"Dimension of embeddings: {len(query_result)}")

嵌入维度:3072

doc_result[:5]

结果

[-0.02129288576543331, 0.0008162345038726926, -0.004556538071483374, 0.02918623760342598, -0.02547479420900345]

工具/函数调用

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
API 参考:tool

将工具模式与我们的 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)

由于工具调用分两个阶段进行,其中

  1. 在我们的第一次调用中,我们收集了 LLM 决定使用的所有工具,以便它可以获得结果作为附加上下文,从而给出更准确和无幻觉的结果。

  2. 在我们的第二次调用中,我们将解析 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"]))
API 参考:ToolMessage

最后,我们调用 LLM(与工具绑定),并在其上下文中添加函数响应。

response = llm_with_tools.invoke(messages)
print(response.content)

输出

The final answers are:

- 3 * 12 = 36
- 11 + 49 = 60

定义工具模式:Pydantic 类 Optional

上面我们展示了如何使用 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]
API 参考:PydanticToolsParser

现在,我们可以将它们绑定到聊天模型并直接获得结果

chain = llm_with_tools | PydanticToolsParser(tools=[multiply, add])
chain.invoke(query)

输出

[multiply(a=3, b=12), add(a=11, b=49)]

现在,如上所述,我们解析并运行这些函数,并再次调用 LLM 以获得结果。


此页是否对您有帮助?