回收 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)、记忆修复前备份。
180 lines
12 KiB
HTML
180 lines
12 KiB
HTML
<!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> 大文件(>200 KB)· <code>ls -R</code> · <code>find <根></code> 无 <code>-maxdepth</code> ·
|
||
<code>journalctl</code> 无 <code>-n/--since</code> · <code>dmesg</code> 无 head · <code>Read</code> 超大文件(>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>
|