本页目录
构建聊天机器人时,记录对话历史是非常常见的需求。
这样 LLM 才能了解已经发生过的对话。
你也就可以直接提出后续问题,不必每次都重新描述背景。
而且,理解对话如何持久化,对于通过网络与 LLM 通信也很重要。
本示例会展示如何使用 Vercel AI SDK 完成这件事。
这个 CoreMessage 类型
先了解一下对话历史可能采用的结构。
AI SDK 暴露了一个名为 CoreMessage的类型,它是表示对话中一条消息的对象。
理解这个类型之后,就能理解对话历史的结构,我保证。
滚动式代码讲解
动手试试看它包含什么。创建一个 messages 数组,并把它的类型设为 CoreMessage 数组。
每条消息都必须包含 role 属性,这是一个字符串,可以是 user、system、assistant 或 tool。
每条消息还必须包含一个 content 属性,也就是消息内容。
在这个例子中,对话历史只包含一条用户消息:“Hello, you!”。
为了表示 LLM 的回复,使用 assistant 角色:
前面简单介绍过系统提示词。在消息历史中,它们的 role 是 system.
这里要求 LLM 向所有与它对话的人问候。
import { type CoreMessage } from "ai";const messages: CoreMessage[] = [];
后面介绍工具调用时会再看工具。
随着对话不断变长,这个数组会加入更多 user and assistant 消息。
理解 messages 数组后,把它应用到一个接近真实场景的例子中。
想继续深入: 加入“面向真正工程师的 AI 编码”候补名单
搭建服务器
这一次,我们第一次搭建一个服务器。
滚动式代码讲解
把它放进一个 startServer 函数中:
使用 Hono 包创建服务器:
为服务器添加路由:
然后使用 serve from @hono/node-server:
最后使用 node:events 等待启动,并返回 server:
export const startServer = async () => {};
这样就得到一个便捷函数,可以调用它在 localhost:4317.
接下来构建 API 调用:
滚动式代码讲解
我们的 /api/get-completions 路由会接收一个由 CoreMessage 对象组成的数组。
然后把完整对话历史传给 generateText.
LLM 会根据对话历史判断接下来应该说什么。
它建议的消息会被添加到 result.response.messages.
因此可以使用 ctx.json.
import { type CoreMessage } from "ai";app.post("/api/get-completions", (ctx) => {const messages: CoreMessage[] = await ctx.req.json();});
总结一下,我们构建了一个 API 端点:接收对话历史,并返回 LLM 接下来会说的消息。
这是一个非常常见的模式。这意味着我们的服务器完全 无状态.
由客户端负责追踪对话。
也可以把对话存储在服务器上,但这种方式更适合作为入门。
调用服务器
现在有了服务器,就可以从客户端调用它。我在 Node 上运行,但同样可以轻松地在浏览器中运行。
滚动式代码讲解
创建一个新的消息数组,并启动服务器:
使用 fetch 把消息发送给服务器,再使用 res.json() 把响应转换为 JavaScript 对象。
最后,把新消息追加到对话历史并记录出来。
import { type CoreMessage } from "ai";import { startServer } from "./server.ts";const messagesToSend: CoreMessage[] = [{role: "user",content: "What's the capital of Wales?",},];await startServer();
最终输出大致如下:
[{"role": "user","content": "What's the capital of Wales?"},{"role": "assistant","content": [{"type": "text","text": "The capital of Wales is Cardiff."}]}]
这个数组已经可以接收另一条 role 为 user的消息,整个过程可以重复。
总结
本示例展示了如何使用 Vercel AI SDK 追踪对话历史。
我们了解了 messages 数组及其中的各种角色。
我们也看到了如何搭建一个接收并追加对话历史的服务器。
还看到了如何从客户端调用这个服务器。