Files
dsh_ai1net_server/docs/会话与接续/省积分_四个根治方法详解_20260915.html
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

180 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>省积分 · 四个根治方法详解</title>
<style>
:root{
--ink:#0b1220; --mut:#6b7688; --line:#e6e9ee; --bg:#f4f5f7;
--red:#c02626; --redbg:#fef2f2; --redln:#fecaca;
--amb:#b45309; --ambbg:#fffbeb; --ambln:#fde68a;
--grn:#0a7a4f; --grnbg:#ecfdf5; --grnln:#bbf7d0;
--blu:#1d4ed8; --blubg:#eff6ff; --bluln:#bfdbfe;
}
body{margin:0;padding:26px 14px 40px;background:var(--bg);color:var(--ink);
font-family:system-ui,-apple-system,"Segoe UI","Microsoft YaHei",sans-serif;
-webkit-font-smoothing:antialiased;line-height:1.5}
.wrap{max-width:940px;margin:0 auto}
.card{background:#fff;border:1px solid var(--line);border-radius:18px;padding:24px 26px;margin-bottom:14px;
box-shadow:0 1px 2px rgba(11,18,32,.04),0 10px 28px -14px rgba(11,18,32,.13)}
h1{font-size:28px;line-height:1.3;margin:0 0 8px;letter-spacing:-.7px;font-weight:800}
h1 em{font-style:normal;color:var(--red)}
.sub{font-size:14.5px;color:var(--mut);font-weight:700;margin:0}
.sub b{color:var(--ink)}
.mh{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.no{font-size:13px;font-weight:800;color:#fff;background:var(--ink);border-radius:8px;padding:4px 9px;letter-spacing:.5px}
.mt{font-size:21px;font-weight:800;letter-spacing:-.4px;margin:0}
.tag{font-size:12.5px;font-weight:800;border-radius:999px;padding:4px 11px;white-space:nowrap}
.t-red{color:var(--red);background:var(--redbg);border:1px solid var(--redln)}
.t-amb{color:var(--amb);background:var(--ambbg);border:1px solid var(--ambln)}
.t-grn{color:var(--grn);background:var(--grnbg);border:1px solid var(--grnln)}
.t-blu{color:var(--blu);background:var(--blubg);border:1px solid var(--bluln)}
table{width:100%;border-collapse:collapse;font-size:14px}
th,td{text-align:left;vertical-align:top;padding:9px 12px 9px 0;border-bottom:1px solid #f1f3f6}
th{width:96px;color:var(--mut);font-weight:800;white-space:nowrap;font-size:13px}
tr:last-child td,tr:last-child th{border-bottom:0}
td b{color:var(--red)}
code{background:#f3f4f6;border:1px solid #e8eaee;border-radius:5px;padding:1px 5px;font-size:12.8px;
font-family:ui-monospace,Consolas,monospace}
.warn{background:var(--redbg);border-left:4px solid var(--red);border-radius:0 12px 12px 0;
padding:14px 18px;font-size:14.5px}
.warn .wt{font-weight:800;color:var(--red);font-size:15.5px;margin-bottom:8px}
.warn ul{margin:8px 0 0;padding-left:20px}
.warn li{margin:5px 0}
.fx{margin-top:12px;padding:11px 15px;border-radius:11px;font-size:14px;font-weight:700;
background:#f8fafc;border:1px dashed #dbe1e8}
.fx span{color:var(--red);font-weight:800}
.state{display:inline-block;font-size:12.5px;font-weight:800;border-radius:6px;padding:3px 8px}
.s-on{color:var(--grn);background:var(--grnbg)}
.s-off{color:var(--amb);background:var(--ambbg)}
.rel{display:flex;gap:10px;flex-wrap:wrap;margin-top:6px}
.rel div{flex:1 1 190px;background:#f8fafc;border:1px solid #e8ecf1;border-radius:12px;padding:12px 14px;font-size:13.5px}
.rel b{display:block;font-size:15px;margin-bottom:3px}
.foot{font-size:12.5px;color:var(--mut);text-align:center;margin-top:6px}
/* ── 手机端:表格改竖排,禁止横向撑破 ─────────────────── */
@media (max-width:600px){
body{padding:16px 10px 26px}
.card{padding:17px 15px;border-radius:14px}
h1{font-size:22px;letter-spacing:-.4px}
.mt{font-size:18px}
.sub{font-size:13.5px}
table{font-size:13.5px}
tr{display:block;border-bottom:1px solid #f1f3f6;padding:8px 0}
tr:last-child{border-bottom:0}
th,td{display:block;width:auto;border:0;padding:0}
th{padding-bottom:3px}
td{padding-bottom:2px}
.warn{font-size:13.5px;padding:13px 14px}
.warn ul{padding-left:17px}
.fx{font-size:13px}
.rel div{flex:1 1 100%}
}
</style></head><body><div class="wrap">
<div class="card">
<h1>省积分 · <em>四个根治方法</em>详解</h1>
<p class="sub">成本 = <b>请求次数 × 当时上下文体积</b>。历史只增不减、输出永久驻留、每轮全量重发 ——<br>
四个方法分别打在这个链条的不同环节上。</p>
</div>
<div class="card">
<div class="warn">
<div class="wt">先纠正一个口径:第 1 轮「只产生 27 万 token」吗?</div>
实测同一个会话(443 次带 usage 的模型请求):
<ul>
<li><b>27 万</b>(269,522)= 第 1 轮<b>结束时上下文的绝对体积</b>。这是"水位",只算一次。</li>
<li><b>1,090 万</b>(10,906,992)= 第 1 轮<b>实际计费的 input 合计</b>。101 次请求,每次都把当时的全部历史重发一遍。<br>
⇒ 两者差 <b>40 倍</b>。</li>
<li>而第 1 轮在全量 1.93 亿里只占 <b>5.6%</b> —— 它的问题不是"贵",是<b>把水位顶起来了</b>。</li>
<li>真正最贵的是<b>第 11、12 轮</b>:22.0% + 18.4% = <b>40.4%</b>。它们在 68 万的水位上,各跑了 <b>66 / 55 次</b>请求。</li>
</ul>
<div style="margin-top:10px;font-weight:800;color:var(--red)">
⇒ 「顶水位」(第 1 轮)和「在高水位上跑请求」(第 11/12 轮)是两件事,后者更贵。
</div>
</div>
</div>
<div class="card">
<div class="mh"><span class="no">方法 ①</span><h2 class="mt">批量活写脚本</h2><span class="tag t-red">打在:请求次数</span></div>
<table>
<tr><th>干什么</th><td>同质的小改动(清注释、改文案、换版本号、批量改名)<b>不逐处 Edit</b>,写一个脚本一次做完。</td></tr>
<tr><th>触发条件</th><td>同一会话内对同一文件 ≥3 次编辑,或待办本身是"同类 × N 处"。</td></tr>
<tr><th>为什么根治</th><td>一次工具调用在历史里留两条记录(入参 + 结果),<b>后续每一轮都要重发</b>。<br>
把 N 次编辑压成 1 次 ⇒ 历史里的工具痕迹从 <b>2N 条降到 2 条</b>,且不再随轮数放大。</td></tr>
<tr><th>实测</th><td>出事那轮:<b>101 次请求</b>、142 次文件编辑、179 次命令,只为清 96 处同类注释。<br>
改成 1 个脚本 ⇒ 请求数可降到个位数级别。</td></tr>
<tr><th>现状</th><td><span class="state s-off">未实现</span> —— 属"操作纪律",不是硬门禁。</td></tr>
<tr><th>代价</th><td>脚本要写对;一次动的地方变多 ⇒ 必须先 dry-run + 备份。写错的话影响面比逐处改大。</td></tr>
<tr><th>落地</th><td>写进根 <code>CODEBUDDY.md</code> 的操作纪律;钩子里对"同文件第 3 次编辑"给提示。</td></tr>
</table>
<div class="fx">收益量级:单轮请求数 <span>101 → 10 上下</span>,该轮计费量随之腰斩再腰斩。</div>
</div>
<div class="card">
<div class="mh"><span class="no">方法 ②</span><h2 class="mt">拦大输出</h2><span class="tag t-grn">打在:每次请求的体积</span></div>
<table>
<tr><th>干什么</th><td>硬门禁(<code>PreToolUse</code>)拦 6 类<b>高置信度</b>命令:<br>
<code>cat</code> 大文件(&gt;200 KB)· <code>ls -R</code> · <code>find &lt;根&gt;</code> 无 <code>-maxdepth</code> ·
<code>journalctl</code> 无 <code>-n/--since</code> · <code>dmesg</code> 无 head · <code>Read</code> 超大文件(&gt;400 KB)</td></tr>
<tr><th>放行什么</th><td>一切带管道的写法(<code>| head</code> / <code>| grep</code> / <code>| wc -l</code>)——输出已被下游截断,不构成风险。</td></tr>
<tr><th>为什么根治</th><td>上下文体积<b>只增不减</b>。一条 2 MB 输出进去,就永久占 2 MB,<b>再乘以后面每一次请求</b>。<br>
⇒ 拦一条 = 省 <code>字符数 ÷ 2.11 × 剩余请求数</code> 的 token。</td></tr>
<tr><th>实测</th><td>回放 <b>4,053 条真实命令</b>:误拦率从 1.63% 收到 <b>0.05%</b>(2 条,且都是真阳性)。</td></tr>
<tr><th>现状</th><td><span class="state s-on">已上线</span> —— 配置已挂 <code>Bash|Read</code>,完全重启后生效。</td></tr>
<tr><th>代价</th><td>低。带 <code>DSH_OUTPUT_GUARD_OFF=1</code> 应急开关;三档 soft / hard / off 可切。</td></tr>
<tr><th>落地</th><td>无需额外动作,重启即生效。</td></tr>
</table>
<div class="fx">这是<span>唯一</span>在"灌进去之前"就把体积掐掉的手段,其余三个都是事后收敛。</div>
</div>
<div class="card">
<div class="mh"><span class="no">方法 ③</span><h2 class="mt">命令限流</h2><span class="tag t-amb">打在:高水位段的请求次数</span></div>
<table>
<tr><th>干什么</th><td>软告警(<code>UserPromptSubmit</code> 钩子):读本会话 usage,当"当前体积"或"单轮工具调用次数"越线时,<br>
向下一轮注入一句话 ——「本轮已 66 次调用、水位 68 万,请收敛成一个脚本 / 一次批量操作」。</td></tr>
<tr><th>为什么根治</th><td>①② 降的是<b>每次请求的体积</b>,③ 降的是<b>请求次数</b>。成本 = 次数 × 体积,<b>两个都要压</b>。</td></tr>
<tr><th>实测</th><td>第 11 轮:<b>66 次请求 × 64 万水位 = 4,247 万</b>(占全量 22%)。<br>
同轮若收敛到 10 次请求,量级掉到 640 万左右 ⇒ 省下全量的 <b>约 19%</b>。</td></tr>
<tr><th>现状</th><td><span class="state s-off">未接入</span> —— 钩子本体已存在,限流提示被取消,尚未接回。</td></tr>
<tr><th>代价</th><td>提示本身占约 50 token,可忽略;但它只是"劝",AI 不理会就无效 ⇒ 软约束。</td></tr>
<tr><th>落地</th><td>把 <code>stop-dialog-guard.py</code> 的 <code>budget_note()</code> 重新接上(改一个 if 条件)。</td></tr>
</table>
<div class="fx">它治的是"<span>在水位已经很高时还猛跑请求</span>"这个最贵的模式。</div>
</div>
<div class="card">
<div class="mh"><span class="no">方法 ④</span><h2 class="mt">切会话</h2><span class="tag t-blu">打在:让体积归零</span></div>
<table>
<tr><th>干什么</th><td><b>一个需求一个会话</b>。需求闭环就新建会话,不开"万能长会话"。</td></tr>
<tr><th>为什么根治</th><td>这是<b>唯一能让上下文归零</b>的手段。历史是 append-only,<b>AI 无权删自己的历史</b> ——<br>
所以在一个 59 万水位的会话里"少说两句"完全没用,体积不会降一分。</td></tr>
<tr><th>实测</th><td>目标会话末段水位 593,510。有几轮指令只有几个字(如"推送"),却仍要重发 <b>49.8 万 token</b>;<br>
那一轮 9 次请求合计 <b>443 万 input</b>,就为了推一次代码。</td></tr>
<tr><th>现状</th><td><span class="state s-off">纯纪律</span> —— 无工具强制;跨会话靠 <code>session-handoff/</code> 交接单。</td></tr>
<tr><th>代价</th><td>开会话要读交接单(几十 KB 一次),会话内上下文会丢 ⇒ 交接单必须写全。</td></tr>
<tr><th>落地</th><td>写进 <code>CODEBUDDY.md</code>:<b>一个需求一个会话;闭环即新建</b>。</td></tr>
</table>
<div class="fx">前三个是"<span>别让水位涨太快</span>",这一个才是"<span>把水位倒掉</span>"。</div>
</div>
<div class="card">
<div class="rel">
<div><b>① 批量活写脚本</b>少留痕迹 —— 从源头减少历史条目</div>
<div><b>② 拦大输出</b>别灌垃圾 —— 挡住单条巨型输出</div>
<div><b>③ 命令限流</b>高位少跑 —— 压住高水位段的请求数</div>
<div><b>④ 切会话</b>及时倒水 —— 唯一能归零的动作</div>
</div>
<div class="fx" style="margin-top:14px">共同根因:<b>历史只增不减,工具输出永久驻留,每轮全量重发</b>。
①②③ 在会话内减缓累积,④ 才是重置。会话内解决不了根因本身 —— 那要靠平台的压缩策略。</div>
</div>
<div class="foot">数据来源:目标会话转录逐条统计(443 次带 usage 的模型请求)| 折算比 2.11 字符/token</div>
</div></body></html>