9、输入上下文怎么设计:从 Prompt 到上下文系统
这一章要回答什么
当前这套教程前 8 篇,已经把一个多 Agent 产品从 0 到 1 的主骨架讲清楚了。
但如果继续往下看,你会发现一个问题越来越关键:
为什么同一个 Agent,有时输出很稳,有时又会明显跑偏?
很多人第一反应是:
- 模型不够强
- Prompt 写得不够好
- 规则不够细
这些都可能有影响,但在真实项目里,更常见的根因其实是:
上下文给得不对。
也就是说,Agent 质量很多时候不是由“模型多聪明”决定的,而是由“系统到底给了它什么信息、按什么结构给、什么时候给”决定的。
这章就结合当前项目,讲清楚:
- 上下文和 Prompt 的区别
- 为什么多 Agent 系统必须认真设计上下文
- 当前项目里的上下文系统已经发展到了什么程度
- 后面最值得怎么继续演进
为什么“只写 Prompt”不够
在最初做 Agent 原型时,很多人会把所有事情都理解成:
- 写一个 System Prompt
- 拼一个 User Prompt
- 调一下模型
这在单轮生成任务里勉强够用,但一旦进入多 Agent、多步骤、多轮反馈的系统,就会很快遇到问题。
问题 1:信息来源越来越多
在当前项目里,Writer 并不是只看一个题目就开始写。
它实际上可能同时要考虑:
- 任务基础信息
Research的研究摘要- 用户 reject 后的反馈
- 当前生效的修订要求
Reviewer的审核意见
如果这些信息只是随便拼成一大段文字,系统很快就会变得不稳定。
问题 2:历史信息会越来越长
随着多轮 reject 增加,系统会越来越容易出现:
- 上一轮写了什么
- 上一轮哪里被判定不行
- 哪些问题已经修好了
- 哪些问题还没解决
如果没有“上下文系统”,就只能把历史文本越堆越长。
问题 3:不同 Agent 本来就应该看到不同信息
Dispatcher、Research、Writer、Reviewer 的职责不同,所以它们需要的上下文也不同。
比如:
Dispatcher更需要题目、角度、读者Research更需要主题边界和必须覆盖点Writer更需要上游产物和反馈Reviewer更需要当前正文和当前标准
这时你会发现,问题已经不再是“Prompt 怎么写”,而是:
上下文到底该怎么组织。
上下文和 Prompt 的区别是什么
这两个词很容易混,但在工程上其实不是一回事。
Prompt
Prompt 更像“最终送给模型的一段话”。
它是最终形态,比如:
- system prompt
- user prompt
Context
Context 更像“系统在生成 Prompt 之前,用来组织输入信息的中间层”。
它包括:
- 信息从哪里来
- 哪些信息该给哪个 Agent
- 哪些是当前生效要求
- 哪些是历史记录
- 哪些应该优先呈现
可以把它理解成:
- Prompt 是给模型看的文本
- Context 是系统整理这些文本之前的结构化状态
当前项目最近补的 Context Breakdown,本质上就是在把这个中间层显式展示出来。
一个 Agent 的上下文,通常应该分成哪几层
结合当前项目,我更推荐把上下文理解成 5 层,而不是一整段杂糅文字。
1. 任务基础信息
这是任务最稳定的那部分。
比如:
topicangleaudiencetonelengthmust_includemust_avoid
这些内容通常对多个 Agent 都有用,但不一定每次都完整原样传递。
2. 当前步骤目标
这层是“这一轮你现在到底要干嘛”。
比如:
Dispatcher:规划标题和主线Research:整理研究摘要Writer:生成提纲和初稿Reviewer:审核当前文章
很多系统的问题,不是背景不够,而是“当前这一步的目标没有说清楚”。
3. 上游产物
这层是上一个或前几个步骤已经产出的东西。
在当前项目里比较典型的是:
research_markdowndraft_markdownreview_notes
这些产物不是背景,而是下一步的直接输入。
4. 当前生效反馈
这层在多轮修订里尤其重要。
当前项目现在已经有:
effective_feedback
它代表的不是“用户说过什么”,而是:
到目前为止,真正还在生效的修订要求是什么。
5. 活跃问题与冲突状态
这是系统进一步演进出来的一层。
当前项目已经有:
issue_boardpending_conflict
这让系统不只是“记住反馈文本”,而是能知道:
- 现在有哪些 open issue
- 哪些意见互相冲突
- 是否需要用户裁决
当前项目最开始是怎么做上下文的
最初版本其实很简单,更多是“按 Agent 手工拼接 Prompt”。
大概会是这样的思路:
Dispatcher看选题和角度Research看选题和 must_includeWriter看研究摘要和用户反馈Reviewer看文章正文
这已经比“一个大 Prompt 打天下”强很多了。
但随着系统变复杂,这种写法会慢慢暴露问题。
当时的问题是什么
主要有三类:
- 上下文构造逻辑分散在不同 Agent 文件里
- reject 后只回灌最后一段反馈,历史信息不够结构化
- 很难向页面解释“这次到底给了模型什么”
这也是为什么后面项目开始往“上下文系统”而不只是“Prompt 模板”演进。
当前项目的上下文系统已经演进到了什么程度
如果看现在的实现,会发现它已经明显超出“简单 Prompt 拼接”了。
1. 有任务级上下文快照
当前项目已经有:
task_context_snapshots
这意味着系统可以在关键节点保存一份完整状态,方便:
- 回看
- 调试
- 复盘
2. 有当前生效反馈
系统不再只依赖最后一次 feedback,而是引入了:
effective_feedback
这让多轮修订时的上下文收敛能力大大提高。
3. 有问题板
通过:
issue_board
系统开始把历史反馈转成“问题状态”,而不只是堆积自然语言。
4. 有冲突待确认状态
通过:
pending_conflict
系统已经能识别多轮反馈冲突,并等待用户确认最终生效结论。
5. 有上下文可视化
任务详情页里的:
Context Breakdown
已经能把上下文按来源拆开显示出来,例如:
- 任务基础信息
- 上游输入
- 当前生效反馈
- 活跃问题
这一步非常关键,因为它让上下文从“隐藏在代码里的实现细节”变成了“可以被看见、被理解、被调试的对象”。
多轮修订为什么会把上下文设计推向更复杂的阶段
单轮生成时,上下文设计还相对简单。
但一旦进入多轮修订,系统就会自然进入另一个阶段。
从“生成任务”变成“收敛任务”
这时 Agent 关注的不再只是:
- 我要写什么
而更多是:
- 我要改什么
- 哪些问题还没解决
- 哪些问题已经解决,不要回退
- 本轮新增要求是什么
也就是说,多轮修订会把上下文的重心从“背景信息”推向“状态管理”。
从“聊天记录思路”变成“issue board 思路”
如果系统只是把所有反馈原文累加,很快就会乱。
所以当前项目才会逐步演进出:
issue_boardeffective_feedbackconflict_resolution
这些都在说明:
多轮修订时,上下文应该更多地表现为“当前有效状态”,而不是“历史文本全集”。
当前项目最值得继续补的上下文工作
如果沿着现在的方向继续做,我认为最值得优先补的是三件事。
1. 把上下文构建进一步收敛成专门层
现在系统已经有不少上下文能力了,但构建逻辑仍然分散在不同地方。
后面可以进一步收敛成更明确的 builder。
2. 把“有效标准”做得更清楚
现在系统已经有:
effective_feedbackquality_gate
后面还可以进一步让每个 Agent 更明确知道:
- 当前标准是什么
- 当前优先修的问题是什么
3. 让上下文和调试视图更紧密
Context Breakdown 已经是很好的开始。
后面如果继续做,可以让调试页更明确展示:
- 哪一层上下文来自哪里
- 哪一层是本轮新增
- 哪一层是冲突后用户确认的结论
这一章的结论
一个真实的多 Agent 系统,做着做着就会发现:
Prompt 只是最终表现,真正决定稳定性的,是上下文系统。
当前项目已经从最初的“手工拼 Prompt”,逐步演进出了:
- 快照
- 生效反馈
- 问题板
- 冲突确认
- 上下文可视化
这说明系统已经在从“调用模型”走向“管理上下文”。
下一章看什么
既然上下文会越来越依赖多轮反馈,那么紧接着就要回答另一个问题:
多轮 reject 的反馈到底该怎么管理?冲突又该怎么处理?
下一章我们就专门讲当前项目里的:
issue_boardeffective_feedbackpending_conflictconflict_resolution
也就是多轮反馈和冲突裁决这条主线。