这类问题我又碰上了一次。Agent 调本地函数时收到 arguments 是 {"city":"上海"} 这样的字符串,函数内取 city 报 KeyError;日志里打印原始 tool_call,arguments 里还带着反斜杠和引号。

第一反应是「工具描述里示例写成字符串,模型照抄」,验证下来不成立。

这类报错背后常见的原因有几处,逐个排除就行。模型按字符串输出参数,客户端没有二次反序列化;SDK 版本差异,新旧字段一处给 dict 一处给 str;网关转发时把对象序列化了两次。

动手时先把 arguments 的原始类型和内容打出来

python -c "import json;d=json.load(open('t.json'));print(type(d['arguments']),d['arguments'][:80])"

再往下判断是否为字符串后做一次 json.loads

python -c "import json;s='{\"city\":\"上海\"}';print(json.loads(s) if isinstance(s,str) else s)"

然后在注册工具处加一层统一的参数解析

python -c "import json;parse=lambda a: json.loads(a) if isinstance(a,str) else a;print(parse('{\"n\":1}'))"

等前面都确认过,再用一次真实调用验证函数能拿到字段

python call_tool.py --name get_weather --args '{"city":"上海"}'

改完先别撤,确认这几项。函数内能直接按字典取字段,日志里不再出现反斜杠转义,连续 20 次调用无 KeyError。

提醒一点。这类问题多半出在客户端拼装而不是模型,收到参数先判类型再解析,比反复改提示词有效。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189