SOP:新增判据 L(批量接口提醒)+ BASELINE 记「逐条 vs 批量入参」¶
主题目录:
batch-interface-20261007/|变更日期:2026-10-07|起因:slurm_ins系统侧 deploy 阶段优化结果(累计墙钟 −95.8%)
1. 背景¶
slurm_ins 的 deploy 阶段三项优化实测:整体墙钟 13.83 → 10.34 s、deploy 阶段 7.2 → 4.0 s、
远端命令 41 → 18,变更记录 225/25/200 逐条一致;三层堆叠后本会话累计 247.7 → 10.3 s(−95.8%)。
拆开看,三项改动其实是两类不同模式:
| # | 原状 | 改后 | 模式 |
|---|---|---|---|
| 1 | _stage_build 3 条探测逐条 |
拼一段 shell 一次往返 | 合并调用(省握手/往返) |
| 2 | _is_install_current 3~4 条探测逐条 |
同上 | 合并调用 |
| 3 | installed_packages_cmd:for p in …; do rpm -q $p; done |
rpm -q --qf … pkg1 pkg2 … |
整批入参(省进程启动与解析) |
关键:第 3 条不是"合并"——它把 N 次调用变成 1 次调用处理 N 个对象;而图上明确标注 「第三条是这次最大的单项收益」。
对照 agent 侧:第 1、2 类已由 判据 A/E 强制合并覆盖;第 3 类在 agent 侧没有任何判据(缺口)。
2. 目标¶
- 新增 判据 L(仅提醒):
RunCommand命令含逐项循环 → 提醒确认目标命令是否支持一次传多个参数; - 把「合并调用 ≠ 整批入参」写进稳定层
BASELINE.md§2,附slurm_ins实测数据; - 不强制——循环有时确属必要(目标命令不支持批量、或需在循环内分支),Hook 无命令语义。
3. 前置条件¶
- 可写
merge-guard/merge-guard.py与docs/BASELINE.md; - Hook 脚本改动即时生效(10-07 实测),故先离线验证再交;
- 判据 L 与已有判据 A/E 的分工必须写清(否则会被误认为重复)。
4. 影响范围¶
| 项 | 说明 |
|---|---|
| 涉及对象 | merge-guard(新增判据 L)、docs/BASELINE.md(新增机制条) |
| 是否停服 | 否;无窗口要求,改完下一次调用即生效 |
| 行为变化 | RunCommand 命令含循环时多注入一行提醒(每会话至多一次、约 70 字) |
| 不受影响 | A/B/D/E/F/I/J 强制判据、C/K 提醒、指纹放行、DENY_MAX / INJECT_MAX |
5. 分步操作¶
步骤 1:备份(必做)¶
TS=$(date +%Y%m%d-%H%M%S)
D=~/Documents/services/token_proxy/batch-interface-20261007/backup/home/rain/Documents/services/token_proxy
mkdir -p "$D/merge-guard" "$D/docs"
cp -p ~/Documents/services/token_proxy/merge-guard/merge-guard.py "$D/merge-guard/merge-guard.py.bak.$TS"
cp -p ~/Documents/services/token_proxy/docs/BASELINE.md "$D/docs/BASELINE.md.bak.$TS"
cp -p ~/Documents/services/token_proxy/docs/HANDOFF.md "$D/docs/HANDOFF.md.bak.$TS"
步骤 2:加判据 L(四处,成套)¶
- 常量
LOOP_RE(\bfor\s+\w+\s+in\b|\bwhile\s+read\b|\bxargs\b); PROMPTS["L"]与文档头判据列表同步;- 主流程独立判定块(不进
_detect——L 是单次调用即可判的形态,且仅提醒); - 状态加
l_fired键(每会话一次)。
坑:
- L 的提示文本不含 %d,故不能用 PROMPTS[mark] % args,直接取字符串;
- L 走独立标记(l_fired)而不占 INJECT_MAX——否则会与判据 C 争提醒额度;
- 可复用 _cmd_raw(tool_input) 取命令原文(它兼容 command / cmd / script 三个字段),
不要自己再解析 tool_input。
cd ~/Documents/services/token_proxy
python3 -m py_compile merge-guard/merge-guard.py && echo "语法通过"
grep -n "LOOP_RE\|l_fired" merge-guard/merge-guard.py | head
步骤 3:离线验证(每个分支用独立 session)¶
坑:l_fired 是"每会话一次",若四个用例共用一个 session,只有第一条会触发——
这是设计而非缺陷,但会让验证误判"分支失效"。故每个用例给独立 session_id。
cd ~/Documents/services/token_proxy && python3 - <<'PY'
import json, subprocess, sys
H = "merge-guard/merge-guard.py"
def run(cmd, sid):
e = {"hook_event_name": "PreToolUse", "session_id": sid, "agent_id": "a",
"tool_name": "RunCommand", "tool_input": {"command": cmd}}
return subprocess.run([sys.executable, H], input=json.dumps(e), capture_output=True, text=True).stdout
for cmd, sid, desc in [("for p in a b; do rpm -q $p; done", "T1", "for 循环"),
("printf x | xargs -n1 echo", "T2", "xargs"),
("while read l; do echo $l; done < f", "T3", "while read"),
("ls -l /tmp", "T4", "无循环")]:
out = run(cmd, sid)
print("%-12s -> %s" % (desc, "含批量接口提醒" if "批量接口提醒" in out else "静默"))
PY
预期:前三条触发、第四条静默。验证后清理 guard_events 里的测试行与 merge-guard/state/T*。
步骤 4:BASELINE.md 记「逐条 vs 批量入参」¶
在 §2「机制与陷阱」加一条,须写明:① 合并调用省往返、整批入参省进程,二者不可替代;
② slurm_ins 的实测数字与"整批入参是最大单项收益";③ 同族口径——exec_linux 内部是
for cmd: conn.run_cmd(cmd),一次传多条命令不减往返。
坑:本条要追加在「诊断工具口径必须自证」那条之后,不要替换它(本轮第一次编辑即误替换, 已当场恢复并校验)。
grep -c "口径必须自证" ~/Documents/services/token_proxy/docs/BASELINE.md # 预期 1
grep -c "逐条」与「批量入参" ~/Documents/services/token_proxy/docs/BASELINE.md # 预期 1
6. 验证¶
| 层级 | 命令 | 预期 |
|---|---|---|
| 语法 | python3 -m py_compile merge-guard/merge-guard.py |
无输出 |
| 三分支 | 步骤 3(独立 session) | for / xargs / while read 均触发,无循环静默 |
| 每会话一次 | 同一 session 连发两次循环命令 | 第一次触发、第二次静默 |
| 真机 | 在真实会话里发一条含循环的 RunCommand |
注入「【批量接口提醒】…」 |
| 稳定层 | 步骤 4 的两条 grep -c |
均 1 |
7. 回滚¶
备份位置:batch-interface-20261007/backup/home/rain/Documents/services/token_proxy/{merge-guard,docs}/,
台账见 backup/README.md。
cp -p ~/Documents/services/token_proxy/batch-interface-20261007/backup/home/rain/Documents/services/token_proxy/merge-guard/merge-guard.py.bak.20261007-082707 \
~/Documents/services/token_proxy/merge-guard/merge-guard.py
python3 -m py_compile ~/Documents/services/token_proxy/merge-guard/merge-guard.py && echo "回滚后语法通过"
回滚后验证:grep -c "LOOP_RE" merge-guard/merge-guard.py 为 0(判据 L 消失)。
BASELINE.md 的机制条建议保留(它记录的是事实,与判据 L 是否存在无关)。
8. 风险说明¶
| 风险 | 缓解 |
|---|---|
| L 与 A/E 重复、造成噪声 | 分工写进 docstring:A/E 管合并省往返,L 管整批入参省进程;L 每会话至多一次 |
| 循环本是必要的(误报) | 只提醒不强制;文本为"先确认目标命令是否支持批量入参",非"必须改" |
| 验证时误判"分支失效" | 步骤 3 明确要求每个用例独立 session(l_fired 每会话一次) |
| 编辑 BASELINE 时误替换相邻条目 | 步骤 4 的两条 grep -c 断言(各 1 处);本轮已实际踩到并修复 |
正则误伤(如命令里含字符串 for) |
\bfor\s+\w+\s+in\b 要求完整 for … in 结构,普通文本不会命中 |
附录:交付物清单¶
| 文件 | 说明 |
|---|---|
merge-guard/merge-guard.py(改) |
判据 L:LOOP_RE + PROMPTS["L"] + 独立判定块 + l_fired 状态键 |
docs/BASELINE.md(改) |
§2 新增「逐条 vs 批量入参」机制条 |
docs/HANDOFF.md(改) |
判据数 9 → 10;3.2 的 K 行扩为 K/L |
batch-interface-20261007/SOP.md |
本文档 |
batch-interface-20261007/backup/ |
三份备份与台账 |
来源:
/home/rain/Documents/services/token_proxy/batch-interface-20261007/SOP.md| 最后更新:2026-10-07 08:28(由build/sync.py同步,请勿在站点侧修改)