上下文反模式

AI Agent 上下文工程中常见的五种反模式:只传当前消息、全量塞入、记忆全放 messages、没有 pending_question、UI 状态与 Agent 状态分裂。

#type / concept #status / evergreen #tech / ai

[!info] related notes

上下文反模式

上下文工程中常见的五种反模式,以及对应的正确做法。

反模式 1:只传当前消息

表现

messages := []service.ChatMessage{
    {Role: "user", Content: contentText},
}

每次只传当前用户消息,Python 端每次都像第一次见到用户。

后果

用户:膝盖有下坠感
AI:请问持续多久?有没有疼痛?
用户:一周了,走路会明显
AI:请问你能补充持续多久、有没有疼痛吗?

这不是模型”不聪明”,而是它每次收到的上下文都是断的。

正确做法

加载历史 messages 并传给模型。至少包含当前会话的最近几轮原始消息。详见 Context Builder 模式

反模式 2:把所有历史无脑塞进去

表现

把所有 messages 全量传给模型,不做任何过滤或压缩。

后果

问题说明
token 成本高每轮都传全量历史,token 消耗线性增长
模型注意力分散无关的早期对话干扰当前判断
旧信息污染早期的错误信息可能影响新判断
半截消息污染SSE 断流产生的 partial message 进入上下文
工具结果过长完整的 RAG 检索结果或 tool result 占用大量 token
重复问答模型可能重复问已经回答过的问题

正确做法

采用分层策略:

最近 6~10 轮:保留原始 messages
更早内容:进入 conversation_summary
结构化症状:永远单独保留
知识库检索:每轮动态注入 top 3~5
工具结果:只保留摘要,不保留全部原文

详见 上下文窗口预算

反模式 3:把”记忆”全部放在 messages 里

表现

用户第一轮说”我膝盖有下坠感,一周了,走路明显”,系统完全依赖这句话在 messages 里,不抽取结构化数据。

后果

  • 模型每轮都要从自然语言里重新推理”膝盖""下坠感""一周""走路”
  • 如果 messages 被 trim 或 summary,这些信息可能丢失或变得模糊
  • 代码无法根据结构化字段驱动逻辑(如 missing_slots)

正确做法

把关键信息抽成结构化状态:

{
  "body_part": "膝盖",
  "symptom": "下坠感",
  "duration": "一周",
  "trigger": "走路"
}

messages 是证据,structured state 是工作记忆。 详见 问诊状态 Schema

反模式 4:没有 pending_question

表现

AI 问”是否伴随疼痛或肿胀?“,用户答”没有”,系统不知道”没有”指的是什么。

后果

模型可能把”没有”理解为:

  • 没有疼痛
  • 没有肿胀
  • 两个都没有
  • 没有其他症状

下一轮可能重复问同样的问题,或者做出错误推断。

正确做法

状态里维护 last_questionpending_answer_for

{
  "last_question": "是否伴随疼痛或肿胀?",
  "pending_answer_for": ["pain", "swelling"]
}

用户回答”没有”时,结合 pending_answer_for 解析:

{
  "pain": "none",
  "swelling": "none"
}

这比纯文本问答稳定很多。详见 结构化信息采集

反模式 5:UI 状态与 Agent 状态分裂

表现

前端人体 SVG 已经高亮”膝盖”,但模型上下文里没有 body_part: knee。用户看起来在一个问诊流程里,模型实际不知道 UI 发生了什么。

后果

  • 用户点击了膝盖,AI 还问”你想咨询哪个部位?”
  • 右侧看板显示”膝盖”,AI 回复里提到”肩部”
  • 前端和后端的状态不一致,用户体验割裂

正确做法

UI 展示状态 = 后端 consultation_state 的投影
模型上下文 = consultation_state 的精选版本

前端不要自己维护一套不可追踪的”隐式状态”。所有 UI 可见的状态都应该来自后端 consultation_state,或者同步回后端。

总结

反模式核心问题正确做法
只传当前消息模型失忆加载历史 messages
全量塞入token 浪费、注意力分散分层策略 + 预算控制
记忆全在 messages无法驱动逻辑结构化 state 独立维护
没有 pending_question回答歧义维护 last_question + pending_answer_for
UI/Agent 状态分裂前后端不一致UI 是 state 的投影
创建于 2026/6/30 更新于 2026/7/15