Replies: 1 comment
|
这五条里有一条被标题埋掉了,我想先把它拎出来——第 3 条不是"死循环"的一部分,它是独立的数据损坏,而且是这五条里唯一造成不可逆后果的。 一、第 3 条应该单独开一帖工具自己知道有 1771 行,却只给了 1482 行,还不说。 后面接一个 write,文件就被腰斩——你实测的 11,688 行掉到 1,718 行、 这条和死循环没有因果关系:就算第 1 条的看门狗做出来了,第 3 条照样会悄悄毁文件,只是毁得快一点。而现在它躺在一个叫「死循环」的帖子的第 3 项里,维护者按标题分诊时几乎必然会把它当成循环问题的附属现象。 建议单开一帖,标题直写后果,比如 " (你说"如需要可提供最小化复现脚本"——对这一条我建议不要等人要,直接附上。一个能稳定复现的静默丢行脚本,是这五条里最容易被立刻接受的东西。) 二、第 2 条我可以给一个具体的根因和当场能用的绕法你写的是"可能 \r\n / 尾随空白"。基本可以确定就是 你在 Windows 上,文件多半是 CRLF 行尾。如果 grep 是按 于是 当场可用的绕法:把行尾锚点写成 这在 LF 和 CRLF 文件上都成立,你现在就能用,不用等修复。 (如果这个绕法有效,那就等于替维护者确认了根因——建议把结果补到帖子里,比"可能是行尾问题"这句推测有力得多。) 三、第 1 条:看门狗会掩盖问题,值得在提案里点破你的 1、2、4 其实是一条链: 你自己已经看到了 2→1 这一段。我想补的是:这说明循环是症状,不是病。 所以第 1 条那个"最大工具调用次数 / 最大墙钟时间"的看门狗,做出来是对的(任何 agent 运行时都该有刹车),但它治的是"卡死会话"这个后果,不是"为什么会转不出来"。 如果只做看门狗,你这次的故障会从"会话卡死"变成"跑了 80 轮然后放弃,文件改了一半"——后者更难发现。 建议在提案里把这两件事分开写:
第 4 条你提的"按匹配文本直接返回、别让调用方拿行号去二次定位"我觉得特别对。这是一类通用问题:任何"先拿位置、再按位置取内容"的两步流程,中间只要有写操作就一定会漂。给出内容级定位(或者给一个能校验的 token)能一次性消掉这一整类失败,比让调用方自己记得重新 grep 可靠得多。 四、第 5 条:这条改起来最便宜"requires reading first" 不告诉你要读哪个文件——这是纯粹的文案问题,把文件路径写进报错就完事了。 顺带说,这条和你其余四条属于同一个主题:工具的报错没有携带调用方据以纠正行为所需的信息。 第 5 条是不知道读哪个文件;第 2 条是匹配失败但不知道为什么(行尾看不见);第 1 条是循环了但没人喊停。你这一帖实际上是一份"工具层可诊断性"的清单——如果重新组织,按这条线索排比按严重度排更有说服力。 边界与利益相关我们不修 DSH 自家组件—— 第二节那个 利益相关:我维护 pi2dsh(Pi 生态兼容层)。这条不推销——你踩的是 DSH 原生工具的缺陷,换一套插件不会让 |
Uh oh!
There was an error while loading. Please reload this page.
Harness Bug Report: run_code 脚本死循环 + 工具层数据一致性问题
run_code编写脚本,对 ~200 个源文件做批量查找-替换迁移(utility/css、utility/attribute 等 C++ 工程)1. [严重] 单次 run_code 执行无迭代/时长预算,工具调用循环可直接把会话卡死
agent 生成的脚本用 "grep 找下一个匹配 → edit 替换 → 再 grep" 的 while/guard 循环处理多文件。当一次 edit 的结果仍满足下一次 grep 的模式(例如替换文本中仍含被搜模式、或 old==new 时),循环在同一行上永远重新匹配,没有进度推进。harness 对单次
run_code的工具调用总数/总时长没有任何上限或看门狗,于是会话(该任务)整体挂起,只能人工 kill 整个任务才能恢复。复现要点(伪代码):
期望:harnharness 为
run_code提供「单次执行最大工具调用次数 / 最大墙钟时间」并强制中断(类似 goal 轮次),或至少在无进展时终止。2. [中] tools.grep 的
$行尾锚点与 tools.read 的行内容不一致观测:文件行
return GetAreaView()->GetAreaFeatures()->GetAlt();确实存在,但tools.grep({ pattern: "GetAlt\\(\\);$" })返回 0 条;去掉$后命中。说明 grep 侧对行尾(可能 \r\n / 尾随空白)的处理与 read 侧不一致。这一差异直接导致上一条的「找不到 → 反复重试」循环被写出。3. [严重] tools.read 在大文件/超长行文件上静默丢行,配合 write 造成文件截断损坏
实测三次:
tools.read({ offset: 1, limit: 2000 })只返回 1,482 行,而totalLines报告 1771 —— 丢行是静默的,没有任何报错;期望:
read返回的行数与totalLines必须一致或显式报错;绝不静默丢弃中间行。4. [中] grep 行号在一次脚本内多次 edit 后漂移
同一个
run_code里"先 grep 拿行号、再按行号 read 取内容"的流水线,在前面的 edit 改变了行数后,后面 grep 返回的行号指向旧内容(read 出来的首行与 grep 匹配文本不一致,出现大量 "nodef/set? 漂移" 跳过)。行号应被视为易失信息,建议 grep/read 提供内容级定位(如grep --with-context或按匹配文本直接返回)。5. [低] edit 的 "requires reading first" 缓存语义不清
同一脚本内前几次 edit 成功,后续对另一文件的首次 edit 报 "requires reading first";而先调用一次小范围 read 再 edit 即可成功,说明"已读"状态有文件级缓存,但失效规则不透明。建议在错误信息中直接说明要求(读哪个文件)。
附加
git checkout+ 重放 edit 列表,期间多次中断(用户 kill)。All reactions