本地工具抛了 TimeoutError,框架把异常字符串直接写进 tool 消息,模型把这句英文错误当成查询结果,回答里出现了 Traceback 片段。

原因不止一个,得分开看。异常没有转换成结构化错误码;tool 消息里塞了完整堆栈,模型照抄;提示词没约定遇到错误时怎么回复;外层没有重试,直接进入下一轮。

先把 tool 消息的原始内容打出来确认

python -c "import json;print([m['content'][:120] for m in json.load(open('msgs.json')) if m['role']=='tool'])"

接着统一包装成 code 与 message 两个字段

python -c "import json;print(json.dumps({'code':'TOOL_TIMEOUT','message':'查询超时'},ensure_ascii=False))"

提示词里要求错误时先重试再说明

python run_agent.py --prompt prompts/tool_error.txt

等前面都确认过,再对 TOOL_TIMEOUT 做一次带退避的重试

python run_agent.py --retry 1 --backoff 2

中间停过一次,把已经改的东西回滚干净,再重新来一遍。

改完先别撤,确认这几项。tool 消息里不再出现堆栈,模型遇到错误会先重试并在回答里说明失败原因,用户侧不再看到 Traceback。

这里还有个坑。把原始异常直接透给模型等于让它猜,错误要先转成机器和模型都能读的短码,再由提示词决定后续动作。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189