# 记忆整理 SOP ## 核心原则:存在性编码 LLM自身是压缩器+解码器。L1只需让它**意识到某类知识存在**,它就能通过tool call自行取用深层内容。 **L1本质:用最短词数表达——什么场景下有什么记忆可用(存在性)。** L1两类内容,统一ROI评估: - **存在性指针**:指向L2/L3知识的最短触发词 - **行为规则**:不提醒就会犯的错(致命/高频均可,只要ROI过门槛) ROI = (不放这几个词的犯错概率 × 代价) / 每轮词数成本 ## 快速判断 **该留**:反直觉触发词——没提示就想不到去查SOP的场景词。如`tmwebdriver_sop(httponly cookie)`:没有`httponly cookie`这个词,你不会想到取cookie要查tmwebdriver **该删**: - 名字翻译:`proxy-pool/(代理池)` → 名字自解释,括号是废词,直接`proxy-pool`即可 - 内容描述:`opencli_sop(66站点CLI,复用Chrome session)` → 实现细节属于SOP内部,不是触发场景 - 直觉能力:不提醒也能想到 → 0收益,白交每轮成本 - 冗余:L3已覆盖的规则 / L1其他行已含的片段 ## 压缩四原则 1. **命名自解释 > 加描述**:SOP名能说清的,L1不加注释;改名的ROI常高于改L1 - 推论:极低ROI且文件名自解释的条目可不单独列入L1,但仍需被原则2的集合包含住,靠集合触发词+ls兜底 2. **存在性集合最小描述**:多个相近条目若可被同一上位场景覆盖,用集合名表达这类能力的存在,不必平铺子项。如`qq操作/飞书操作/企微操作`→`im操作:*_im_sop`;子项名自解释则只列名不翻译 3. **条目 = 场景↔方案存在性**:如`视频理解:yt-dlp取字幕`、`fofa(资产测绘)`——场景名是触发词,方案名编码存在性;括号内**只放反直觉触发词**,非反直觉的(纯翻译/内容描述/实现细节)全是浪费 - **触发词判定**:假设用户说出这个词,你能否想到去查对应SOP?能→直觉(不需要);不能→反直觉(必须留)。如`game_download(百度网盘)`:用户说"百度网盘下载",没这个词你不会想到game_download→必须留 4. **分层归位**:L1内部调整位置——带行为规则或高频高ROI的条目放上方场景行,纯存在性指针归L1下方平铺列表。**归位≠移出L1,存在性不可丢** ## 整理流程 1. 逐行读L1,按`|`拆片段,先分类:存在性指针 / RULES / 翻译 / 内容描述 / 实现细节 / 冗余 2. 先清RULES:逐条问“这是全局高ROI,还是特定场景低危险规则?” - 全局高ROI → 留 - 特定场景 / 低危险 → 降级到L3或删除 3. 再清存在性指针:检查是否在表达**场景↔方案存在性**;场景触发词只在**反直觉**时才加,翻译/内容描述/实现细节删掉 4. 审计幽灵条目:L1指向的L3文件是否真实存在?不存在则按ROI决定删除或补建文件 5. 禁值存储:L1括号内禁放参数值(IP/端口/凭证等),这些属于L2,L1只编码存在性 6. 检查L3文件名是否自解释;能靠改名解决的,不靠L1加描述;最后验证总行数 ≤ 30 **红线**:记忆修改是持久性伤害,错误每轮复利。L1只能patch词级别修改,禁overwrite 产生误导应及时修正L1或记忆更名 ## L2 瘦身流程(冗余长段→L3,事实无损) 适用:L2 某段冗长(服务器/工具详情),需压缩但禁丢事实。 1. **先迁再压**:把该段完整事实迁到/合并进 L3 专属 SOP(已有同主题 SOP 就并入,勿重复建,先 `ls ../memory/` 查),L2 只留 6-9 行"连接方式+服务端点+高频坑+指针(见 xxx_sop.md)"。 2. 迁移后同步 L1 加新 SOP 名(自解释即可,勿加冗余括号)。 3. 每节独立闭环:迁移→压 L2→同步 L1,再进下一节,限制失败半径。 4. 验证:核对 6 项(每个新 SOP 文件存在 & 已入 L1)、L2 无遗留脏字符、总行数下降。 ## 坑:L2 历史脏字符导致 file_patch 匹配失败 - 现象:`file_patch` 连续报"未找到匹配旧文本块",但肉眼看 old_content 与文件一致。 - 根因:老记录行首可能混入真实的多余 `|`(或全角/箭头字节差异),复制时看不出。 - 排查:`for i,l in enumerate(lines): print(i+1, repr(l[:20]))` 用 repr 看真实字节。 - 解法:**改用 Python 按行号切片替换**:`lines=open(p,encoding='utf-8').read().split('\n'); assert lines[a].startswith(...); newlines=lines[:a]+repl+lines[b:]; open(p,'w',encoding='utf-8').write('\n'.join(newlines))`。前后加 `assert startswith` 双锚点防错位,改完 repr 复核。此法顺带清脏字符。