知识点思维导图
31 个知识节点
大模型基础(07) - 大模型 API 基础
读完后,你应能完成以下任务:
- 绘制“大模型基础(05) - 大模型 API 基础 / message 不是一段字符串,是带角色的列表”的关键对象与数据流,解释“前端同学第一反应往往是「把用户的问题当 body 发过去」。”,并用源码位置、日志或 Trace 标注证据。
- 为“大模型基础(05) - 大模型 API 基础 / token:模型的计价单位,也是上下文的尺子”设计正常与异常输入,验证“所以输入 token 是随轮数累加的。”,输出首个偏差位置与回归测试结果。
- 实现“大模型基础(05) - 大模型 API 基础 / 密钥在后端,前端只调你自己的接口”的最小代码或配置,检验“最后一个硬规矩:API Key 绝不能出现在前端代码里。”,输出命令、结果与 Diff,并说明不适用边界。
一、大模型 API 基础的真实应用场景
你给公司做了个「制度问答」页面。用户输入「报销要几天内提交?」,前端不能像调普通 REST 接口那样 GET /api/baoxiao 就完事——因为答案不在数据库里,在模型脑子里。
你要做的是:把用户这句话,连同「你是公司制度助手」这条规则,打包成一个特定结构发给模型,再把模型吐回来的文本展示出来。这个「打包结构」和「调用约定」,就是大模型 API。它和你熟悉的 fetch 很像,但有三个你必须先搞懂的点:消息分角色、计费按 token、密钥不能落前端。
二、message 不是一段字符串,是带角色的列表
前端同学第一反应往往是「把用户的问题当 body 发过去」。但模型 API 的输入不是一个字符串,是一个 messages 列表,每条消息带一个 role:
三种角色各管一摊:
| 角色 | 放什么 | 类比前端 |
|---|---|---|
system |
全局规则、人设、约束,整段对话只设一次 | 应用的全局配置 / 初始化 |
user |
用户每一轮的输入 | 用户的每次操作事件 |
assistant |
模型之前每一轮的回复 | 上一次接口返回、存进了 state |
关键认知:模型本身没有记忆。它不知道你们上一句聊了啥。所谓「多轮对话」,是你每次把 system + 全部历史 user/assistant + 这次的新问题,一股脑重新发给它。模型只是对着这一整个列表生成下一句。
三、token:模型的计价单位,也是上下文的尺子
模型不按「字数」算账,按 token 算。token 是模型分词后的最小单位,粗略记:
- 中文:1 个字 ≈ 1 token
- 英文 / 数字:约 4 个字符 ≈ 1 token
为什么前端要在意它?因为 token 同时决定了三件事:
token 多 → 花钱多(按 token 计费)
→ 速度慢(生成的 token 越多越慢)
→ 可能超限(每个模型有上下文长度上限,超了直接报错)
而上面说过,每多聊一轮,整个历史都要重发一遍。所以输入 token 是随轮数累加的。demo 里场景 1 输入 26 token,到场景 2 多聊一轮就涨到 73——这不是个小事,长会话不管理上下文,账单和延迟都会失控。具体的截断、摘要和会话隔离见 Prompt Engineering(16) - 多轮对话与上下文管理。
四、密钥在后端,前端只调你自己的接口
最后一个硬规矩:API Key 绝不能出现在前端代码里。前端代码是公开的,谁都能在浏览器里看到。Key 一旦泄露,别人就能拿你的额度花钱。
正确的链路永远是:
浏览器 ──> 你的后端(持有 Key,封装模型调用) ──> 模型服务
<── <──
后端封装还有个额外好处:换模型时只改一处。把调用逻辑收进一个函数(demo 里的 mock_chat),将来从 mock 换成 OpenAI、再换成通义,上层业务代码一行都不用动。
顺带提一个常被问到的参数 temperature:它控制输出的随机性。值低(如 0.2)输出更确定、更可复现,适合制度问答、信息抽取这类要稳的场景;值高(如 0.9)更发散,适合创意文案。
五、工程上真正会踩的坑
- 把整段历史无脑全发,会话一长就触发上下文超限报错或账单暴涨。需要按 Prompt Engineering(16) - 多轮对话与上下文管理 中的预算策略做截断或摘要。
- system 规则写得太弱,模型不当回事。规则要具体,且关键约束不能只靠 system(能被诱导绕过),该用代码兜的用代码兜。
- 不记 token 和耗时,出了「为什么这次又慢又贵」没法查。接口层至少落 model、input/output tokens、latency、requestId。
- temperature 默认值照抄文档。问答类任务设高了会东拉西扯,务必针对任务调低。
六、一句话面试答法
调用大模型 API 要注意什么? 输入是带 role 的 messages 列表,不是纯字符串;模型本身无记忆,多轮对话靠每次把历史重发,所以输入 token 随轮数累加,要做上下文管理。计费和上下文上限都按 token 算,我会在后端统一封装调用、记录 token 和耗时。API Key 只在后端持有,前端只调我自己的接口,绝不直连模型。
七、动手实践:10 大模型 API 基础
用一个离线的 mock chat API 讲清三件事:message 的角色结构、token 怎么估算、多轮上下文为什么越聊越贵。没有真实模型,无需 API Key。
7.1 在线运行
零依赖,纯标准库。
7.2 预期输出
轮次=1 prompt_tokens≈11 回答=已收到:报销期限?
轮次=2 prompt_tokens≈19 回答=已收到:需要哪些材料?
轮次=3 prompt_tokens≈28 回答=已收到:刚才两点总结一下
预期失败:message[0].role 非法:admin
三轮 prompt_tokens 持续增长,证明每轮都会重发历史。最后一行证明未知角色在进入模型调用前被拒绝;真实项目应使用目标模型 tokenizer 替换教学估算。
7.3 代码↔概念对应
| 概念 | 在 main.py 哪里 |
|---|---|
| message 的 system / user / assistant 角色 | main 里构造 messages |
| 上下文是「手动累加历史」 | 场景 2 里 messages.append(...) |
| token 估算(中文 1 字≈1,英文 4 字符≈1) | estimate_tokens |
| 整段上下文的 token 之和 | count_messages_tokens |
| 模拟模型调用 + 返回 usage | mock_chat |
| temperature 影响输出风格 | mock_chat 里 if temperature <= 0.2 |
| 接口层该记录的字段 | call_log 和汇总打印 |
7.4 动手改
- 把
mock_chat换成真实模型 HTTP 调用(OpenAI / 通义),保留usage字段结构不变,上层代码一行不用改。 - 在场景 2 后面再追加两轮对话,观察
input_tokens怎么持续涨——这就是下一篇「上下文管理」要解决的问题。 - 把
estimate_tokens的英文系数从 4 改成 3,看看估算差多少;真实项目应换成模型自带的分词器。
7.5 可运行源码:大模型 API 基础
main.py
八、总结
- message 不是一段字符串,是带角色的列表:前端同学第一反应往往是「把用户的问题当 body 发过去」。
- token:模型的计价单位,也是上下文的尺子:所以输入 token 是随轮数累加的。
- 密钥在后端,前端只调你自己的接口:最后一个硬规矩:API Key 绝不能出现在前端代码里。
- 工程上真正会踩的坑:规则要具体,且关键约束不能只靠 system(能被诱导绕过),该用代码兜的用代码兜。
- 一句话面试答法:输入是带 role 的 messages 列表,不是纯字符串;
学完自测
选择所有正确答案;提交后逐项核对判断依据。