1. 从过期 CLAUDE.md 说起:TaoToken 把写入和校验拆成两条链路
Claude Code 里最常见的坑,是CLAUDE.md、memory.jsonl被直接追加,过期结论下一次会话继续生效。TaoToken 在这里不是让模型“更聪明”,而是把写入与校验拆成两条可计费链路:去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_intro 获取 Key,Base URL 用 https://taotoken.net/api 。Microsoft 的 environment-probing curation 正是这个思路:长期运行智能体写持久记忆前,由一个只读访问环境的独立记忆智能体做正确性、可复用性校验,论文给出的 CLBench 对照是 39% 到 73%。下面从可复制配置开始。
很多人做长期记忆时会踩同一个循环:让主智能体总结刚做完的事,把总结写进memory.jsonl,下一次会话再读回来。这个流程看起来省钱,实际很贵。一旦写进去的是“临时结论”“过期接口”“局部环境才成立的路径”,后面每次推理都会带着错误前提继续跑,重试、修错、再总结,Token 消耗反而更高。更麻烦的是,这类错误很难定位,因为它不在当前 prompt 里,而在几天前写下的记忆里。
environment-probing curation 的关键不是“再问模型一遍”,而是把校验动作独立出来。写入智能体可以继续负责探索、执行、总结;校验智能体只读访问环境,检查候选记忆能不能被当前项目、当前依赖、当前文件状态证明。证明不了就拒绝写入,证据不足就要求补充,能证明才进入持久记忆。TaoToken 给 Key、统一 Base URL 之后,你可以让主智能体和校验智能体走不同的模型、不同的预算、不同的日志,把“记忆质量”变成可观测指标。
这篇内容给出一条能落地的路径:先拿 TaoToken Key,再配 Claude Code 的settings.json和ANTHROPIC_*,然后配 Codex 的config.toml,接着用 CC Switch 三件套管理供应商切换,最后给出一个本地可执行的只读环境探测脚本,以及 CLBench 风格的本地对照记录方法。所有 SQL、命令、测试都由你在本地执行,校验智能体不直连生产库,也不允许写环境。
2. 先在 TaoToken 拿 Key:Base URL、Key 占位符与预算隔离
不管用 Claude Code、Codex,还是自己写校验脚本,第一步都是拿一个可用的 Key。打开 TaoToken 官网:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_key ,按控制台提示创建 API Key。本文里所有 Key 都写成占位符YOUR_API_KEY,不要把它提交到 Git,也不要写进项目级settings.json后直接推仓库。
统一记住两个值:
Base URL: https://taotoken.net/api API Key : YOUR_API_KEYBase URL 在工具配置里不加 UTM 参数,保持干净。官网、控制台、模型列表、文档入口才带 UTM,方便区分来源。Claude Code 使用ANTHROPIC_*环境变量;Codex 的config.toml使用独立的环境变量名,例如TAOTOKEN_API_KEY。不要把ANTHROPIC_*套到 Codex 配置里,否则你会看到模型供应商不匹配、鉴权失败或请求路径错误。
建议至少准备两类 Key 或两类预算视图:
- 写入智能体用的 Key:负责探索、执行、生成候选记忆。
- 校验智能体用的 Key:只读环境、判定候选记忆、输出结构化裁决。
如果团队规模小,也可以共用一个 Key,但在日志和脚本里按agent_role=writer、agent_role=prober分开打标签。这样当 CLBench 通过率变化时,你能知道是写入侧变差,还是校验侧太松。校验智能体本身会消耗 Token,但它消耗的是“小提示词 + 局部证据”,换来的是持久记忆里少一条错误事实。长期看,这比让主智能体带着错误记忆反复试错便宜。
如果你是第一次接入,可以先在模型对话页确认当前可用的模型 ID:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_chat 。模型 ID 在不同时间的可用列表可能不同,配置里不要硬编码一个已经下线的名字。本文示例使用claude-sonnet-4-5、gpt-5-codex这类占位模型名,实际以你控制台和模型页展示为准。
3. environment-probing curation 的最小闭环:候选记忆、只读探针、裁决、提交
把论文里的流程翻译成工程语言,可以拆成四步。
第一步,写入智能体产生候选记忆。它不是直接写memory.jsonl,而是写memory/candidates/*.json。候选记忆至少包含:
{ "id": "cand_20260101_001", "source_agent": "writer", "created_at": "2026-01-01T10:00:00Z", "claim": "本项目所有外部 API 调用必须走 https://taotoken.net/api 作为 Base URL。", "scope": "project", "evidence_hint": ["README.md", "src/config.ts", ".env.example"], "tags": ["api", "base-url", "taotoken"] }第二步,独立记忆校验智能体只读访问环境。它可以读文件、看目录、查 Git 状态、运行限定在只读范围内的命令。它不能写文件、不能改配置、不能执行迁移、不能连生产库。对于数据库相关记忆,只允许读者在本地只读副本上执行 SQL,或者读取已经导出的 schema 文件;校验智能体本身不直连 Oracle、MySQL、PostgreSQL 等生产库。
第三步,校验智能体输出结构化裁决,而不是自然语言“看起来可以”。一个可用的裁决 schema 如下:
{ "verdict": "accept", "confidence": 0.86, "canonical_claim": "项目级 Base URL 统一为 https://taotoken.net/api", "evidence": [ "README.md:12", ".env.example:3", "src/config.ts:8" ], "reuse_scope": "project", "expires_at": null, "reject_reason": null, "dedupe_key": "project:api:base_url" }verdict只允许三类:accept、reject、needs_more_evidence。accept才进入持久记忆;reject进入拒绝日志,供人工抽查;needs_more_evidence不写入,返回给写入智能体补充证据。
第四步,提交器只做机械动作:读取accept裁决,按dedupe_key去重,然后追加到memory/verified.jsonl。提交器不调用模型,避免“最后一步又被模型改口”。这个闭环的价值在于:模型负责判断,脚本负责执行,权限边界清楚。
在 Claude Code 里,你可以把校验智能体定义成只读子智能体。在 Codex 里,可以用config.toml切供应商,再用外部脚本承担只读探测。无论哪种方式,核心都是同一个:写入前校验,校验者独立,环境访问只读,裁决结构化。
4. Claude Code 配置:settings.json 与 memory-prober 子智能体
Claude Code 推荐用settings.json管理ANTHROPIC_*。项目级可以放在.claude/settings.json,用户级可以放在~/.claude/settings.json。下面示例把 Base URL 指向 TaoToken,Key 用占位符:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "claude-sonnet-4-5", "ANTHROPIC_SMALL_FAST_MODEL": "claude-3-5-haiku-latest" }, "permissions": { "allow": [ "Read", "Grep", "Glob", "Bash(pwd)", "Bash(ls:*)", "Bash(git status:*)", "Bash(git log:*)", "Bash(cat:*)", "Bash(rg:*)" ], "deny": [ "Write", "Edit", "Bash(rm:*)", "Bash(mv:*)", "Bash(git push:*)", "Bash(npm install:*)", "Bash(pnpm install:*)", "Bash(docker:*)", "Bash(kubectl:*)", "Bash(psql:*)", "Bash(mysql:*)", "Bash(mongo:*)" ] } }这里的权限列表是示例,不是绝对安全策略。关键点是校验智能体不应拥有Write、Edit,也不应拥有会修改环境、部署、迁移数据库的 Bash 权限。如果你的 Claude Code 版本使用不同的权限字段,按官方文档调整,但保持“只读探针”原则。
接着定义memory-prober子智能体。可以放在.claude/agents/memory-prober.md,内容类似:
--- name: memory-prober description: 只读环境探测,在写入持久记忆前验证候选记忆 tools: Read, Grep, Glob, Bash --- 你是独立记忆校验智能体。你的任务不是继续探索项目,而是验证候选记忆是否被当前环境证据支持。 规则: 1. 只能读取文件、目录、Git 状态和日志片段。 2. 不得写入、编辑、删除、移动任何文件。 3. 不得执行安装、部署、迁移、数据库写入。 4. 不得连接生产数据库;数据库 schema 只能读取本地导出文件。 5. 必须输出 JSON,字段包括 verdict、confidence、canonical_claim、evidence、reuse_scope、expires_at、reject_reason、dedupe_key。 6. 证据不足时输出 needs_more_evidence,不要猜测。 7. 如果候选记忆是临时状态、个人偏好、一次性调试结论,倾向 reject 或缩小 reuse_scope。然后让写入智能体只生成候选记忆,不直接写verified.jsonl。你可以在主提示词里加一条:
完成探索后,把可复用经验写入 memory/candidates/,不要直接追加 memory/verified.jsonl。等待 memory-prober 校验通过后,再由提交脚本写入。Claude Code 的ANTHROPIC_AUTH_TOKEN用YOUR_API_KEY,Base URL 统一为https://taotoken.net/api。如果遇到 401,先检查 Key 是否复制完整;如果遇到 404,先检查 Base URL 是否被误写成带/v1或带 UTM 的地址。工具配置不需要 UTM,保持https://taotoken.net/api。
5. Codex 配置:config.toml 不要混用 ANTHROPIC_*
Codex 的配置入口是~/.codex/config.toml,和 Claude Code 的settings.json不是一套。不要把ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN写进 Codex 的 provider 字段。Codex 侧使用独立的环境变量,例如TAOTOKEN_API_KEY。
一个示例配置如下:
model = "gpt-5-codex" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"终端里设置 Key:
export TAOTOKEN_API_KEY="YOUR_API_KEY"然后启动 Codex:
codex --config ~/.codex/config.toml如果你的 Codex 版本要求wire_api = "responses"或不同的 provider 字段,以本地版本和 TaoToken 文档为准。原则是:Base URL 用https://taotoken.net/api,Key 用独立变量,不要把 Claude Code 的ANTHROPIC_*直接搬过来。很多“模型不可用”的报错不是 Key 错,而是供应商协议字段混用。
在长期记忆场景里,Codex 可以负责执行和修改代码,但记忆校验最好由外部脚本调用独立模型完成。你可以让 Codex 生成memory/candidates/*.json,然后运行第 7 节的memory_probe_gate.py。校验通过后,memory/verified.jsonl才更新。这样 Codex 本身不需要获得写记忆文件的最终权限,减少误写。
如果你同时使用 Claude Code 和 Codex,可以准备两个终端 profile:一个加载ANTHROPIC_*,一个加载TAOTOKEN_API_KEY。不要在同一套 Codex provider 里读取ANTHROPIC_AUTH_TOKEN。配置越清楚,后面排查越省时间。
6. CC Switch 三件套:Claude Code、Codex、终端环境变量
如果你用 CC Switch 管理多个供应商,可以把“三件套”理解成三份配置源:
- Claude Code 配置:
~/.claude/settings.json或项目.claude/settings.json,使用ANTHROPIC_*。 - Codex 配置:
~/.codex/config.toml,使用TAOTOKEN_API_KEY和独立 provider。 - 终端环境变量:
~/.zshrc、~/.bashrc或项目.env,用于脚本、CI、临时命令。
CC Switch 只负责切换当前生效的配置,不改变 TaoToken 的 Base URL。无论切到哪个 profile,Base URL 都是:
https://taotoken.net/apiClaude Code 的 CC Switch profile 可以写成:
{ "name": "TaoToken-ClaudeCode", "target": "claude-code", "settings": { "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "claude-sonnet-4-5", "ANTHROPIC_SMALL_FAST_MODEL": "claude-3-5-haiku-latest" } } }Codex 的 CC Switch profile 可以写成:
{ "name": "TaoToken-Codex", "target": "codex", "env": { "TAOTOKEN_API_KEY": "YOUR_API_KEY" }, "config": { "model": "gpt-5-codex", "model_provider": "taotoken", "model_providers": { "taotoken": { "name": "TaoToken", "base_url": "https://taotoken.net/api", "env_key": "TAOTOKEN_API_KEY", "wire_api": "chat" } } } }终端环境变量可以单独维护一个片段:
# ~/.zshrc 或项目 .env export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export TAOTOKEN_API_KEY="YOUR_API_KEY"注意,终端里同时存在ANTHROPIC_*和TAOTOKEN_API_KEY没问题,只要 Codex 的config.toml明确读取TAOTOKEN_API_KEY。真正危险的是把两套协议变量混在同一个工具里。CC Switch 三件套分开维护后,你可以快速在 Claude Code、Codex、脚本之间切换,同时保留同一套记忆校验流程。
7. 可运行脚本:用 TaoToken 做只读环境探测与记忆闸门
下面给一个最小可运行脚本memory_probe_gate.py。它做四件事:读取候选记忆,执行白名单只读命令收集证据,调用 TaoToken 上的校验模型输出 JSON 裁决,按裁决结果写入或拒绝。所有命令都在本地执行,不连接生产库。
先安装依赖:
python -m venv .venv source .venv/bin/activate pip install anthropic脚本示例:
# memory_probe_gate.py import json import os import subprocess import sys from datetime import datetime, timezone from pathlib import Path from anthropic import Anthropic BASE_URL = os.getenv("ANTHROPIC_BASE_URL", "https://taotoken.net/api") API_KEY = os.getenv("ANTHROPIC_AUTH_TOKEN", "YOUR_API_KEY") MODEL = os.getenv("MEMORY_PROBER_MODEL", "claude-sonnet-4-5") CANDIDATE_DIR = Path("memory/candidates") VERIFIED_FILE = Path("memory/verified.jsonl") REJECTED_FILE = Path("memory/rejected.jsonl") ALLOWED_COMMANDS = [ ["pwd"], ["ls", "-la"], ["git", "status", "--short"], ["git", "log", "-1", "--oneline"], ["git", "diff", "--stat"], ["cat", "README.md"], ["cat", ".env.example"], ["cat", "package.json"], ["rg", "-n", "taotoken|base_url|BASE_URL", "."], ] client = Anthropic(api_key=API_KEY, base_url=BASE_URL) def run_readonly(cmd: list[str]) -> str: try: completed = subprocess.run( cmd, capture_output=True, text=True, timeout=15, check=False, ) output = (completed.stdout or "") + (completed.stderr or "") return output[:4000] except Exception as exc: return f"[command-error] {' '.join(cmd)}: {exc}" def collect_evidence() -> list[dict]: evidence = [] for cmd in ALLOWED_COMMANDS: output = run_readonly(cmd) evidence.append({ "command": " ".join(cmd), "output": output, }) return evidence def load_candidates() -> list[dict]: if not CANDIDATE_DIR.exists(): return [] candidates = [] for path in sorted(CANDIDATE_DIR.glob("*.json")): try: candidates.append(json.loads(path.read_text(encoding="utf-8"))) except Exception as exc: print(f"skip {path}: {exc}", file=sys.stderr) return candidates def probe(candidate: dict, evidence: list[dict]) -> dict: prompt = f""" 你是独立记忆校验智能体。请只读判断下面候选记忆是否被当前本地环境证据支持。 候选记忆: {json.dumps(candidate, ensure_ascii=False, indent=2)} 环境证据: {json.dumps(evidence, ensure_ascii=False, indent=2)[:12000]} 要求: 1. 只能依据证据判断,不得猜测。 2. 输出严格 JSON,不要 Markdown。 3. verdict 只能是 accept、reject、needs_more_evidence。 4. 字段必须包含 verdict、confidence、canonical_claim、evidence、reuse_scope、expires_at、reject_reason、dedupe_key。 5. 如果记忆是临时状态、一次性调试结论、个人偏好,倾向 reject 或缩小 reuse_scope。 6. 不要建议连接生产数据库;数据库 schema 只能依赖本地导出文件。 """ message = client.messages.create( model=MODEL, max_tokens=1200, temperature=0, messages=[{"role": "user", "content": prompt}], ) text = "".join( block.text for block in message.content if getattr(block, "type", "") == "text" ) return json.loads(text) def append_jsonl(path: Path, record: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) with path.open("a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n") def main() -> int: evidence = collect_evidence() candidates = load_candidates() if not candidates: print("no candidates found in memory/candidates") return 0 accepted = 0 rejected = 0 for candidate in candidates: result = probe(candidate, evidence) record = { "candidate": candidate, "verdict": result, "probed_at": datetime.now(timezone.utc).isoformat(), } if result.get("verdict") == "accept": append_jsonl(VERIFIED_FILE, record) accepted += 1 else: append_jsonl(REJECTED_FILE, record) rejected += 1 print(f"{candidate.get('id')} -> {result.get('verdict')}") print(f"accepted={accepted}, rejected_or_pending={rejected}") return 0 if __name__ == "__main__": raise SystemExit(main())运行:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export MEMORY_PROBER_MODEL="claude-sonnet-4-5" python memory_probe_gate.py这个脚本不是完整生产系统,但它体现了核心边界:只读命令白名单、结构化裁决、接受后才写verified.jsonl、拒绝也留痕。你可以把ALLOWED_COMMANDS按项目替换成更精确的命令,例如只允许读取pyproject.toml、go.mod、Cargo.toml、docker-compose.yml的片段。任何数据库查询都应该由你在本地只读副本执行,再把结果作为证据文件传入,而不是让校验智能体直连生产库。
8. CLBench 对照与本地复刻:39%→73% 不是玄学,是流程差异
论文给出的数字是 CLBench 通过率从 39% 升到 73%。这个数字不应该被理解成“换个 Key 就提升”,而是“在写入持久记忆前增加独立只读校验,减少错误记忆注入”。本地复刻时,不要只记录最终通过率,还要记录记忆接受率、拒绝率、需要补充证据比例、平均校验 Token、后续任务重试次数。
可以用一个 CLBench 风格的本地评估表:
| 组别 | 写入策略 | 记忆来源 | 校验方式 | 任务通过率 | 错误记忆命中 |
|---|---|---|---|---|---|
| 基线组 | 直接追加 | 主智能体总结 | 无 | 记录本地结果 | 记录本地结果 |
| 探针组 | 候选后校验 | 主智能体总结 | 只读环境探测 | 记录本地结果 | 记录本地结果 |
| 论文对照 | 环境探测式策展 | 长期运行智能体 | 独立只读记忆智能体 | 39% 到 73% | 论文口径 |
本地复刻步骤可以这样设计:
- 准备一组长期任务,例如“修复接口版本漂移”“补齐配置文档”“迁移旧环境变量”。每个任务都要求智能体写一条可复用记忆。
- 基线组让主智能体直接写
memory/verified.jsonl。 - 探针组只让主智能体写
memory/candidates/,由memory_probe_gate.py调用 TaoToken 校验后,再写memory/verified.jsonl。 - 在后续会话中读取
verified.jsonl,运行同一套任务检查。通过率、重试次数、人工修正次数都记录到 CSV。 - 每周抽查
memory/rejected.jsonl,看拒绝理由是否合理。如果拒绝太多,说明候选记忆质量差;如果接受太多,说明校验太松。
评估命令可以写成:
python clbench_like_eval.py \ --memory memory/verified.jsonl \ --tasks tasks/clbench_mini.jsonl \ --out runs/probe_$(date +%s).csvCSV 字段建议:
task_id,baseline_pass,probe_pass,accepted_count,rejected_count,token_in,token_out,retry_count,human_fix如果你要把 TaoToken 的用量拆开,可以在脚本里分别记录写入调用和校验调用的model、input_tokens、output_tokens。TaoToken 官网控制台入口在这里:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_clbench 。建议把校验模型固定为便宜、稳定、温度 0 的模型,把写入模型留给主力模型。校验模型不需要创造力,它需要的是严格按证据输出 JSON。
不要期望一次就复刻出 39% 到 73% 的绝对数字。你的任务集、项目状态、模型版本都不同。真正可复刻的是流程差异:直接写入 vs 写入前独立只读校验。只要你能记录“错误记忆进入持久层”的次数,就能看到差异。
9. 常见排障:403、404、模型名不对、记忆重复
第一类问题:401 或 403。通常是 Key 复制不完整、Key 被禁用、或者把 Key 写进了错误的环境变量。Claude Code 检查ANTHROPIC_AUTH_TOKEN,Codex 检查TAOTOKEN_API_KEY,Python 脚本检查ANTHROPIC_AUTH_TOKEN。不要把 Codex 的 Key 环境变量写成ANTHROPIC_AUTH_TOKEN,也不要把 Claude Code 的ANTHROPIC_*塞进 Codex 的model_providers。
第二类问题:404 或路径错误。工具配置的 Base URL 统一用https://taotoken.net/api,不要带 UTM,不要额外拼/v1,除非你使用的 SDK 或工具文档明确要求。Claude Code、Codex、Python SDK 对路径的处理不同,先把 Base URL 保持干净,再按工具文档调整。
第三类问题:模型名不对。模型列表会变化,配置里写死的模型 ID 可能已经不可用。去模型对话页确认当前模型 ID:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_chat 。校验脚本里用MEMORY_PROBER_MODEL环境变量覆盖,不要在代码里四处硬编码。
第四类问题:记忆重复。两条候选记忆语义相同但表述不同,校验智能体可能都接受。解决方法是让裁决输出dedupe_key,提交器在写入前检查verified.jsonl中是否已有相同 key。如果有,只更新证据和更新时间,不追加新行。
第五类问题:校验消耗 Token 太多。常见原因是把完整日志、完整仓库都塞进 prompt。正确做法是只传候选记忆、少量文件片段、最近一次 Git 状态和精确搜索结果。校验智能体只读,不代表它要读全量。你可以把证据收集拆成两步:先用规则脚本抽取相关文件片段,再交给模型裁决。
第六类问题:只读环境被破坏。检查权限配置,确保校验智能体没有Write、Edit,Bash 白名单里没有rm、mv、sed -i、npm install、docker、kubectl、数据库客户端写入命令。数据库相关证据必须由读者在本地只读副本执行 SQL 后导出,校验智能体只读该导出文件。
10. 文末 CTA:模型对话、Coding Plan、创建 Key、Claude Code 文档
如果你准备把这套“写入前独立校验”的流程跑起来,按下面顺序操作最省时间。
先到模型对话页确认可用模型和请求格式:
https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_chat需要长期高频调用时,查看 Coding Plan:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_plan创建或管理 API Key,把
YOUR_API_KEY替换成真实值:
https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_keysClaude Code 的 Anthropic 兼容配置以这份文档为准:
https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=memory_probe_doc
最后再强调一次配置边界:Claude Code 用settings.json和ANTHROPIC_*,Codex 用config.toml和独立环境变量,CC Switch 三件套分开维护;Base URL 统一为https://taotoken.net/api;Key 占位符统一为YOUR_API_KEY。把写入智能体和校验智能体拆开,把只读环境探测放在持久记忆提交之前,再用本地 CLBench 风格记录表观察通过率变化。这样你不仅是在用 TaoToken 给 Key,更是在给长期记忆加一道可审计的闸门。