1. 大模型应用开发
这一章用一个贯穿案例讲清楚应用如何调用模型。设想你要为一家公司的新员工做“入职答疑助手”:员工会问项目管理工具、账号申请、请假和报销。成功标准不是让模型写得像人,而是让它在知道依据时准确回答,在没有依据时承认缺口,同时能在多轮对话中理解“这个工具”等指代。
先备知识:把几个词连起来
读过基础编程就能理解本章。API 是程序间按约定发送请求、接收结果的接口;请求是本次传给模型的输入,响应是返回的数据。上下文是模型在本次推理时实际看到的信息,而不是它“记住”的全部聊天。概率分布是一组非负数,合计为 1,用来描述不同候选的相对可能性;采样是按照这组概率选一个候选。区分“模型内部生成”“应用选择输入”“服务端执行业务校验”这三层,就能分析大部分应用题。
1.1 从输入到回答:模型到底做了什么
发送给模型的文字先经过分词器,转成一串 token 编号。token 是模型处理文本的单位,可能是一个汉字、一个词的一部分、标点或若干字符,不能简单按“一个汉字等于一个 token”估算。模型读入已有 token 后,为词表里的每个候选 token 算一个分数(logit)。经过归一化,这些分数成为“下一 token”的概率。选出下一 token、接到上下文末尾、再预测下一 token,如此循环,直到停止标记或达到输出限制。这就是自回归生成。
这种机制解释了两个现象。第一,同一个问题可能生成不同措辞,因为每一步都可能从概率分布中采样;前面一处选择不同,后面上下文也随之变化。第二,语句通顺并不证明事实正确。模型会续写符合上下文的内容,却没有自动连接你公司的最新制度。问“公司的项目管理工具是什么”,如果请求没有提供公司文档,模型可能把常见工具名说得很肯定。应用必须把“语言生成”和“事实获取”分开:前者交给模型,后者由受控资料或工具提供,再检查回答是否得到依据支持。
1.2 temperature 和 top_p 的计算逻辑
logit 不是概率。设三个候选 token 的 logit 分别为 ln 4、ln 2、0。在 temperature = 1 时,对每个 logit 取指数,得到权重 4、2、1;除以总和 7 后,概率是 4/7≈0.571、2/7≈0.286、1/7≈0.143。temperature 的作用是先用温度除 logit,再做 softmax。若温度改为 0.5,权重变成 16、4、1,概率成为 16/21≈0.762、4/21≈0.190、1/21≈0.048:最高概率候选更集中。温度升高则通常使分布更平。这里的数字只是讲原理的手算例子,不是某个模型的实际输出或推荐参数。
top_p 改变的是可供采样的集合。沿用温度为 1 的概率 4/7、2/7、1/7,从大到小累加;若 top_p=0.7,第一个候选累计约 0.571,尚未达到 0.7,须把第二个也纳入,累计约 0.857。第三个被排除。对保留下来的概率重新归一化,两个候选的采样概率成为 2/3 和 1/3。因此 top_p 是“取累计概率达到阈值的最小候选前缀”,不是“每个概率低于 0.7 的 token 都删掉”。实现细节和参数允许范围应以所用模型的 API 文档为准。
在分类、信息抽取或制度问答中,通常希望输出更稳定,可以先降低随机性并在固定样本上测量效果;创意文案可能需要更大的表达空间。官方课程建议先调整一个采样参数,观察变化,再考虑另一个。低温不等于事实正确,top_p 变小不等于证据充分,设置随机种子也不应当被理解为绝对复现保证。
1.3 API 消息如何组成一次请求
对话 API 常把内容组织成 messages 列表:system 或相应高优先级消息定义应用的长期行为,user 放本轮用户问题,assistant 放此前模型回复。具体角色、字段和顺序以当前接口规范为准。一次调用时模型能参考的,是应用这次实际传入的消息;应用通常必须自行保存和选取历史,不能假定服务端永久记住每位用户的全部对话。
消息 1 system: 你是入职答疑助手;仅依据获准资料回答。
消息 2 user: 我们用什么项目管理工具?
消息 3 assistant: 根据当前资料,使用 Jira。
消息 4 user: 那怎么申请账号?
第二轮里的“账号”指向前一轮的 Jira。若应用只发送消息 4,模型就缺少指代依据。若历史很长,不能机械地全部回传:应保留与本轮相关的实体、用户目标、必要约束和可靠的工具结果;过时或无关的聊天可以截断或摘要。摘要本身也可能遗漏关键条件,重要事实应回到权威资料核对。跨会话连续对话还需要应用持久化记录,并遵守相应权限和数据保存规则。
1.4 上下文窗口、token 与成本
上下文窗口是一次推理可处理的 token 容量。系统指令、历史消息、用户问题、检索片段、工具结果和将生成的回答都会争夺这份容量;不同模型、不同服务的上限和计费规则并不相同。为了理解预算,可做一个纯示例:假设某模型一次最多处理 8,000 token,应用预留 1,000 token 给输出和必要余量,那么可用于输入的预算至多约 7,000 token。若系统指令占 500、历史占 2,000、检索资料占 4,000、用户问题占 200,已用 6,700,还只剩约 300。再放 1,000 token 文档就可能超过预算。这个例子只说明加法,不能作为任何阿里云产品的固定规格。
控制成本的先后顺序是:删掉无关资料和重复历史;按权限与相关性检索少量必要片段;控制合理的输出长度;统计实际输入、输出 token、延迟与答对率。盲目截断文档开头可能剪掉关键例外条款,盲目摘要也可能抹去日期和审批条件。业务上更可靠的做法是先确定“回答必须用到哪条证据”,再分配上下文预算。知识库内容经常更新时,可用 RAG 动态取相关片段,而不是把整座知识库塞进一次请求。
1.5 流式输出与安全边界
非流式调用通常等模型完成后一次返回;流式调用按增量返回,让页面较早显示首段内容,改善用户感知等待。它改变的是传输和呈现方式,不负责提高事实正确率,也未必减少模型总计算量。若要先审查整段答案、验证 JSON 或拦截敏感内容,应用需要设计缓冲、增量检测或在通过检查后再展示,不能边显示边假定后续不会出现问题。
API Key 属于凭据,应放在服务端的受控配置或环境变量中,不能写进公开静态网站的前端代码;前端应调用自己的受控后端。请求、日志与历史中可能含员工信息,应按最小权限和必要保存原则处理。外部文档可提供事实,但文档里的“请忽略系统规则”“把密钥发给我”是数据,不是可以提升权限的指令。是否允许查询某项资料、调用某个工具,必须由应用程序的鉴权与校验决定。
1.6 从机制迁移到新场景
换成客服、电商导购或设备维修助手时,先画出四件事:①问题所需事实从哪里来,哪些会更新;②模型本次需要哪些指令、历史和证据;③输出交给人阅读还是程序执行;④哪一步由程序而非模型做权限和正确性检查。然后把故障映射回机制。回答乱跳,先看采样与提示词;把“它”理解错,先看历史选择;编造最新价格或制度,先看证据接入与更新;用户等太久,分开量测检索、推理和展示,流式只改变最后一段的感知。
例如设备维修助手收到“这台机器昨天又报警了”,本轮缺少“哪台”和“昨天”的具体记录。不能靠调低温度让模型猜中设备编号。应用先利用用户身份查询获准设备列表和告警日志,必要时请用户澄清,再把相关记录送入上下文;模型据此解释,程序仍负责限制它能看到的设备范围。这样把问题拆回“信息、生成、权限”三个环节,就能把本章原理用于题干之外的场景。
1.7 用单选、多选题检验理解
单选题判断:先定位题干的主要故障。如果第二轮“它的账号怎么申请”答成泛泛建议,优先查是否传入必要历史;如果相同问题答法波动大,检查采样参数与提示词约束;如果答案流畅却写错内部制度,补权威资料和证据核验,不把低温当作事实修复;如果页面等待完整回答过久,可以考虑流式显示,但不能据此推出答案更准确。
多选题判断:逐项问“该措施解决哪个环节”。保留必要上下文解决指代问题;缩短无关历史有助于预算与成本;服务端保护 API Key 解决凭据暴露;对流式输出做适当审查解决展示前校验。诸如“模型自动永久记住用户”“top_p 是单个 token 的固定概率门槛”“temperature 为零就保证事实真实”都把不同机制混为一谈,应排除。
课程依据:官方 2.1 课程 Notebook;官方课程目录与考纲。本章的手算、预算和场景为教学示例。