fix(agent): 文本兜底解析裸多行JSON tool_call——LLM输出无围栏连续动作对象时误当交付件正文deliver
pbls M1a第四轮实测:角色LLM在长上下文里输出连续多行裸{"action":"tool_call",...}(无```围栏),整体json.loads失败+围栏扫描无命中→兜底把tool_call文本当result deliver→交付件content是JSON文本、files_json只剩快照,QC必退且退回理由失真(实际代码/git提交都真实落地了)。修:_parse_agent_action加raw_decode逐段扫描取第一个动作对象。本地单测6/6(多对象/单deliver/纯文本/围栏优先/坏前缀跳过/DSML不回归)
This commit is contained in:
parent
715be0b387
commit
66387c4210
@ -2032,6 +2032,28 @@ def _parse_agent_action(raw):
|
||||
if isinstance(d, dict) and 'tool' in d:
|
||||
return {"action": "tool_call", "tool": d.get("tool", ""), "params": d.get("params") or {}}
|
||||
|
||||
# 裸 JSON 动作对象扫描(2026-09-15 pbls M1a 实测):LLM 连续输出多个无围栏的
|
||||
# {"action":"tool_call",...} 对象(一行一个)——整体 json.loads 失败(多对象拼接)、
|
||||
# 围栏扫描无命中 → 兜底把 tool_call 文本当交付件正文 deliver → 交付件 content
|
||||
# 就是 JSON 文本、files_json 只有快照文件,QC 必退且退回理由失真。
|
||||
# raw_decode 逐个扫描,取第一个可解析的动作对象。
|
||||
_dec = json.JSONDecoder()
|
||||
_idx = 0
|
||||
while True:
|
||||
_b = raw.find('{', _idx)
|
||||
if _b < 0:
|
||||
break
|
||||
try:
|
||||
_d, _end = _dec.raw_decode(raw[_b:])
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
_idx = _b + 1
|
||||
continue
|
||||
if isinstance(_d, dict) and 'action' in _d:
|
||||
return _d
|
||||
if isinstance(_d, dict) and 'tool' in _d:
|
||||
return {"action": "tool_call", "tool": _d.get("tool", ""), "params": _d.get("params") or {}}
|
||||
_idx = _b + max(_end, 1)
|
||||
|
||||
return {"action": "deliver", "result": raw}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user