Agent 调用工具可能返回超大结果(比如代码搜索返回 50KB),这会带来什么问题?你会怎么处理?OpenClaw 是怎么做的?
- 标签:AI、OpenClaw、大模型应用开发、AI应用开发、Agent开发
🏛 业务架构师
工具返回超大结果(如代码搜索返回 50KB)会带来三连问题:一是撑爆上下文窗口——一次调用就吃掉数万 token 预算,多来两次整个会话瘫痪;二是成本失控——这些 token 按 cache 未命中价计费,每次循环都要重复付费;三是效果劣化——大海捞针效应,模型反而抓不住关键信息,答案质量下降。
我的处理策略分层:
- 源头治理(工具侧改造):工具设计遵循"返回摘要+支持钻取"——默认返回结构化摘要(命中数、前 N 条预览、total),提供
fetch_detail(id)按需取明细。这是治本方案,新工具必须按此规范设计; - 传输治理(框架侧截断):结果超阈值(如 8K token)自动截断+尾部注明"已截断,共 X 条,可分页获取"——让模型知道信息不全,引导它分页而非瞎猜;
- 压缩治理:超长文本用小模型做"面向当前问题的摘要"后再入上下文;
- OpenClaw 的做法:Context Engine 统一做结果限幅与摘要,超限部分外置存储、按需引用——把"全量入窗"变成"按需取用"。
设计哲学:工具输出要当"邮件摘要"而不是"原始附件轰炸"——这个规范要在工具接入评审时强制卡住,事前一句话的事,事后救火的成本高百倍。
🏗 系统架构师
超大工具结果的三重危害:一是窗口挤占——50KB ≈ 12K+ token,直接吃掉几十轮对话的预算,触发历史裁剪,丢任务关键上下文;二是成本放大——Agent 循环每步都带全量上下文计费,这个 50KB 会在后续 N 步里被重复计费 N 次(无缓存时成本乘数效应);三是效果衰减——大段噪声稀释 attention,关键信息 lost-in-the-middle,模型决策质量下降。
我的处理分层:
- 源头限制:工具接口设计时就定义返回契约——最大条数、字段白名单、分页参数;API 类工具默认返回摘要 + 明细分页;
- 结果处理管道:截断(头部优先)→ 摘要(LLM/规则提取关键信息)→ 结构化提取(只留任务相关字段)——处理后再回填;
- 落盘外置:全量结果存工作区文件,上下文只留"文件路径 + 内容摘要",后续需要时用读取工具按需取(分段读)——OpenClaw 的典型做法,等价于把数据从内存换到磁盘换页加载;
- 检索化:超大结果(代码库搜索、长文档)转成可检索的临时索引,按 query 取片段。
OpenClaw 的做法:工具输出经过 Context Engine 的尺寸策略——超阈值自动截断/摘要 + 全文落盘 + 引用回填,模型可自主决定是否读取全文。架构原则:上下文里放"目录",数据放"外部存储",按需分页加载。
💻 全栈开发专家
超大工具结果的问题:上下文被挤爆(50KB ≈ 1.5 万 token,直接吃掉预算)、成本激增、检索/推理质量下降(有效信息被稀释)、甚至触发截断把 system prompt 挤出去。
我的三层处理方案(通用工程实践):
1. 工具端约束(治本,写工具时就做):
- 分页/限量参数:
limit、offset、maxResults默认小值; - 结果摘要化:返回
{summary, total, items_preview[3], cursor},全量数据落盘或留在源系统; - 结构裁剪:只返回模型需要的字段,去掉日志、时间戳等噪声。
python
@tool
def search_code(query: str) -> str:
hits = index.search(query, limit=50)
return f"共{len(hits)}处命中,前3处:\n" + "\n".join(
f"{h.path}:{h.line}" for h in hits[:3]) + f"\n需要细节用 read_file(path) 分页查看"2. 运行时防护:工具结果超过阈值(如 8k token)自动截断+摘要+提示模型「结果已截断,可用分页工具获取」;文件类结果存沙箱路径只回传路径。
3. 协作模式(OpenClaw 的思路):超大结果给子 Agent 消化——子 Agent 在独立上下文里读全量、产出百字结论回传父 Agent,父上下文只承担结论成本。这是「上下文隔离」模式,处理日志分析、代码库扫描这类必然大结果的场景最优雅。
原则:工具返回值的默认形态应该是「摘要 + 获取详情的后续手段」,全量裸返是设计失误。