Skip to main content
PremAI 是一个一体化平台,简化了由生成式 AI 驱动的强大、生产就绪应用程序的创建。通过简化开发流程,PremAI 让您专注于提升用户体验并推动应用程序整体增长。您可以快速开始使用 我们的平台

ChatPremAI

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

安装与设置

我们从安装 langchainpremai-sdk 开始。您可以输入以下命令安装:
pip install premai langchain
在继续之前,请确保您已在 PremAI 上创建账户并已创建项目。如果没有,请参阅 快速入门 指南开始使用 PremAI 平台。创建您的第一个项目并获取 API 密钥。
from langchain.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-4.1")

聊天补全

ChatPremAI 支持两种方法:invoke(与 generate 相同)和 stream 第一种方法会给出静态结果。而第二种方法会逐个 Token 流式传输。以下是如何生成类似聊天的补全。
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 等)并将这些仓库连接到 LLMs。您可以将 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 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 流式传输 Token。以下是操作方法。
import sys

for chunk in chat.stream("hello how are you"):
    sys.stdout.write(chunk.content)
    sys.stdout.flush()
与上面类似,如果您想覆盖系统提示和生成参数,您需要添加以下内容:
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()
这将逐个 Token 流式传输。
请注意:截至目前,不支持带有流式传输的 RAG。但我们仍然通过 API 支持它。您可以在 此处 了解更多信息。

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_message], template_id=template_id)
Prem 模板也可用于流式传输。

Prem 嵌入

在本节中,我们介绍如何使用 PremEmbeddings 与 LangChain 访问不同的嵌入模型。让我们从导入模块并设置 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:")

我们支持许多最先进的嵌入模型。您可以在 此处 查看我们支持的 LLMs 和嵌入模型列表。对于本例,让我们使用 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)

# 打印查询嵌入向量的前五个元素

print(query_result[:5])
与聊天不同,对于 PremAIEmbeddings 设置 model_name 参数是强制性的。
最后,让我们嵌入一些示例文档
documents = [
    "This is document1",
    "This is document2",
    "This is document3"
]

doc_result = embedder.embed_documents(documents)

# 与前面的结果类似,打印第一个文档向量的前五个元素

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.tools import tool
from pydantic import BaseModel, Field

# 定义函数参数的模式
class OperationInput(BaseModel):
    a: int = Field(description="First number")
    b: int = Field(description="Second number")


# 现在定义函数,参数模式将是 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)
由于工具调用分两个阶段进行:
  1. 在第一次调用中,我们收集了 LLM 决定使用的所有工具,以便它可以将结果作为附加上下文,从而给出更准确、无幻觉的结果。
  2. 在第二次调用中,我们将解析由 LLM 决定的工具集并运行它们(在我们的情况下,将是我们定义的函数,使用 LLM 提取的参数)并将此结果传递给 LLM。
from langchain.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 类 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]
现在,我们可以将它们绑定到聊天模型并直接获取结果:
chain = llm_with_tools | PydanticToolsParser(tools=[multiply, add])
chain.invoke(query)
输出
[multiply(a=3, b=12), add(a=11, b=49)]
现在,如上所述,我们解析这些并运行这些函数,然后再次调用 LLM 以获取结果。