Token、上下文与一次请求结构

这篇是普通人、产品经理、工程师都必须先搞懂的底层概念。很多 AI 使用问题看起来像“模型不聪明”,实际是 Token 预算、上下文装配或请求结构出了问题。

一句话区分

概念 一句话 你真正要关心的事
Token 模型读写内容的计量单位 影响上下文上限、费用、速度和截断
上下文 模型这一次回答时能看到的全部信息 影响回答是否知道背景、是否被噪声干扰
请求结构 你把任务、材料、工具和输出要求交给模型的方式 影响模型能不能稳定执行
记忆 产品或系统长期保存的用户偏好/历史信息 不等于本次请求一定可见
工具调用 模型要求外部系统执行某个动作 工具结果会再进入上下文

Token 不是字数

Token 可以是一个汉字、一个英文词的一部分、一个数字片段、一个标点、一个 JSON 字段名,甚至是图片/文件被转换后的内部表示。

常见误解:

  • “我只发了 2000 字,不算长”:中文、英文、代码、表格、JSON 的 token 密度不同。
  • “只算我输入的内容”:模型输出也占 token,推理 token、工具 schema、检索片段也会占空间。
  • “同一段内容所有模型 token 数一样”:不同 tokenizer 会有差异。
  • “上下文窗口大就一定更好”:长上下文会带来成本、延迟和注意力稀释。

实践判断:

场景 做法
长文总结 先分段摘要,再综合,不要一口气塞满窗口
文件问答 先让 AI 建目录和要点,再围绕具体章节追问
API 调用 估算输入、输出、工具 schema、RAG 片段的总 token
高频模板 把稳定指令放前面,变量放后面,便于缓存
成本控制 限制输出长度,避免让模型写“完整长报告”

上下文到底包括什么

一次请求里,模型可能看到:

上下文类型 内容 风险
系统/开发者规则 安全边界、风格、工具权限、输出规则 写得含糊会导致行为不稳定
用户当前输入 当前问题、目标、限制 太短会缺背景,太长会混入噪声
历史对话 前几轮仍被保留的对话 长对话会挤占窗口,旧目标可能干扰新目标
文件/图片 上传材料、截图、PDF、表格 模型可能只理解部分内容
RAG 片段 检索出来的文档片段 召回错误会把模型带偏
工具结果 搜索、数据库、代码运行、API 返回 工具错误会污染后续推理
记忆 用户偏好、长期事实、项目背景 可能不可见、过期或不该用于当前任务

上下文工程的核心不是“塞更多”,而是“让模型看到正确、必要、优先级清楚的材料”。

记忆不等于上下文

很多产品会说自己有 Memory、Projects、Knowledge、Workspace 或个人资料,但这些不是同一个东西。

名词 真实含义 使用判断
上下文 本次请求实际传给模型的内容 决定这次能不能回答
记忆 产品长期保存的信息 可能被系统选择性放入上下文
项目空间 一组聊天、文件和说明的组织方式 适合长期任务,但仍受上下文窗口限制
知识库 文档被索引后按需检索 召回不准时答案仍会错
会话历史 当前对话前面的消息 太长会被截断或压缩

所以不要说“我之前告诉过它”。更可靠的做法是把当前任务需要的背景重新整理成一段“任务状态摘要”。

一次请求的最小结构

产品界面里的“一句话提问”和 API 里的请求,本质都可以拆成下面几块:

模型选择
+ 指令层:系统规则、角色、边界
+ 用户任务:我要你完成什么
+ 输入材料:文本、文件、图片、表格、代码
+ 上下文:历史、检索片段、工具结果、记忆
+ 工具定义:能调用什么、参数是什么、权限是什么
+ 输出契约:格式、长度、字段、引用、失败处理
+ 控制参数:最大输出、推理强度、温度、是否流式
-> 模型输出:文本 / 结构化结果 / 工具调用请求

一个好请求至少要有 6 个字段:

目标:我要完成什么。
背景:为什么做、给谁用、当前限制是什么。
材料:你可以使用哪些内容。
约束:不要做什么、必须遵守什么。
输出:用什么格式交付。
验收:怎样算好、怎样算不合格。

API 视角的一次请求

不同平台字段名不同,但常见结构相似:

字段 作用 产品侧理解
model 选择模型 快、强、便宜、长上下文、多模态之间取舍
messages / input 对话和输入内容 系统、用户、助手、工具结果按顺序进入
content parts 多模态内容块 文本、图片、文件、音频等
tools 可调用工具定义 搜索、数据库、代码执行、MCP、内部 API
tool_choice 是否强制/禁止/自动工具调用 控制模型什么时候行动
response_format / schema 输出结构 JSON、表格、固定字段、可校验
max output 最大输出长度 防止长篇废话和成本失控
reasoning 推理强度或思考预算 复杂任务用强推理,简单任务不浪费
stream 是否流式返回 影响首包体验
metadata 业务追踪信息 trace_id、场景、版本、实验分组

工具调用循环

工具调用不是模型自己“真的去做了事”,而是一个循环:

用户任务
-> 模型判断需要工具
-> 模型输出 tool call(工具名 + 参数)
-> 外部系统执行工具
-> 工具结果回填给模型
-> 模型基于结果继续回答或再次调用工具

必须注意:

  • 工具描述和参数 schema 也会占 token。
  • 工具结果太长会挤占上下文,需要摘要或筛选。
  • 工具失败要有错误分类,不能只把错误原文丢给模型。
  • 写操作必须分权限:只读、建议写入、人工确认后写入、直接写入。
  • 每次工具调用都要能追踪:工具名、参数、结果、耗时、错误、成本。

RAG 如何进入请求

RAG 不是模型训练,而是把检索到的资料片段拼进上下文:

用户问题 -> 查询改写 -> 检索 -> Rerank -> 上下文拼装 -> 模型回答

请求里通常会包含:

  • 用户原始问题。
  • 改写后的检索 query。
  • 若干检索片段。
  • 每个片段的标题、章节、更新时间、权限组。
  • 回答要求:必须基于片段回答,无法确定就说明无法确定。
  • 引用格式:结论后标注依据。

常见失败:

  • 召回没命中正确资料。
  • 命中了但片段太碎,缺上下文。
  • 片段互相冲突,模型没有说明冲突。
  • 检索片段覆盖了系统规则,产生 prompt injection 风险。

结构化输出

当结果要进入系统,而不是给人随便读,就要使用结构化输出。

例子:

{
  "intent": "refund_request",
  "confidence": 0.86,
  "need_human_review": true,
  "evidence": ["用户提到已付款但未收到商品"],
  "next_action": "create_support_ticket"
}

结构化输出的好处:

  • 可以被代码解析。
  • 可以做字段校验。
  • 可以失败重试。
  • 可以进入日志和指标。
  • 可以和工具参数衔接。

要避免:

  • 只说“请输出 JSON”,但不定义字段。
  • 字段可以为空却没有说明。
  • 让模型输出自由文本再靠正则硬解析。

成本、时延和截断

一次请求的成本和时延通常来自:

  • 输入 token:用户输入、历史、文件、RAG、工具 schema。
  • 输出 token:模型回答、结构化字段、推理内容。
  • 工具耗时:搜索、数据库、代码执行、外部 API。
  • 重试:解析失败、工具失败、模型不稳定。
  • 多轮:Agent 循环越多,成本越难控。

常见控制方式:

  • 给每类上下文设 token 预算。
  • 长资料先摘要、再进入主请求。
  • 对工具结果做裁剪和字段化。
  • 对高频系统提示使用缓存。
  • 明确最大输出长度。
  • 复杂任务拆阶段,不在一次请求里做完所有事。

最小自测

拿下面这个模糊请求做改写:

帮我分析一下这个竞品。

合格版本应包含:

  • 竞品是谁。
  • 分析目标是什么。
  • 使用哪些资料。
  • 输出维度是什么。
  • 是否需要联网。
  • 输出格式是什么。
  • 哪些结论必须标注不确定。

可直接复用:

目标:请分析竞品 A 和竞品 B 在 AI 客服场景下的差异。
背景:我们准备设计面向电商卖家的客服 Agent,需要判断功能优先级。
材料:我会提供官网介绍、价格页和 3 篇用户评价。
要求:按功能、数据接入、自动化程度、人工接管、价格、风险 6 个维度比较。
输出:先给一张表,再给 5 条产品启发。
限制:不要编造材料中没有的信息;不确定的地方标注“待核查”。
验收:结论必须能转成 PRD 的功能优先级建议。

下一站

想继续学 去这里
按能力选工具 AI 工具与能力地图
看主流工具差异 主流 AI 工具能力差异
学 Prompt/RAG/上下文/MCP Prompt、RAG、上下文与 MCP
学 Agent 和 Runtime Agent 核心概念 · 工程化与 Runtime