Agent 每轮把接口返回的 20KB JSON 原样塞回 messages,第三轮开始报 context_length_exceeded,model 是 gpt-4o-mini,单次 tools 定义还占了两千 token。
一开始怀疑是「工具 schema 全量下发,挤占了可用上下文」,查了一圈,方向不对。
真正麻烦的地方在于,几个原因的现象几乎一样。工具结果没有截断,整段 JSON 都进了历史。也可能是同一份结果在多轮里重复保留,越滚越大。
不容易想到的是,没有按 token 预算做历史裁剪。
量一下每轮 messages 的 token 数
python -c "import tiktoken;e=tiktoken.get_encoding('cl100k_base');print(len(e.encode(open('msgs.json').read())))"
只保留结果里的关键字段再回填
python -c "import json;d=json.load(open('tool.json'));print(json.dumps({k:d[k] for k in ('id','status','amount')},ensure_ascii=False))"
超过阈值时把旧结果压成一句摘要
python -c "print({'policy':'keep_last_2_tool_results','max_tokens':6000})"
末了把工具定义按需下发,只带当前步骤要用的
python -c "print({'tools':['get_order'],'defer_others':True})"
别只看报错消失,验证要多做一步。五轮对话的 messages 稳定在六千 token 以内,工具结果只剩关键字段,任务照常完成且不再报超限。
上下文是预算而不是仓库,工具结果该剪就剪,留下能支撑下一步判断的字段即可,全量保留只会让模型更早撞上上限。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
