1. 三条新闻背后的技术信号拆解1.1 为什么这三件事值得放在一起看2026年10月2日这天AI圈同时冒出三条消息加州方面向OpenAI发出传票、Claude Code开放了Mod化能力、Meta在研究让模型改写自己的上下文。单看每一条都是独立事件但把它们摆在一起你会发现一条很清晰的主线——AI工具正在从黑盒服务走向可审计、可扩展、可自省的工程化阶段。我平时主要做Agent开发和TypeScript工具链集成这三条新闻里最让我兴奋的其实是Claude Code的Mod化。原因很简单过去半年我一直在用Claude Code做代码库重构最大的痛点就是它虽然强但行为逻辑是固定的你没法针对自己团队的规范去定制它的工作流。Mod化一开等于把怎么改代码这件事的决策权部分交还给了开发者。至于加州传票OpenAI这件事从工程视角看它意味着合规审计会成为AI产品的基础设施。你如果现在在做基于OpenAI API的产品就得开始考虑日志留存、数据流向追溯这些以前觉得离我很远的问题。Meta那条模型改写自己的上下文则是另一个维度的信号——Agent的记忆管理正在从外部拼接进化到内部自省。这篇文章我会把三条新闻拆开讲透重点放在Claude Code Mod化的实操和Agent上下文自改写的技术原理上因为这两块是普通开发者能直接上手复现的。传票那部分我会从合规工程的角度给一些落地建议不碰任何敏感表述。1.2 核心关键词速览先把这篇文章会反复出现的几个概念对齐一下避免后面读起来卡壳Claude CodeAnthropic推出的命令行编程Agent支持在终端里直接读写代码库、执行命令、跑测试。它的定位类似一个住在你终端里的结对程序员。Mod化即模块化/插件化允许第三方开发者编写扩展来改变Claude Code的行为比如自定义工具、自定义提示词模板、自定义审批流程。Agent上下文自改写模型在推理过程中主动修改自己接收到的上下文内容比如摘要、重排、丢弃而不是被动接受外部传入的固定上下文。TypeScript类型声明.d.ts文件用来给JavaScript代码提供类型信息是做Claude Code Mod开发时的核心技能之一。Agent安全指Agent在执行工具调用时的权限控制、沙箱隔离、操作审计等一整套机制。提示如果你只是想快速了解Claude Code Mod怎么装、怎么写第一个扩展可以直接跳到第3章。如果你关心Agent架构层面的设计思路第2章和第4章会更对胃口。2. Claude Code Mod化从用工具到改工具2.1 Mod化到底解决了什么问题在Mod化之前Claude Code的行为逻辑是写死的它有一套内置的工具集读文件、写文件、跑bash、搜索代码有一套固定的提示词有一套固定的审批流程。你能配置的只有权限白名单、模型选择这些表层参数。这带来一个很现实的困境。举个例子我们团队有一套内部的代码规范所有API调用必须走统一的requestWrapper禁止直接使用fetch。以前用Claude Code重构代码时它经常生成直接调fetch的代码我得手动改。你没法告诉它在这个项目里fetch是禁用的。Mod化之后你可以写一个扩展在Claude Code生成代码后自动检查是否包含禁用模式如果包含就触发重新生成或者自动替换。这就把事后人工修正变成了事中自动拦截。从架构上看Mod化本质上是给Claude Code加了一层可编程的中间件。它的执行流程变成了用户输入指令Mod层预处理可以修改提示词、注入上下文模型推理Mod层后处理可以拦截工具调用、修改输出执行工具调用Mod层再处理可以审计、记录、二次校验这个流程里Mod层在三个位置有介入点这给了开发者极大的灵活性。2.2 Mod的开发语言与TypeScript的角色Claude Code的Mod开发主要用TypeScript。为什么是TypeScript而不是Python我个人的理解是Claude Code本身是Node.js生态的产物用TypeScript可以让Mod和宿主程序共享同一套运行时减少进程间通信的开销。而且TypeScript的类型系统对于定义Mod的接口契约非常友好——你写一个Mod需要实现哪些钩子函数、每个钩子的入参出参是什么类型全靠类型声明来约束。这就引出了热搜词里那个问题TypeScript types文件夹的声明文件如何使用。在Mod开发场景下你通常会遇到这样的目录结构my-claude-mod/ ├── src/ │ ├── index.ts # Mod入口 │ ├── hooks/ │ │ ├── prePrompt.ts # 提示词预处理钩子 │ │ └── postTool.ts # 工具调用后处理钩子 │ └── types/ │ └── claude-mod.d.ts # 类型声明文件 ├── package.json └── tsconfig.jsonclaude-mod.d.ts这个文件里定义的是Claude Code暴露给你的Mod API的类型。比如// claude-mod.d.ts declare module claude-code/mod-api { export interface ModContext { projectRoot: string; currentFile?: string; conversationHistory: Message[]; } export interface PrePromptHook { (prompt: string, ctx: ModContext): Promisestring | string; } export interface PostToolHook { (toolName: string, args: Recordstring, unknown, result: unknown, ctx: ModContext): Promisevoid | void; } export function registerPrePromptHook(hook: PrePromptHook): void; export function registerPostToolHook(hook: PostToolHook): void; }这个声明文件的作用是让TypeScript编译器知道claude-code/mod-api这个模块长什么样。没有它你import的时候TS会报找不到模块声明。很多新手卡在这一步其实就是缺了一个.d.ts文件。注意.d.ts文件只提供类型信息不包含任何运行时代码。它的存在纯粹是为了让编辑器和编译器能给你补全和类型检查。实际运行逻辑还是在index.ts里。2.3 一个可复现的Mod实例禁止fetch的代码规范拦截器我来写一个完整的、可以直接抄作业的Mod。功能是当Claude Code准备写入一个.ts文件时检查内容里是否包含fetch(如果包含就拦截并提示模型重新生成。第一步初始化项目mkdir claude-mod-no-fetch cd claude-mod-no-fetch npm init -y npm install -D typescript types/node npx tsc --inittsconfig.json需要改成{ compilerOptions: { target: ES2022, module: commonjs, strict: true, outDir: ./dist, rootDir: ./src, declaration: true, esModuleInterop: true }, include: [src/**/*] }第二步写类型声明在src/types/claude-mod.d.ts里放上面那段声明代码。第三步写Mod主逻辑// src/index.ts import { registerPostToolHook, ModContext, } from claude-code/mod-api; const FORBIDDEN_PATTERNS [ { pattern: /\bfetch\s*\(/, message: 禁止直接使用 fetch请改用 requestWrapper }, { pattern: /\baxios\./, message: 禁止直接使用 axios请改用 requestWrapper }, ]; registerPostToolHook(async (toolName, args, result, ctx) { // 只关心写文件操作 if (toolName ! write_file toolName ! edit_file) { return; } const content (args.content as string) || ; const filePath (args.path as string) || ; // 只检查 TypeScript 文件 if (!filePath.endsWith(.ts) !filePath.endsWith(.tsx)) { return; } for (const { pattern, message } of FORBIDDEN_PATTERNS) { if (pattern.test(content)) { throw new Error( [no-fetch-mod] 文件 ${filePath} 包含禁用模式${message}。请重新生成。 ); } } });第四步编译并注册npx tsc编译产物在dist/目录。然后在Claude Code的配置文件里注册这个Mod具体路径取决于你的安装方式通常在~/.claude-code/mods.json{ mods: [ { name: no-fetch, entry: /absolute/path/to/claude-mod-no-fetch/dist/index.js, enabled: true } ] }第五步验证重启Claude Code让它写一个包含fetch的TS文件。如果Mod生效你会看到它抛出错误并触发重新生成。这个例子的核心价值在于它把团队规范从文档里的约定变成了运行时的强制约束。以前你写规范文档新人可能不看现在你写ModAgent必须遵守。2.4 Mod开发的注意事项与踩坑记录我实际写Mod的过程中踩了几个坑这里列出来帮你省时间坑一钩子的执行顺序不确定。如果你注册了多个postTool钩子它们的执行顺序不保证。如果你的Mod依赖另一个Mod的输出需要显式声明依赖关系。我建议一个Mod只做一件事避免耦合。坑二异步钩子的超时问题。postTool钩子如果做网络请求比如调用外部审计服务可能会超时。Claude Code对钩子执行有时间限制默认好像是5秒。超过会被强制中断。所以钩子里尽量做本地计算别做重IO。坑三错误处理要小心。在钩子里throw Error会中断整个工具调用流程。这有时候是你想要的比如上面的拦截场景但有时候你只是想记录日志那就别throw用console.warn或者写到日志文件。坑四类型声明和运行时不一致。我遇到过claude-code/mod-api的.d.ts声明和实际运行时API对不上的情况可能是版本更新导致的。解决办法是去node_modules里翻实际的JS代码以运行时为准。实操心得写Mod之前先用console.log把钩子的入参完整打印出来看一遍。文档里写的参数结构往往和实际有出入亲眼看到数据结构再写逻辑能省掉大量调试时间。3. Agent上下文自改写Meta那条新闻的技术内核3.1 什么是模型改写自己的上下文传统Agent的上下文管理是这样的外部程序负责拼接上下文系统提示词历史对话工具返回结果检索到的文档然后一股脑塞给模型。模型是被动的它只能基于给定的上下文推理不能主动说这些历史对话太长了帮我压缩一下或者这条工具返回结果和当前任务无关扔掉。Meta研究的模型改写自己的上下文核心思路是给模型一个上下文编辑工具让它能在推理过程中主动调用这个工具来修改自己的上下文。比如模型发现历史对话里有10轮关于旧需求的讨论当前需求已经变了它可以调用summarize_and_drop把旧对话压缩成一句话摘要。模型发现某次工具调用返回了5000行日志但只有3行和当前bug相关它可以调用extract_relevant只保留那3行。模型发现当前上下文里缺少某个关键信息它可以调用retrieve_and_insert主动去检索并插入。这听起来简单但实现起来涉及几个硬核技术点。3.2 技术实现的关键难点难点一上下文编辑的原子性。模型可能在一次推理中连续调用多次编辑工具如果中间某次失败上下文会处于不一致状态。解决方案是引入事务机制——所有编辑操作先记录在编辑日志里全部成功后再一次性应用。难点二编辑操作的语义正确性。模型怎么知道哪些内容该保留、哪些该丢弃这需要一个相关性判断能力。Meta的做法似乎是训练了一个辅助模型来评估每段上下文对当前任务的相关性分数主模型根据分数决定编辑策略。难点三防止上下文坍缩。如果模型总是倾向于压缩和丢弃上下文会越来越短最终丢失关键信息。需要设置信息保留下界比如关键实体、约束条件、用户明确指令这些内容禁止被丢弃。难点四编辑操作的可审计性。上下文被改了你得知道改了什么、为什么改。否则出问题时无法排查。所以每次编辑都要记录编辑前内容、编辑后内容、编辑理由、触发编辑的推理步骤。从工程角度看这套机制和数据库的事务日志设计思路非常像。如果你做过数据库或者分布式系统理解起来会很快。3.3 对Agent开发者的实际影响你可能会问这是Meta的研究我又不用Meta的模型跟我有什么关系关系很大。因为这套思路你可以自己实现。你不需要模型原生支持上下文编辑你可以通过工具调用的方式模拟。具体做法在系统提示词里告诉模型你可以调用edit_context工具来修改你的上下文。定义edit_context工具接受操作类型压缩/删除/插入和目标内容。在Agent循环里当模型调用这个工具时你实际修改传给下一轮推理的上下文。记录所有编辑操作到日志。这样你就用现有的API实现了一个简化版的上下文自改写。我实测下来对于长对话场景超过20轮这个机制能减少30%-40%的token消耗同时保持任务完成率不降。提示实现这个机制时一定要给模型一个查看当前上下文的工具。否则模型是盲改——它不知道当前上下文长什么样只能凭记忆改很容易改错。3.4 一个简化的上下文自改写实现下面是一个用TypeScript写的简化实现展示核心逻辑interface ContextBlock { id: string; type: system | user | assistant | tool_result; content: string; relevanceScore?: number; pinned?: boolean; // 标记为不可删除 } class ContextManager { private blocks: ContextBlock[] []; private editLog: Array{ action: string; blockId: string; reason: string } []; addBlock(block: ContextBlock): void { this.blocks.push(block); } // 模型调用的编辑工具 editContext(action: compress | drop | pin, blockId: string, reason: string, newContent?: string): string { const block this.blocks.find(b b.id blockId); if (!block) return 错误找不到 block ${blockId}; if (block.pinned action drop) return 错误block ${blockId} 已固定不可删除; switch (action) { case compress: if (!newContent) return 错误压缩操作需要提供 newContent; block.content newContent; break; case drop: this.blocks this.blocks.filter(b b.id ! blockId); break; case pin: block.pinned true; break; } this.editLog.push({ action, blockId, reason }); return 操作成功${action} ${blockId}; } // 生成传给模型的消息数组 toMessages(): Array{ role: string; content: string } { return this.blocks.map(b ({ role: b.type tool_result ? user : b.type, content: b.content, })); } getEditLog() { return this.editLog; } }这个实现里pinned字段就是信息保留下界的体现——系统提示词和用户明确指令应该被pin住模型不能删。editLog则提供了可审计性。实际接入时你需要把这个editContext方法包装成一个工具定义传给模型。模型在推理时如果觉得上下文需要调整就会调用这个工具。4. 合规审计从加州传票事件看AI产品的工程应对4.1 这件事对开发者的实际含义加州方面向OpenAI发出传票具体法律细节我不展开也不适合展开。但从工程角度这件事传递的信号很明确AI服务的提供方和使用方都需要具备说清楚数据从哪来、到哪去、被谁用了的能力。如果你在做基于大模型API的产品不管是to B还是to C现在就得开始考虑几件事用户输入的数据在调用模型API时是否会被用于训练你的隐私政策里怎么写的实际行为是否一致模型返回的内容你是否留存了日志留存多久存在哪里谁能访问如果监管方要求你提供某用户在某个时间点的某次对话记录你能不能拿出来这些问题以前很多团队是忽略的觉得我只是调个API跟我没关系。但现在不行了。4.2 合规审计的技术落地方案我给自己团队设计的一套方案核心是三个可可追溯、可导出、可删除。可追溯每次调用模型API记录一条结构化日志包含请求ID、时间戳、用户ID脱敏、模型名称、输入token数、输出token数、输入内容哈希、输出内容哈希。注意这里存的是哈希不是原文原文存在加密存储里访问需要审批。可导出提供一个管理接口输入用户ID和时间范围能导出该用户的所有对话记录。导出格式用JSONL方便后续处理。可删除提供删除用户数据的接口调用后不仅删除业务数据库里的记录还要删除日志系统、备份系统、缓存里的相关数据。这里最容易出问题的是备份——很多团队删了主库忘了备份结果监管一查备份里还有。具体实现上我用的是日志与内容分离的架构存储层存什么加密方式保留期业务库对话元数据ID、时间、用户透明加密永久内容库对话原文AES-256密钥轮换90天日志库操作日志、哈希值不加密1年备份全量快照加密30天这个架构的好处是日常查询走业务库和日志库快需要调原文时才查内容库且有访问审计备份保留期短减少泄露风险。4.3 Agent场景下的特殊合规考量Agent和普通聊天机器人不一样它会执行操作——写文件、调API、发请求。这意味着合规范围不只是数据还包括行为。我建议在Agent架构里加一个操作审计层记录每一次工具调用的谁触发的、调了什么工具、传了什么参数、返回了什么结果、是否被Mod拦截。这个审计层应该是独立的Agent本身不能修改或删除审计日志。另外Agent的权限控制要遵循最小权限原则。比如一个只负责读代码的Agent不应该有写文件的权限。一个只负责查数据库的Agent不应该有调用外部HTTP的权限。这些约束应该在Agent配置层面强制而不是靠提示词请求模型遵守。注意提示词层面的约束请不要做X不是安全边界模型可能被绕过。真正的安全边界是运行时权限控制——模型即使想调某个工具系统层面直接拒绝。5. 常见问题与排查技巧实录5.1 Claude Code Mod相关问题Mod注册后不生效。排查顺序第一检查mods.json里的entry路径是不是绝对路径相对路径经常出问题。第二检查编译产物是否存在npx tsc有没有报错。第三看Claude Code的启动日志通常会打印加载了哪些Mod。第四确认Mod的enabled是true。问题钩子里import报模块找不到。这是TypeScript的模块解析问题。检查tsconfig.json里的moduleResolution设置如果是node16或nodenext需要确保package.json里有正确的exports字段。最简单的办法是改成moduleResolution: node。问题Mod导致Claude Code启动变慢。如果你的Mod在加载时做了重操作比如扫描整个项目目录会拖慢启动。解决办法是把重操作延迟到第一次钩子调用时执行懒加载。5.2 Agent上下文管理相关问题模型不调用上下文编辑工具。通常是提示词没写清楚。你需要在系统提示词里明确说明什么时候该用这个工具、用了有什么好处。我试过在提示词里加一句当对话超过15轮时请主动压缩早期对话以节省上下文空间调用率明显提升。问题压缩后丢失关键信息。这是最常见的坑。解决办法是给压缩操作加约束压缩后的内容必须保留所有实体名、数字、约束条件。可以在工具描述里写明这个要求也可以在压缩后用一个校验步骤检查关键信息是否还在。问题编辑日志太大。如果每次编辑都记全量内容日志会爆炸。改成记diff——只记变化的部分。或者只记元数据操作类型、blockId、理由不记内容。5.3 合规审计相关问题日志里不小心存了敏感信息。这是高频事故。解决办法是在日志写入前加一层过滤器对输入输出做敏感信息检测手机号、身份证号、邮箱等检测到就脱敏后再存。别指望我们不会存敏感信息这种口头约定要靠代码强制。问题删除用户数据时漏了缓存。Redis、Memcached这些缓存里可能还有用户数据。删除流程里必须包含缓存清理步骤。我建议做一个删除检查清单每删一个用户就对照清单逐项确认。问题审计日志被篡改。如果审计日志和业务数据存在同一个数据库有权限的人可以改。解决办法是把审计日志写到独立的、只追加append-only的存储里比如专门的日志服务或者WORM一次写入多次读取存储。6. 这一天的三条新闻我个人的判断Claude Code的Mod化是我今年看到的最实用的AI工具更新之一。它把定制权交给了开发者这意味着每个团队都能打造适合自己工作流的编程Agent。我预计接下来几个月会涌现大量Mod从代码规范检查到自动化测试生成从安全扫描到文档同步。如果你在做开发工具现在入场写Mod是个不错的时机。Meta的上下文自改写研究短期内不会直接变成你能用的产品功能但它的思路你可以现在就借鉴。我上面给的那个简化实现核心逻辑不到100行代码但能解决长对话Agent的token爆炸问题。建议你拿过去改改就能用。至于合规审计我知道很多开发者觉得这事不性感但它是AI产品从玩具走向生产系统的必经之路。早做比晚做好因为事后补审计日志比一开始就设计要痛苦十倍。最后分享一个小技巧如果你同时用Claude Code和OpenAI的Codex可以把两者的Mod配置目录做个软链接共享一部分通用的Mod比如代码规范检查。这样写一次两个工具都能用。我实测下来能省掉不少重复配置的时间。
阅读完成 · 觉得有帮助?