多 LLM Agent 交互系统上下文传递的设计

上下文架构
Agent 自身的对话上下文
每个 Agent 都有自己的 AgentState.messages,这是它真正喂给模型的对话历史。
在 BaseAgent.agent_loop 里,每轮都会把 self.state.get_conversation_history() 交给 LLM.generate()。也就是说,模型不是直接看全局共享上下文,而是看当前 Agent 自己这份 history。
父子 Agent 之间怎么传上下文
子 Agent 是通过 create_agent() 创建的。如果 inherit_context=True,就把父 Agent 的 conversation_history 拿出来,作为 inherited_messages 传给子 Agent,然后在 _run_agent_in_thread() 里,会把这段上下文包成:
<inherited_context_from_parent>
...
</inherited_context_from_parent>
这表示:
子 Agent 能看到父 Agent 的历史
但系统明确告诉它:这是背景信息,不是让你继续替父 Agent 干活
这一步很重要,因为它避免了多 Agent 之间“角色混淆”。
另外,send_message_to_agent() / agent_finish() 也会把跨 Agent 消息写进共享的 _agent_messages 队列,子 Agent 在 BaseAgent._check_agent_messages 里轮询这些消息,再把它们转成自己的上下文。
所以多 Agent 的消息流是:
父 Agent history
→ create_agent 继承给子 Agent
→ shared message queue 传递实时消息
→ 子 Agent 再把收到的消息写回自己的 messages
上下文溢出防护
压缩对话历史
真正防止超长上下文的核心,在 memory_compressor.py。
它的策略是:
- 保留所有 system 消息
- 保留最近 MIN_RECENT_MESSAGES = 15 条普通消息
- 对更早的消息按 10 条一组做摘要
- 只有当总 token 超过 MAX_TOTAL_TOKENS * 0.9,也就是 100k 的 90% 时才压缩
- 压缩后的内容不是简单截断,而是让模型生成一个保留关键安全信息的摘要,比如:
- 已发现的漏洞
- 关键路径和参数
- 认证信息
- 失败尝试
- 已经做过的测试方向
- 然后它会把旧消息清掉,替换成摘要消息。
先计算预算,再压缩
在 strix/llm/llm.py 的 _prepare_messages() 里,会先算 system prompt 和 agent identity 占了多少 token:
reserved_tokens = sum(get_message_tokens(msg, self.config.litellm_model) for msg in messages)
再把这个预算传给 memory_compressor.compress_history(…)。
也就是说,压缩不是盲压,而是按剩余 token 空间来决定。
工具输出也会截断
上下文膨胀不只来自对话,还来自工具输出。这个项目也做了截断:
- strix/tools/executor.py 会把工具结果整理后再放回 conversation history
- 大输出会被裁掉中间或后半段。
- 浏览器、代理、终端这些工具本身也有各自的长度限制和截断逻辑
所以不会把一整坨超长日志原封不动塞回模型。
总结
[用户/目标输入]
|
v
[Root Agent / 主 Agent]
文件:agents/StrixAgent/strix_agent.py
|
| 1) 自己先有一份 messages
| 2) 每轮把 state.get_conversation_history() 交给 LLM
v
[BaseAgent 主循环]
文件:agents/base_agent.py
|
|--> 调用 LLM.generate(...)
|--> 接收模型输出
|--> 工具执行结果写回 messages
|
v
[LLM 看到的上下文]
文件:llm/llm.py
|
| 先拼系统提示词 + agent identity
| 再把 conversation_history 送去压缩器
v
[上下文压缩器]
文件:llm/memory_compressor.py
|
| 规则:
| - 保留所有 system 消息
| - 保留最近 15 条消息
| - 旧消息按 10 条一组摘要
| - 超过约 90% token 预算才压缩
v
[压缩后的 history]
|
v
[LLM 继续推理]
|
| 生成工具调用 / 文本回复
v
[工具执行层]
文件:tools/executor.py
|
| 工具结果会被整理成 observation
| 长输出会被截断
v
[工具结果回灌到 messages]
|
v
[下一轮 Agent 推理]
|
+--------------------------------------+
子 Agent 继承链路
----------------
[父 Agent 创建子 Agent]
文件:tools/agents_graph/agents_graph_actions.py
|
| if inherit_context=True
| -> 取父 Agent conversation_history
v
[继承到子 Agent 的上下文]
|
| 被包成:
| <inherited_context_from_parent> ... </inherited_context_from_parent>
|
| 系统明确告诉子 Agent:
| 这只是背景,不是让你继续父任务
v
[子 Agent 自己的 messages]
|
| 子 Agent 继续按自己的任务跑
| 也会继续走“LLM -> 工具 -> 回灌 -> 压缩”
v
[共享消息队列]
文件:tools/agents_graph/agents_graph_actions.py
|
| send_message_to_agent()
| agent_finish() 回传 completion report
v
[BaseAgent 定期轮询队列]
文件:agents/base_agent.py
|
| _check_agent_messages()
| 把消息转成自己的 user message
v
[子 Agent 继续执行]
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)