LV020-API调用
一、概述
AI 助手应该是什么样的?
(1)懂我们的意图
(2)深入聊天
(3)记得我们的喜好
这样的应用背后,我们需要解决三个核心问题:
- 如何让它“听话”并且”说的好“?参数控制
- 如何让“它不健忘”,能连贯的对话?对话管理
- 如何让它“认识我们”,提供个性化服务?状态管理
二、API 简介
1. 什么是 API?
1.1 基本概念
API(Application Programming Interface,应用程序编程接口)是一组预先定义的规则和协议,允许不同的软件系统之间进行通信和数据交换。可以将 API 理解为 "软件之间的对话语言"——当代码需要调用某个远程服务(如 AI 模型)时,按照 API 规定的格式发送请求,服务端按照规定的格式返回结果。
Tips:在这里,简单说的话这个 API 的 作用就是指向特定的 ai 服务(例如文本生成、图像理解等)。
1.2 一个比喻
用餐厅比喻来理解三者的对应关系:
| 餐厅角色 | 对应角色 | 说明 |
|---|---|---|
| 顾客 | 你的应用程序 | 想吃一道复杂的菜(比如 "佛跳墙"),但没有厨房、食材和手艺,只能坐在餐桌旁告诉服务员想吃什么 |
| 后厨 | AI 大模型 (DeepSeek、GLM、GPT 等) | 拥有顶级厨具(成千上万的 GPU)、珍贵食材(海量训练数据)和顶尖厨师(复杂算法),但后厨不对外开放,不能直接进去 |
| 服务员 + 菜单 | API | 你无法直接进后厨点菜,必须通过服务员。菜单(API 文档)列出能做什么——文本总结、代码生成、翻译、问答,以及需要提供什么信息。你按菜单点餐(发送请求),服务员把订单送到后厨,做好后再端回给你 |
┌──────────┐ (1)Order ┌──────────┐ (2)Forward ┌──────────┐
│ │ ───────────────> │ │ ───────────────> │ │
│ Customer │ (Send Request) │ Waiter │ (Forward Req) │ Kitchen │
│ (You) │ │ (API) │ │(AI Model)│
│ │ <─────────────── │ │ <─────────────── │ │
└──────────┘ (4)Serve └──────────┘ (3)Return └──────────┘
(Return Result) (Model Output)
Menu = API Doc Order = Payload VIP Card = API Key1.3 本质
API 调用的本质是一次 "意图的编码和解码的过程":
- 编码意图:把人类语言和指令转换为结构化数据,例如 JSON 格式
- API 传输:通过标准协议传递编码后的意图
- 解码响应:将 AI 的输出换回可理解的形式
2. 什么时候需要 API
本地部署的模型本身不需要依赖外部的 API,但为了让它能被方便地使用,我们通常会为它 "创建" 一个本地的 API 服务。
- 本地部署的模型:就像厨房里的 全套厨具和食材
- 模型文件:就是菜谱
- 为模型创建本地 API:相当于在家里定了一个 点餐和上菜的规则
2.1 不需要 API 的情况:直接调用("自己下厨")
这种方式下,我们和模型是 "零距离" 接触。比如我们现在写了一个 Python 脚本,用来处理本地文件。脚本直接加载模型,处理数据,然后输出结果。整个过程中,只有我们这个脚本在和模型互动。
【优点】简单、快速、延迟极低。因为没有网络通信的开销。
【缺点】不灵活。这个模型能力被 "锁死" 在这个脚本里了,其他程序或用户无法使用它。
2.2 需要 API:服务化部署("在家开家庭餐厅")
这种方式下,我们为模型创建一个服务,让它能接受来自各方的请求。比如我们想开发一个带界面的 本地 Web 应用(一个桌面版的 AI 聊天助手?)。然后还想让公司内网的 其他同事或程序 也能使用我们服务器上的这个模型。
这个时候我们需要使用像 FastAPI、Flask 这样的框架,写一个简单的程序。这个程序会加载模型,并监听一个网络端口(如 http://localhost:8000)。其他程序(如网页前端、其他同事的脚本)就可以像访问网站一样,向这个地址发送请求来使用模型。
【优点】灵活、可共享、易于集成。模型变成了一个标准化的服务,可以被任何能发送网络请求的程序调用。
【缺点】引入了微小的网络延迟,部署稍微复杂一点。
2.3 本地模型服务化工具
现在有很多工具可以帮我们一键把本地模型变成 API 服务,极大简化了过程:
Ollama:部署和运行开源模型的最流行工具,运行后自动提供一个本地 API
LM Studio:图形化界面工具,同样在启动模型后提供本地 API 端点
vLLM:一个高性能的推理引擎,专为生产环境设计,核心就是提供 API 服务
使用这些工具,我们基本上只需要执行一条命令,它们就会在本地(如 http://localhost:11434)启动一个兼容 OpenAI API 格式的服务,让我们可以像调用 GPT-4 的 API 一样调用我们自己的本地模型。
3. 与 AI 对话的 "信使"
完成 API 调用需要下面几个内容:
- Endpoint(服务入口):API 的网络地址,指向一个特定的 AI 服务。相当于门牌号
- Headers(握手协议):身份验证与数据格式建立安全的通信通道。相当于身份证
- Payload(结构化信件):指令、参数和上下文,承载全部的 "意图"。相当于包裹
3.1 Endpoint(服务入口)
API 的网络地址(URL),例如 Deepseek 官网中提供的 base_url:
https://api.deepseek.com/v1常用的大模型 API 端点:
| 服务商 | Base URL | 说明 |
|---|---|---|
| DeepSeek | https://api.deepseek.com/v1 | DeepSeek 官方 API |
| OpenAI | https://api.openai.com/v1 | OpenAI 官方 API |
| Anthropic | https://api.anthropic.com/v1 | Claude 系列 API |
| OpenCode Zen | https://opencode.ai/zen/v1 | OpenCode Zen 网关 |
| Ollama(本地) | http://localhost:11434 | 本地大模型服务 |
3.2 Headers(握手协议)
Headers 包含 Authorization(认证)和 Content-Type(内容类型)。
- Authorization 用来证明“你是你”,就是进行身份验证,携带 API Key,格式为
Authorization: Bearer YOUR_API_KEY。在线大模型服务一般都需要身份验证,但本地大模型服务(如 Ollama)可以不用 API Key - Content-Type 声明数据格式,一般是
Content-Type: application/json。它用来声明数据格式,是我们和大模型沟通的语言规范,例如 JSON 格式。
3.3 Payload(结构化信件)
Payload 是把指令、参数、上下文打包成大模型可读的格式,一般是 JSON,承载我们要传达的全部 "意图"。
{
"model": "deepseek-chat",
"messages": [
{"role": "user", "content": "Hello"}
],
"temperature": 0.7
}4. API 调用的完整流程
下面的总结由 AI 生成。一次完整的 AI API 调用过程包含以下阶段:
4.1 阶段一:构建请求
你在应用里输入问题(比如:"写一首关于秋天的诗")并点击发送。你的应用程序(服务员)立刻开始工作,它会根据预设的规则,将你的问题和其他参数打包成一个标准的 "订单"——也就是一个 HTTP 请求。包含三个关键部分(还是以餐厅作类比):
- 餐厅地址:API 端点 URL。要根据api文档确定。
- 会员卡:API Key,放在请求头中。证明你是合法顾客
- 菜单和口味要求:请求体(JSON),包含
model、messages、temperature、max_tokens等
Tips:
model:你要哪位 "主厨" 来做(比如deepseek-chat)messages:你的具体问题和对话历史temperature:你希望主厨的创造力有多高(0 是严格按菜谱,1 是自由发挥)max_tokens:这道菜最多上多少 "道"(控制回答长度)
技术实现示例:
import os
from openai import OpenAI
# 建立连接(找到餐厅)
client = OpenAI(
api_key=os.environ.get('DEEPSEEK_API_KEY'), # 你的会员卡
base_url="https://api.deepseek.com" # 餐厅地址
)
# 下订单
response = client.chat.completions.create(
model="deepseek-chat", # 选择主厨
messages=[ # 点单内容
{"role": "system", "content": "你是一个专业的AI助手"},
{"role": "user", "content": "请介绍一下AI API调用的基本流程"}
],
temperature=0.7, # 口味要求
max_tokens=1000, # 份量控制
stream=False # 上菜方式
)4.2 阶段二:网络传输
这个 HTTP 请求通过互联网发送出去。它会经过你的路由器、运营商网络、各种骨干网路由器,最终抵达 AI 服务商的服务器。这个过程就像服务员把你的订单从餐桌送到厨房入口,中间可能要穿过餐厅的大堂。为了保证订单不被偷看或篡改,整个过程通常是加密的(HTTPS)。
4.3 阶段三:服务端处理
这是最核心、最复杂的部分。你的请求进入 AI 服务商的庞大系统后,会经历以下步骤:
(1)抵达大门:API 网关(前台兼保安)
- 身份验证:检查你的 API 密钥是否有效、是否有余额
- 速率限制:防止你点单太快把厨房搞乱(比如每分钟最多 60 次)
- 请求校验:检查你的订单格式对不对(JSON 是否合法)
(2)进入等待区:任务队列(取餐号系统)
- AI 推理非常消耗计算资源,如果所有订单都直接冲向主厨,系统会崩溃
- 请求会被放入任务队列里排队,保证公平有序
- 实现削峰填谷,即使瞬间来一万单,厨房也能按自己的节奏处理
(3)预处理:备菜
- 内容审查:检查你的提问是否包含违规内容
- 提示词优化:在你的要求上加点 "标准配方",引导主厨做出更符合预期的菜
- 参数解析:提取 temperature、max_tokens 等参数,准备好交给主厨
(4)核心烹饪:模型推理(明星主厨上场)
- 分词:主厨不认识汉字,只认识数字。他会先把你的问题切分成一个个最小的单元(Token),然后转换成数字 ID
- 模型计算:这些数字 ID 被送入加载在 GPU 上的神经网络模型中,模型会一层一层地处理这些输入
- 自回归生成:模型预测出第一个词,然后把这个词也作为输入,再去预测第二个词,如此循环直到生成完整回答
(5)出锅装盘:后处理与响应
- 格式化:将结果打包成标准的 JSON 格式
- 最终审查:再次快速检查生成的内容是否安全合规
- 计费信息:记录这次请求消耗了多少 Token
4.4 阶段四:响应返回
封装好的 HTTP 响应原路返回,穿过 API 网关,经过互联网,最终回到你的应用程序。这里有一个关键点:流式传输 vs 非流式传输
- 非流式:等模型生成完整结果后一次性返回。就是等主厨把整道菜都做完,一次性端上桌。
- 流式:模型每生成一小段就立即返回。主厨每炒好一小部分,服务员就立刻端给你(打字机效果)。
响应数据结构示例:
{
"id": "chatcmpl-123",
"model": "deepseek-chat",
"choices": [
{
"message": {
"role": "assistant",
"content": "AI API调用的基本流程包括..."
}
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 12,
"total_tokens": 21
}
}4.5 完整流程
[你] <-> [你的App] <--(HTTP请求)--> [互联网] <--(HTTPS)--> [AI服务商]
|
V
[API网关] (鉴权, 限流)
|
V
[任务队列] (排队)
|
V
[预处理服务] (审查, 解析参数)
|
V
[模型推理服务] (在GPU上进行分词、计算、生成)
|
V
[后处理服务] (格式化JSON, 计费)
|
V
[API网关]
|
V
[互联网]
|
V
[你] <--(显示结果)--> [你的App] <--(HTTP响应)--> [互联网] <--(HTTPS)--> [AI服务商]5. API 与 SDK 的关系
- API 是底层的通信协议,定义了原始的请求/响应格式(如 JSON 结构、HTTP 方法和端点 URL),与编程语言无关
- SDK(Software Development Kit)是对 API 的封装,提供特定编程语言的函数库,简化调用过程,例如
@ai-sdk/openai包封装了 OpenAI Responses API 的调用细节
直接调用 API 需要手动处理请求构造、序列化、错误处理等细节,而使用 SDK 可以大幅减少样板代码。
三、 API 格式
OpenCode Zen 作为 AI 模型网关,根据底层 provider 的不同,提供了三种 API 格式。Zen 不进行格式转换,而是直接透传各 provider 的原生 API,以保持各模型的独特能力。
1. 常见格式
下面描述格式时,以 Zen | OpenCode 为例了。
1.1 OpenAI API
1.1.1 Completions 格式
最原始的”续写”接口,诞生于 GPT-3 时代,这是 OpenAI 最早期的 API 形式,主要面向 GPT-3 时代的模型。
发布时间:2020 年 6 月(随 GPT-3 发布)
端点:
/v1/completions核心逻辑:“续写”。给它一段开头的文字(Prompt),它预测接下来的内容。
解决的问题: 将 LLM 作为一种通用的文本生成工具,验证了模型通过简单的提示(Prompting)就能完成翻译、总结、纠错等多种任务的能力。
应用场景: 简单的文本续写、代码补全。
为什么逐步废弃?Completions 接口 不会做任何拼接,会将用户的输入原封不动地传给模型,即不应用任何 Chat Template。然而,当前绝大多数模型在训练时都使用了特定的对话模板(Chat Template),因此推理时也应使用对应模板才能获得最佳效果。Completions 接口要求用户自己手动拼接模板,既繁琐又容易出错,所以 已逐步弃用,成为遗留接口。
1.1.2 Chat Completions 格式
Chat Completions 是 OpenAI 于 2023 年发布的 API 格式,采用 messages 数组承载对话历史,每个消息包含 role(user/assistant/system)和 content 字段。该格式因设计简洁、易于实现而成为行业事实标准,被 DeepSeek、Kimi、GLM、MiniMax 等大量第三方模型广泛兼容。注:部分 Provider(如 DeepSeek)同时支持 Chat Completions 和 Messages 两种格式。
发布时间:2023年3月
端点:
/v1/chat/completions核心逻辑:“对话管理”。不再是单一的 Prompt 字符串,而是包含角色(
system、user、assistant)的消息列表。开发者需自行管理对话上下文。解决的问题: 解决了 Completions 接口在处理多轮对话时”格式混乱”的问题。通过定义系统指令(System Message),开发者能更稳定地控制模型的语气和行为。
在 Zen 中适用的模型:DeepSeek、Kimi、GLM、MiniMax、Grok、Big Pickle 等,SDK包对应
@ai-sdk/openai-compatible**应用场景:**智能客服、聊天机器人;复杂的指令遵循(通过
systemrole 设定约束);结构化数据提取(JSON Mode)
请求示例:
{
"model": "deepseek-v4-flash",
"messages": [
{ "role": "user", "content": "解释什么是 API" },
{ "role": "system", "content": "你是一个有丰富经验的AI开发工程师"}
],
"stream": false
}1.1.3 Responses 格式
Responses 是 OpenAI 于 2025 年 3 月 发布的新一代 API 格式,旨在统一聊天、推理、工具调用和多轮会话管理。相比于 Chat Completions,Responses 内置了会话状态维护、推理链展示等高级特性,是 OpenAI 未来推荐的主要交互方式。但其他模型提供商对该接口的支持尚不如 Chat Completions,因此兼容性暂时不如后者。不过,Responses 接口代表了 OpenAI API 的未来演进方向。
发布时间: 2025 年 3 月
端点:
/v1/responses解决的问题:简化调用方式 ,使模型调用更简单、更清晰;内置工具调用,联网搜索、代码解释器等工具由引擎自动调用,无需用户手动中转;简化上下文管理,通过
previous_response_id引用历史,无需手动维护完整消息列表。在 Zen 中适用的模型:全部 GPT 系列,对应 SDK 包:
@ai-sdk/openai
请求示例:
{
"model": "gpt-5.5",
"input": "解释什么是 API"
}1.2 Messages 格式
Messages 是 Anthropic 于 2023 年独立设计的 API 格式。其 messages 结构与 Chat Completions 不同,content 字段支持多 block 数组(text/image/tool_use),并且响应中包含 stop_reason、usage.cache_creation 等特有字段,能更好地支持 extended thinking 等 Anthropic 独有的推理能力。DeepSeek、Qwen 系列模型实现了对该格式的兼容。
- 端点:
/v1/messages - 在 Zen 中适用的模型:Claude 系列、Qwen 系列,对应 SDK 包:
@ai-sdk/anthropic
请求示例:
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"messages": [
{ "role": "user", "content": "解释什么是 API" }
]
}2. 提供商?
提供商(Provider)指提供 AI 模型服务的公司或平台,它们拥有模型并对外暴露 API 供开发者调用。
| 格式 | 格式来源 | 原生使用该格式的 Provider | 兼容该格式的 Provider |
|---|---|---|---|
| Chat Completions | OpenAI(2022) | OpenAI | DeepSeek、Kimi、GLM、MiniMax、Grok 等大多数第三方 |
| Responses | OpenAI(2025) | OpenAI(GPT 系列) | 暂无其他提供商兼容 |
| Messages | Anthropic(2023) | Anthropic(Claude 系列) | DeepSeek、Qwen 系列 |
关键点:
- 格式由 Provider 定义:OpenAI 设计了 Chat Completions,后来推出 Responses 替代它;Anthropic 独立设计了 Messages
- 第三方 Provider 选择兼容:大多数非 OpenAI 的 Provider(如 DeepSeek、GLM)选择兼容 Chat Completions 格式,因为它最早发布、生态最成熟
- 部分 Provider 同时兼容两种格式:例如 DeepSeek 同时支持 Chat Completions(base_url:
https://api.deepseek.com)和 Messages(base_url:https://api.deepseek.com/anthropic),Qwen 也是此类典型 - Zen 直接透传:Zen 作为网关不转换格式,你调用哪个模型,Zen 就用该模型原生 Provider 的格式转发请求
3. 三种格式对比
3.1 请求结构对比
| 对比维度 | Chat Completions | Responses | Messages |
|---|---|---|---|
| 对话载体 | messages 数组 | input 字段 | messages 数组 |
| 角色字段 | role: user/assistant/system | 无需显式声明 | role: user/assistant |
| 内容字段 | content(纯文本) | input(字符串或数组) | content(字符串或 block 数组) |
| 系统提示 | role: system 消息 | instructions 字段 | system 字段(顶层) |
| 最大输出 | max_tokens | max_output_tokens | max_tokens |
| 流式参数 | stream: true | stream: true | stream: true |
3.2 响应结构对比
| 对比维度 | Chat Completions | Responses | Messages |
|---|---|---|---|
| 顶层对象 | chat.completion | response | message |
| 输出内容 | choices[0].message.content | output 数组 | content 数组 |
| 停止原因 | choices[0].finish_reason | status 字段 | stop_reason 字段 |
| 用量信息 | usage 对象 | usage 对象 | usage 对象 |
| 推理过程 | 无原生支持 | 通过 reasoning 子项 | 通过 extended thinking 机制 |
| 工具调用 | tool_calls 数组 | 内置于 output 格式 | tool_use block 类型 |
3.3 适用场景
- Chat Completions:适合需要跨多种第三方模型迁移的场景,因其兼容性最广。如果你的应用需要灵活切换 deepseek、kimi、glm 等多种模型,推荐使用此格式
- Responses:适合深度使用 OpenAI 生态的场景,能充分利用 GPT 系列的独特能力(如 structured outputs、内置多轮管理)。仅在仅使用 GPT 系列时推荐
- Messages:适合充分利用 Claude extended thinking 能力的场景,或使用 Qwen 系列模型的场景。当你需要精细控制推理过程和缓存策略时最为合适
3.4 设计原则
三种格式的本质差异在于起源和设计哲学:
- Chat Completions 追求 简单通用,牺牲高级特性换取最广泛的兼容性
- Responses 追求 统一集成,试图用一个格式覆盖所有交互模式
- Messages 追求 能力深度,为特定模型的高级特性提供精细控制
4. 示例
有些厂商会提供多种 api 调用格式,例如 deepseek,我们可以看 首次调用 API | DeepSeek API Docs:
base_url (OpenAI) https://api.deepseek.com
base_url (Anthropic) https://api.deepseek.com/anthropic4.1 OpenAI API
这里我看看一个 Python 实例,来自于 deepseek 首次调用 API | DeepSeek API Docs
# Please install OpenAI SDK first: `pip3 install openai`
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ.get('DEEPSEEK_API_KEY'),
base_url="https://api.deepseek.com")
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Hello"},
],
stream=False,
reasoning_effort="high",
extra_body={"thinking": {"type": "enabled"}}
)
print(response.choices[0].message.content)4.2 Anthropic API
参考:Anthropic API | DeepSeek API Docs
import anthropic
client = anthropic.Anthropic()
message = client.messages.create(
model="deepseek-v4-pro",
max_tokens=1000,
system="You are a helpful assistant.",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Hi, how are you?"
}
]
}
]
)
print(message.content)四、 API Key
1. 什么是 API Key
API Key 是一串由服务提供方签发的唯一字符串,用作客户端身份的凭证。每次发起 API 请求时,客户端必须在请求头中携带 API Key,服务端通过验证该 Key 来确认请求的合法性和权限范围。可以将其类比为 "进入大楼的门禁卡"——没有有效的 Key,API 服务将拒绝你的请求。
2. 获取方式
以 OpenCode Zen 为例,获取 API Key 的流程:
(1)访问 opencode.ai/auth 注册或登录
(2)添加支付信息并充值余额
(3)在控制台复制生成的 API Key(格式通常为 sk- 开头的一长串字符)
3. 使用方式
API Key 通过 HTTP 请求头 Authorization 字段传递,格式为 Bearer <key>:
curl https://opencode.ai/zen/v1/chat/completions \
-H "Authorization: Bearer sk-your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-v4-flash", "messages": [{"role": "user", "content": "Hello"}]}'在代码中,应通过环境变量管理 API Key,避免硬编码:
import dotenv from 'dotenv';
dotenv.config();
const response = await fetch('https://opencode.ai/zen/v1/chat/completions', {
headers: {
Authorization: `Bearer ${process.env.OPENCODE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ model: 'deepseek-v4-flash', messages: [...] }),
});五、三个核心问题解答
1. 参数控制
1.1 简介
参数是控制 AI 行为的关键,通过参数的调整,我们可以精确控制 ai 的输出风格,创造力和内容长度等。参数的本质其实影响的是模型的“决策”。AI 生成文本的本质是预测下一个最可能的词,ai 本身是不理解这些词的含义的,而参数最终影响的就是”可能性“的计算方式。
- Temperature:控制创造性和确定性的平衡。Temperature 越低,倾向于选择最高概率的词,输出更加稳定、严谨、可预测,适合事实性回答、技术文档等。Temperature 越高,低概率词出现机会更多,输出更随机、多样、更有 "创意",适合创意写作、头脑风暴
- Max Tokens:限制 AI 回复的最大长度。控制 API 调用成本,避免资源浪费
- Top P:控制词汇选择的多样性
1.2 如何管理
可以将参数配置分离出来,使业务逻辑更加清晰和可维护:
# 参数预设配置
PRESETS = {
"creative_writer": {
"temperature": 0.9,
"max_tokens": 1000
},
"fact_checker": {
"temperature": 0.1,
"max_tokens": 500
}
}
# 调用时
params = PRESETS["creative_writer"]
# API 调用
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
**params
)2. 对话管理
2.1 短期记忆
AI 模型本身是 无状态的,每次请求都是独立的。那么如何能让 AI 拥有短期的记忆?如何让 AI 记住我们是谁?怎么记住历史,实现连贯对话?
解决方案就是欺骗AI,让它自己以为自己记得,核心思想就是:把历史对话(前面输入的内容,AI输出的内容等)作为新的请求的一部分,一起发送给AI。
2.2 对话格式示例
我们可以设计一个对话记录的列表 Messages,包含 "角色——内容",角色包括:
- System:代表系统级别的指令,通常用来放置提示词,提示词可以进一步控制(或者说覆盖)大模型的行为,可以用于设定AI的全行为和背景,具有高优先级,但同时也存在不稳定的风险
- User:用户发出的指令
- Assistant:LLM 给出的回复
【例】
messages = [
{
"role": "system",
"content": "你是一个有帮助的助手。"
},
{
"role": "user",
"content": "你好"
},
{
"role": "assistant",
"content": "你好!有什么可以帮你的吗?"
},
{
"role": "user",
"content": "我刚才想说什么?"
}
]大模型所谓的 "记忆" 对话,其实是依赖于这个列表来传递信息的。
2.3 对话管理
对话管理就是 AI 的短期记忆,通过上下文的注入,让 AI 能够记住对话历史实现连贯的多轮交流。本质上就是一个不断追加和更新历史列表的过程。
随着上下文越来越多,我们发给 AI 的内容越来越多,AI 处理的成本也越来越高,所以很多大模型都设置了上下文长度,例如 64KB、128KB,千问可以达到 256KB。
3. 状态管理
3.1 状态管理概述
前面提到如何让 AI "认识我们",记住用户的姓名、偏好等个人信息,提供个性化服务?这就需要状态管理来实现。状态管理是 AI 的长期记忆系统,通过持久化的存储机制,让 AI 能够记住用户的信息、偏好和历史交互,从而实现真正的个性化体验。
状态管理可以将底层无状态的 AI 服务,包装成用户感知上有状态体验的关键技术。
【状态管理的核心价值】
- 个性化服务:记住用户偏好,提供定制化体验
- 上下文感知:了解用户习惯和历史交互
- 持续学习:基于历史数据优化服务质量
- 用户体验:减少重复信息输入,提高交互效率
3.2 长期记忆和短期记忆的对比
| 特性 | 上下文(短期记忆) | 状态(长期记忆) |
|---|---|---|
| 生命周期 | 会话级(临时) | 应用级(持久) |
| 内容 | 完整的对话历史 | 关键信息片段(如用户名、偏好) |
| 存储 | 内存中的列表 | 变量、文件、数据库、缓存 |
| 作用 | 维持对话连贯性 | 提供个性化体验 |
| 更新频率 | 每次对话更新 | 按需更新 |
| 数据量 | 相对较大 | 相对较小 |
【实际应用示例】
- 短期记忆:记住当前对话中提到的 "我刚才说的那个项目"
- 长期记忆:记住用户 "喜欢喝咖啡"、"住在北京" 等个人信息
3.3 状态存储的载体选择
状态存储的选择取决于应用的规模、性能和持久性需求:
3.3.1 内存变量(临时存储)
# 简单但易失性存储
user_preferences = {
"user_id": "12345",
"preferred_language": "中文",
"theme": "dark",
"last_login": "2024-01-15"
}- 优点:访问速度快,实现简单
- 缺点:程序重启后数据丢失
- 适用场景:开发测试、临时会话
3.3.2 文件存储(轻量级持久化)
# JSON 文件存储示例
import json
# 保存状态
def save_user_state(user_id, state):
with open(f'user_{user_id}.json', 'w', encoding='utf-8') as f:
json.dump(state, f, ensure_ascii=False, indent=2)
# 读取状态
def load_user_state(user_id):
try:
with open(f'user_{user_id}.json', 'r', encoding='utf-8') as f:
return json.load(f)
except FileNotFoundError:
return {}- 优点:实现简单,数据持久化
- 缺点:并发访问可能有问题,性能有限
- 适用场景:单用户应用、小型项目
3.3.3 数据库存储(企业级方案)
- SQLite:轻量级,适合桌面应用
- Redis:高性能内存数据库,适合缓存
- MySQL/PostgreSQL:关系型数据库,适合复杂查询
- MongoDB:文档数据库,适合灵活的数据结构
3.4 状态信息的提取策略
从用户输入中提取关键信息是状态管理的核心环节:
(1)基于规则的方法:关键词匹配、正则表达式匹配
def extract_user_info(text):
info = {}
# 关键词匹配
if "我叫" in text:
name = text.split("我叫")[1].split(" ")[0]
info["name"] = name
# 正则表达式匹配
import re
email_match = re.search(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
if email_match:
info["email"] = email_match.group()
return info(2)基于 AI 的智能提取:例如自然语言处理(Natural Language Processing,简称 NLP)技术等
参考资料:
(3 封私信) 2025 年 AI 大模型应用开发的全攻略。 - 知乎
(13 封私信) 深入理解 OpenAI 的三代 API:从 Completions 到 Responses 的演进之路 - 知乎