先理解上下文,再写第一次模型调用
分清 token、上下文窗口与输出预算,用一个离线示例练习如何组织模型输入。
能解释一条模型请求里有哪些输入,以及超出预算时该删什么。
模型调用的第一道边界,是你实际给了模型什么信息。模型不会自动知道数据库里有什么,也不会因为对话界面显示了历史,就一定收到全部历史。
一次请求应该能被拆成清楚的输入:任务规则、用户问题、必要的历史、检索证据和工具定义。先把这些信息组织好,再讨论提示词写得是否漂亮。
分清三个预算
Token 是模型处理文本的单位,不等于汉字、英文单词或字符。不同模型的 tokenizer 可能不同,同一段内容的 token 数也可能变化。
上下文窗口规定模型一次处理信息的容量,但输入限制、最大输出和推理 token 的计入方式还要看具体接口。不能简单把网页上写的上下文容量全部填成文档。
为输出预留空间,也给固定指令、工具定义和协议包装留余量。实际接入时,用对应模型的计数工具或接口返回的 usage 校准估算。
把输入按职责组织
系统规则负责说明任务边界;用户输入负责表达本次需求;历史记录帮助理解已经发生的事;资料负责提供证据。工具描述则告诉模型有哪些可调用能力。
这些内容的权限不同。检索到的一段网页,即使写着“忽略之前的规则”,也只是外部资料,不能因此获得系统指令的地位。
历史也不是越多越好。优先保留当前目标、已确认约束和必要结果。与当前任务无关的旧讨论会消耗预算,还可能干扰选择。
用离线预算练习取舍
下面的 token 数是人为设置的教学数值,不是真实 tokenizer 的结果。代码只演示:先扣固定成本,再按优先级选择资料。可以直接用 Python 运行。
window = 80
reserved_output = 20
safety_margin = 5
fixed_input = 18
remaining = window - reserved_output - safety_margin - fixed_input
notes = [
{"id": "current-goal", "tokens": 12},
{"id": "relevant-evidence", "tokens": 20},
{"id": "old-discussion", "tokens": 24},
]
selected = []
for note in notes:
if note["tokens"] <= remaining:
selected.append(note["id"])
remaining -= note["tokens"]
assert selected == ["current-goal", "relevant-evidence"]
assert remaining == 5
print(selected)
这个算法不会判断语义重要性,优先级来自你提前排好的列表。工程实现还要记录资料的版本与出处,而不只是保存一段文本。
接口成功,不等于任务成功
HTTP 请求成功只能说明接口完成了某种响应。你还需要区分完整结果、拒绝、超出输出限制、工具请求和服务错误。
如果下一步要把结果写入数据库,给结果定义字段与允许值,并在程序侧做校验。自然语言“看起来像 JSON”不能替代有效的业务契约。
下一步
选一个小任务,例如把一段公开说明整理成三条要点。列出它需要的固定规则、用户内容和输出格式,然后删除所有不必要的历史。
接入真实模型时,记录一次输入的组成与 usage,比较估算和实际差异。记录数量与类型即可,不必把用户正文写入日志。下一篇再处理流式显示与最终结果之间的关系。
资料来源与延伸阅读
资料核验:2026-11-10。本文为原创工程讲解,教学示例不代表线上实测。