From 00bbe42823af5b6834cc7b4add8ca343a2d0ad9e Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 21 Jul 2026 09:05:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(prompt):=20=E7=B3=BB=E7=BB=9F=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E5=8A=A0=E6=8A=A4=E6=A0=8F=E2=80=94=E2=80=94=E5=A4=A7?= =?UTF-8?q?=E6=AE=B5=E4=B8=AD=E6=96=87=E6=AD=A3=E6=96=87=E5=88=AB=E5=86=85?= =?UTF-8?q?=E8=81=94=E8=BF=9B=20.py=20=E6=BA=90=E7=A0=81(bump=200.58.51)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 失败面板 run_python/error 语法预检簇(近7天31次/12task)根行为=模型手写 python-docx/pptx 把大段中文正文硬拼进 .py,ASCII 引号/全角标点/缩进崩成 SyntaxError。 定位:现有正规路径充分(出 docx 的 skill 全指向 rendering/render.py md->docx、且写 "别自己手搓"),但 DB 显示 16 涉事 task 中 7 个没 load 任何 skill→够不着 SKILL 指引; precheck(pysyntax)已 host 侧拦截+回根治 tip+喂 RepeatGuard,浪费已 bound(每任务~2.6次 自愈、无失控循环)。故走最高覆盖最低改动:base 系统提示 general_v1.md(所有任务加载)的 run_python 段加一句原则级护栏——大段中文正文先 write 进 .md/.txt 再 read、有 skill 优先 走其渲染路径(守 recipe-ban,不给可 copy 配方)。纯提示词引导、无法端到端 verify,ROI 本 就低(precheck 已兜),只求少发。遗留:改现有 .docx 无平台路径,需另设计。 顺带补 PROGRESS 缺失的 0.58.50 条目(salvage 提示降噪,并行 session 提交)。 Co-Authored-By: Claude Opus 4.8 (1M context) --- PROGRESS.md | 4 +++- core/__init__.py | 2 +- prompts/system/general_v1.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/PROGRESS.md b/PROGRESS.md index e73ac2a..15f9d46 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2,7 +2,7 @@ > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。 -最后更新:2026-07-21(glm.pro52 空响应定层+治本:禁 thinking 免推理烧穿输出上限 + loop 区分截断,bump 0.58.49) +最后更新:2026-07-21(系统提示加护栏:大段中文正文别内联进 .py——run_python 语法预检失败第一大头治本,bump 0.58.51) --- @@ -24,6 +24,8 @@ ### 2026-07 - **07-21 / 0.58.50 / salvage 成功提示降噪(黄→灰)**:用户反馈"工具调用参数损坏但已就地抢救"黄字吓人、问是否影响后续对话——核实**零影响**(salvage 只就地改写 arguments,当轮照常执行,对话历史与正常轮无异;warn 是纯前端 SSE 展示事件,不入 messages 不回灌 LLM,刷新即消失)。处置:不全静默(上游返脏数据的事实要可见、可与 `tool_salvaged` DB 留痕对上),改**分级降噪**——`loop.py` 该 emit 加 `level:"info"` + 措辞软化「已自动修复工具调用参数…继续执行」;`chat.js` warn 渲染按 level 分流,info 走灰色 muted 无 ⚠,黄色 ⚠ 只留给真打断本轮的路径(丢弃重试/熔断等)。 +- **07-21 / 0.58.51 / 系统提示护栏:大段中文正文别内联进 .py(run_python 语法预检失败治本)**:失败面板 `run_python/error` 语法预检簇(近7天31次/12task)根行为=模型手写 python-docx/pptx 把大段中文正文硬拼进 .py 源码,ASCII 引号/全角标点/缩进崩成 SyntaxError。定位:①现有正规路径充分(所有出 docx 的 skill 都指向 `rendering/render.py` md→docx、且写"别自己手搓"),但 DB 显示 16 个涉事 task 中 **7 个没 load 任何 skill**→够不着 SKILL 指引;②precheck(pysyntax)已 host 侧拦截+回根治 tip+喂 RepeatGuard,浪费已 bound(每任务~2.6次自愈、无失控循环)。故走**最高覆盖、最低改动**:base 系统提示 `prompts/system/general_v1.md`(所有任务加载)的 run_python 段加一句**原则级**护栏——生成/改 docx·pptx 时大段中文正文别内联进 .py、先 write 进 .md/.txt 再 read、有 skill 优先走其渲染路径(守 recipe-ban 不给可 copy 配方)。纯提示词引导、无法端到端 verify,ROI 本就低(precheck 已兜),只求少发。**遗留 Option 4**:改现有 .docx 无平台路径(render.py 只从 md 新生成),模型只能手写 python-docx→内联中文,需另设计(docx→md 拆/模板填充)。`prompts/` 每次 build 实时读、`git pull` 即生效免重启。 +- **07-21 / 0.58.50 / salvage 成功提示降噪**:抢救成功的畸形 tool_call 对后续对话零影响(warn 纯前端 SSE 不入 messages),黄色⚠警告降级为灰色 info 行(emit 加 level:"info"),黄⚠只留真打断路径。改 web UI + loop emit。 - **07-21 / 0.58.49 / glm.pro52 空响应治本(禁 thinking + loop 区分截断)**:探针定层坐实根因链——①`max_output` 是**全仓死字段**(只在 capabilities.py 定义,`_build_kwargs` 零引用,`max_tokens` 从不发)→ 网关放任 glm-5.2 跑到自带 65536 输出上限;②glm-5.2 thinking **网关侧默认开**(线上探针实测 reasoning_content=766>0,尽管 config thinking_mode:false —— 那开关是 glm.yaml 未做的 TODO,根本没传);③重任务(100k 上下文)上思考膨胀烧穿 65536 被截断(finish_reason=length)、content 空 → loop 判空响应整轮丢弃 + **同上下文无效重试**(task 35744bea:5 次 empty 全 tokens_out=65536,事件4=attempt2 铁证);后果单任务烧 ~327k 输出 token。与 opus48/deepseek 网关 wire bug 不同根。**修**:`core/llm.py._build_kwargs` 加 family=="glm" 分支,据 thinking_mode 透传 `extra_body={"thinking":{"type":"enabled|disabled"}}`(GLM 协议,与 reasoning_effort 不同族)——线上探针 A/B 实测 disabled 后 reasoning_content 766→0、正文照常;`core/loop.py` 加 `_finish_reason`,空响应路径区分 length(截断,我方预算烧穿,重试无效)与 wire 吐空,warn 措辞据实 + `record_empty_response` units 记 finish_reason(JSON 免 migration,便于面板区分性质)。修好既坏的 test_loop_empty_response(mock 缺 executor)+ 补截断措辞用例,61 测试全绿。探针 `scripts/diag_glm_empty_probe.py` 留仓(monkeypatch _resolve_executor 绕沙箱池、PROBE_THINKING_OFF A/B 开关)。**遗留**:max_output 对所有模型仍未生效(本次只治 glm thinking 根因,没盲发 max_tokens——怕截断大 write 的 args);要不要让 max_output 全局生效需单独评估各档安全值。 - **07-20 / 0.58.48 / glm.pro52 空响应定层探针**:失败面板 empty 簇(15)主角从 opus48 换成 `glm.pro52`(11/15)。加 `scripts/diag_glm_empty_probe.py`——`build_agent(resume=True)` 复原真实 system prompt + 全工具 schema + **完整多轮上下文**(空响应发生在深层,单条 user 消息复现不了,这是与 2a1bc25d narrated 探针的关键差别),打 glm.pro52,三态判定 EMPTY(真吐空)/NARRATED(工具意图漏成正文)/STRUCTURED。默认锁 task 35744bea(近7天 empty 5 次最可复现)。本机 import litellm 卡 ~20min,交生产机 `.venv/Scripts/python.exe scripts/diag_glm_empty_probe.py` 跑,输出写 `scripts/_glm_empty_probe_*.txt`。定层后再决处置。 - **07-20 / 0.58.47 / 工具失败面板 6 簇巡检 + svg 质量门签名诚实化**:扫近7天失败聚集逐簇定根因。①**write/edit malformed(45/32)**=100% DeepSeek v4 wire 把并行 tool_call 的 arguments 拼成 `{...}{...}`,salvage(0.58.24)复盘提前到 07-20:命中率稳 ~85%(post-launch salvaged 252/malformed 44)、残差涉事 task 全在跑无终态失败=落非流式重试自愈,**决策保持现状不再写代码**(面板绝对数被上线前 07-13/14 尾巴撑高,要看 salvaged/malformed 比)。②**shell/exit "Font issues"(20)**=`svg_quality_checker` 质量门按设计 exit-1,但 `toolfail._classify` 取 `[exit]` 前尾行当签名,而尾行永远是通用 tip「4. Font issues:…」→ 所有门失败(typography/alignment/spec_lock drift)误标成 Font issues 误导排查。修:checker 在 errors>0 时末尾多打确定性 `gate_verdict_line()`「[GATE FAIL] svg_quality_checker: N error file(s) / M total; top issues: …」作为最后一行 stdout(放 main() 里 export 之后),toolfail 现有取尾行逻辑自动拾取诚实签名、toolfail 零改动;`_categorize_issue` 加 `spec_lock/typography` 类避免真错落 "Other"。补 3 测试(GateVerdictLineTests),39+3 全绿。③**run_python 预检(31)**=pysyntax 按设计拦中文正文硬拼进 .py(引号/缩进崩),非平台 bug=提示词治理待办。④**empty(15)**=主角换成 `glm.pro52`(11/15,非旧 opus48 案),需生产跑 narrated 探针定层(本机 import litellm 卡,task e7c2f50b 备用)。⑤**web_fetch(6)**=外部 403 拒抓为主,非平台锅。 diff --git a/core/__init__.py b/core/__init__.py index d2d0123..44e304f 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,3 +1,3 @@ # zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。 # 改版本只动这一行。 -__version__ = "0.58.50" +__version__ = "0.58.51" diff --git a/prompts/system/general_v1.md b/prompts/system/general_v1.md index be297f3..203ae6b 100644 --- a/prompts/system/general_v1.md +++ b/prompts/system/general_v1.md @@ -4,7 +4,7 @@ - `read` / `write` / `edit` —— 文件操作 - `glob` / `grep` —— 文件搜索 - `shell` —— 执行命令(默认 60s 超时) -- `run_python` —— 在子进程里跑 Python (数据处理、生成 .pptx/.docx、画图等)。非短小一次性代码时,先用 `write` 把 `.py` 落到 `/scripts/`(如 `scripts/analyze.py`),再 `run_python(script_path="scripts/analyze.py")` 执行 —— 源码留文件里可重读可改可重跑,不挤占对话历史;`scripts/` 只放过程脚本,交付产物仍落 task_dir 根或 SKILL 指定路径。真·一次性短代码(算个数/探查一行)才用 `run_python(code=...)` 内联。 +- `run_python` —— 在子进程里跑 Python (数据处理、生成 .pptx/.docx、画图等)。非短小一次性代码时,先用 `write` 把 `.py` 落到 `/scripts/`(如 `scripts/analyze.py`),再 `run_python(script_path="scripts/analyze.py")` 执行 —— 源码留文件里可重读可改可重跑,不挤占对话历史;`scripts/` 只放过程脚本,交付产物仍落 task_dir 根或 SKILL 指定路径。真·一次性短代码(算个数/探查一行)才用 `run_python(code=...)` 内联。生成 / 改 docx·pptx 时**大段中文正文别硬拼进 .py 源码**——ASCII 引号、全角标点、缩进极易把中文串崩成 SyntaxError 且报错误导(越照着改越错);正文先 `write` 进 `.md`/`.txt`,脚本 `read` 后再灌进文档,正文就不经过 Python 语法。有对应 skill(proposal / paper / brief 等)时优先走它指引的渲染路径,别自己手搓文档生成代码。 - `load_skill` —— 加载某个 skill 的完整指引 - `task_progress` —— 给 Web 前端发布/更新用户可见的进度步骤列表。只在多步骤任务使用;开始时设 3-7 个关键步骤,每完成或进入一个关键步骤时更新一次。 - `ask_user` —— 在真正的分叉点让用户在 2-4 个互斥方向间点选拍板(见下「方案确认约定」)。