
1. 为什么要拆 Git DAG 共享记忆从 Agora 论文到可对齐的实验日志如果你正在复现 Agora 那套“Git 作为共享记忆”的集体 AutoResearch 实验最先卡住的往往不是 DAG 本身而是每个 commit 对应的 LLM 调用日志对不上。Agora 的设想很清晰多智能体把结果、洞察、验证都写进只追加的 Git 有向无环图每个节点都是一次可检出、可重跑的 commit。但真正跑起来时模型请求走外部 API日志散落在终端、CI、多个 agent 容器里commit 里只有一个结论没有 token 消耗、模型版本、请求 ID 和延迟。最后 DAG 拓扑是一套 ID实验日志是另一套 ID两边只能靠肉眼猜。建议先把模型出口固定到 TaoToken到 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag 拿 KeyBase URL 设成 https://taotoken.net/api 然后再谈 DAG 日志对照表、复现命令和 Token 统计。本文不重复论文综述而是从日志对齐的工程视角拆一遍怎样让 Git DAG 的每个 commit 都能关联到一次或多次模型调用怎样用 TaoToken 的 Key 和 Base URL 把调用记录落到本地 sidecar 日志最后生成一张能直接查 token、耗时、状态和父节点的对照表。典型报错通常出现在三个地方Claude Code 返回 401 或模型名不存在Codex 提示 provider not foundjq 汇总时 token 全是 0。根因往往不是模型能力而是 Base URL 末尾路径、环境变量名、配置文件位置、流式响应 usage 字段没开。下面按“接入准备 → Claude Code → Codex → CC Switch 三件套 → 对照表 → 复现命令 → 排障”展开所有命令都在读者本地执行不涉及任何生产库直连。2. TaoToken 接入准备Key、Base URL 与最小可观测性字段第一步不是改代码而是把模型访问入口统一。到 TaoToken 官网注册并创建 API Keyhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_key 。创建后拿到以 sk 开头的字符串本文统一用YOUR_API_KEY占位。Base URL 固定为https://taotoken.net/api注意这个 Base URL 不加 UTM 参数UTM 只用于官网入口追踪不要写进 SDK 或 config.toml 的 base_url 字段否则部分客户端会把查询串拼进请求路径导致 404。为了把 Agora 的 DAG 日志对齐建议每条模型调用至少记录以下字段。你可以先用 JSON Lines 落地一行一次调用字段含义来源run_id本次实验运行 ID脚本注入agent_id哪个智能体发起脚本注入commit_hash本次结果对应提交git rev-parse HEADparent_hash父提交用于还原 DAGgit rev-parse HEAD^model实际模型名请求体或响应prompt_tokens输入 token响应 usagecompletion_tokens输出 token响应 usagetotal_tokens总 token响应 usagelatency_ms端到端耗时本地计时statusHTTP 状态或业务状态响应log_path原始响应落盘路径脚本生成这组字段里commit_hash是连接 Git DAG 和实验日志的 join key。只要每次 commit 前把当前 HEAD 写进日志或者 commit message 里带上 run_id就能在事后做聚合。不要把 Key 写入 Git 仓库也不要把真实 Key 贴进 commit message。推荐用环境变量export TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api export AGORA_RUN_IDrun-local-$(date %Y%m%d%H%M%S) export AGORA_AGENT_IDagent-claude-code环境变量只存在于当前 shell 或 CI secret不进入版本历史。下面开始分工具配置。3. Claude Code 配置settings.json 与 ANTHROPIC_* 对齐 DAG 日志Claude Code 读取settings.json通常放在项目.claude/settings.json或用户级~/.claude/settings.json。要让 Claude Code 走 TaoToken需要配置ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN。注意Claude Code 用ANTHROPIC_*是正确的但不要把这一组变量套到 Codex 上Codex 不认这些名字。一个可复制的最小配置如下{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: your-claude-model, AGORA_RUN_ID: run-local-001, AGORA_AGENT_ID: agent-claude-code, AGORA_DAG_NODE: node-claude-001 } }这里ANTHROPIC_MODEL填你在 TaoToken 模型列表里实际可用的模型名不要凭记忆写。AGORA_*变量不是 Claude Code 官方变量只是通过env注入到子进程方便你的包装脚本读取。Claude Code 启动后子进程能拿到这些环境变量从而把 run_id、agent_id、DAG 节点写入 sidecar 日志。如果你希望日志更稳不要依赖 Claude Code 内部日志格式而是用一个 wrapper 脚本包一层。比如在项目里建scripts/run_claude_with_log.sh#!/usr/bin/env bash set -euo pipefail RUN_ID${AGORA_RUN_ID:-run-unknown} AGENT_ID${AGORA_AGENT_ID:-agent-unknown} BASE_URL${ANTHROPIC_BASE_URL:-https://taotoken.net/api} LOG_DIR.agora/logs mkdir -p $LOG_DIR COMMIT_HASH$(git rev-parse HEAD 2/dev/null || echo no-git) PARENT_HASH$(git rev-parse HEAD^ 2/dev/null || echo no-parent) START_MS$(date %s%3N) claude $ 21 | tee $LOG_DIR/${RUN_ID}-${AGENT_ID}.raw.log END_MS$(date %s%3N) LATENCY_MS$((END_MS - START_MS)) jq -n \ --arg run_id $RUN_ID \ --arg agent_id $AGENT_ID \ --arg commit_hash $COMMIT_HASH \ --arg parent_hash $PARENT_HASH \ --arg base_url $BASE_URL \ --arg latency_ms $LATENCY_MS \ {run_id:$run_id, agent_id:$agent_id, commit_hash:$commit_hash, parent_hash:$parent_hash, base_url:$base_url, latency_ms:($latency_ms|tonumber), status:unknown, usage:null} \ $LOG_DIR/${RUN_ID}.jsonl这个脚本只做两件事把终端输出原样保留同时追加一条结构化记录。模型返回的 usage 需要从原始响应里再解析或者改用非流式请求单独测一次。Claude Code 的交互式输出不一定带 usage所以更推荐在 CI 或批处理场景里用后面的 curl 方式做 token 统计。配置完成后运行一次claude如果出现 401优先检查ANTHROPIC_AUTH_TOKEN是否是YOUR_API_KEY以及ANTHROPIC_BASE_URL是否写成https://taotoken.net/api而不是带/v1或带 UTM 的网址。模型名 404 时先去 TaoToken 模型对话页确认可用模型https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_claude 。4. Codex 配置config.toml 指定 provider不要混用 ANTHROPIC_*Codex 不走settings.json也不使用ANTHROPIC_*。它通常读取~/.codex/config.toml或项目级配置。要接入 TaoToken应新增一个 model provider并让顶层model_provider指向它。一个可复制的示例model your-codex-model model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat其中wire_api根据你使用的模型和 Codex 版本选择常见是chat或responses。如果你不确定先用模型列表里标注兼容 chat completions 的模型。env_key表示 Codex 会从环境变量TAOTOKEN_API_KEY读取 Key所以运行前需要export TAOTOKEN_API_KEYYOUR_API_KEY export AGORA_RUN_IDrun-codex-$(date %Y%m%d%H%M%S) export AGORA_AGENT_IDagent-codex再运行codex --model your-codex-model 请执行一次最小验证并输出 OK如果 Codex 报provider not found检查三处顶层model_provider的值是否等于[model_providers.taotoken]里的taotokenbase_url是否写成了https://taotoken.net/apienv_key是否和实际 export 的变量名完全一致。不要因为 Claude Code 用了ANTHROPIC_*就把 Codex 也改成ANTHROPIC_BASE_URL或ANTHROPIC_AUTH_TOKEN那会导致 Codex 读不到 Key。和 Claude Code 一样Codex 也需要把 commit hash 写进日志。可以在运行前记录COMMIT_HASH$(git rev-parse HEAD) PARENT_HASH$(git rev-parse HEAD^) echo {\run_id\:\$AGORA_RUN_ID\,\agent_id\:\$AGORA_AGENT_ID\,\commit_hash\:\$COMMIT_HASH\,\parent_hash\:\$PARENT_HASH\,\provider\:\taotoken\} .agora/logs/codex-meta.jsonl这样后续生成 DAG 日志对照表时Claude Code 和 Codex 的记录可以按commit_hash合并。5. CC Switch 三件套多供应商切换与 DAG 日志隔离多人协作的 AutoResearch 项目经常需要切换供应商、模型和 Key。建议用 CC Switch 的思路管理“三件套”Claude Code 的settings.json负责ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL。Codex 的config.toml负责model_provider、base_url、env_key、wire_api。统一环境变量文件负责TAOTOKEN_API_KEY、AGORA_RUN_ID、AGORA_AGENT_ID、AGORA_DAG_NODE。可以按 profile 隔离目录.cc-switch/ profiles/ agora-claude-a.json agora-codex-a.toml agora-env-a.sh agora-claude-b.json agora-codex-b.toml agora-env-b.sh每个 profile 对应一个实验分支或一组 agent。切换时不要只换 Key还要换AGORA_RUN_ID和AGORA_AGENT_ID否则日志会混在一起DAG 节点归属也会乱。比如 agent A 用 Claude Code 配置agent B 用 Codex 配置但两者都往.agora/logs/写就必须靠agent_id和run_id区分。一个简单的切换脚本#!/usr/bin/env bash set -euo pipefail PROFILE${1:?usage: switch_profile.sh profile-name} cp .cc-switch/profiles/${PROFILE}-claude.json ~/.claude/settings.json cp .cc-switch/profiles/${PROFILE}-codex.toml ~/.codex/config.toml source .cc-switch/profiles/${PROFILE}-env.sh echo switched to ${PROFILE} echo run_id${AGORA_RUN_ID} echo base_urlhttps://taotoken.net/api注意脚本里base_url只是打印真实配置仍从 profile 文件读取。切换后建议跑一次git log --oneline --graph确认当前分支和父提交再把新的 run_id 写入日志。6. DAG 日志对照表commit 到 Token 的 join 键设计现在进入核心如何把 Git DAG 和实验日志合成一张对照表。假设每个 commit 对应一次实验节点commit message 里包含run_id而.agora/logs/*.jsonl里记录模型调用。你可以用git log导出节点表git log --prettyformat:%H|%P|%s .agora/logs/git-dag.txt然后解析 JSONL按commit_hash聚合 Token。一个可用的 jq 命令如下jq -s map(select(.usage ! null)) | group_by(.commit_hash) | map({ commit_hash: .[0].commit_hash, parent_hash: .[0].parent_hash, agent_id: .[0].agent_id, run_id: .[0].run_id, calls: length, prompt_tokens: (map(.usage.prompt_tokens) | add), completion_tokens: (map(.usage.completion_tokens) | add), total_tokens: (map(.usage.total_tokens) | add), max_latency_ms: (map(.latency_ms) | max) }) .agora/logs/*.jsonl如果你希望直接得到 Markdown 表格可以加一段 jqjq -r -s map(select(.usage ! null)) | group_by(.commit_hash) | ([commit_hash,parent_hash,agent_id,run_id,calls,prompt_tokens,completion_tokens,total_tokens,max_latency_ms] | tsv), (.[] | [ .[0].commit_hash, .[0].parent_hash, .[0].agent_id, .[0].run_id, (length|tostring), (map(.usage.prompt_tokens)|add|tostring), (map(.usage.completion_tokens)|add|tostring), (map(.usage.total_tokens)|add|tostring), (map(.latency_ms)|max|tostring) ] | tsv) .agora/logs/*.jsonl | column -t -s $\t最终你会得到类似这样的 DAG 日志对照表commit_hashparent_hashagent_idrun_idcallsprompt_tokenscompletion_tokenstotal_tokensmax_latency_msa1b2c3df0e1d2cagent-claude-coderun-20250601-0135120204871681840b2c3d4ea1b2c3dagent-codexrun-20250601-0123072102440961220c3d4e5fb2c3d4eagent-claude-coderun-20250601-02481924096122882600这张表的作用是当你发现某个 DAG 节点结果异常时可以立刻查到它用了哪个 agent、哪个模型、消耗多少 token、延迟是否异常。如果parent_hash在 rebase 后变化但日志里还是旧 hash就会 join 不上这时需要把parent_hash记录为完整 40 位 hash而不是短 hash。TaoToken 官网入口在这里https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_table Key 创建后 Base URL 仍然是 https://taotoken.net/api 。7. 复现命令从 clone 到 Token 统计的完整链路下面给一套最小复现流程。它不依赖任何生产库所有命令由读者本地执行。假设你已经有一个 Agora 风格的 Git 仓库分支上有多条实验 commit。第一步设置 Key 和 Base URLexport TAOTOKEN_API_KEYYOUR_API_KEY export TAOTOKEN_BASE_URLhttps://taotoken.net/api export AGORA_RUN_IDrun-repro-$(date %Y%m%d%H%M%S) export AGORA_AGENT_IDagent-repro第二步克隆并检出目标 commitgit clone your-agora-repo agora-repro cd agora-repro git checkout target-commit mkdir -p .agora/logs COMMIT_HASH$(git rev-parse HEAD) PARENT_HASH$(git rev-parse HEAD^) echo commit_hash${COMMIT_HASH} parent_hash${PARENT_HASH}第三步用 curl 做一次带 usage 的非流式调用把原始响应落盘。路径按 OpenAI 兼容习惯写curl -sS $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: your-model, messages: [ {role: user, content: 只输出 OK} ], stream: false } | tee .agora/logs/${AGORA_RUN_ID}-raw.json第四步把响应转成 JSONL 日志。这里用 jq 提取 usage 和 commit 信息jq -n \ --arg run_id $AGORA_RUN_ID \ --arg agent_id $AGORA_AGENT_ID \ --arg commit_hash $COMMIT_HASH \ --arg parent_hash $PARENT_HASH \ --arg model your-model \ --slurpfile resp .agora/logs/${AGORA_RUN_ID}-raw.json \ { run_id: $run_id, agent_id: $agent_id, commit_hash: $commit_hash, parent_hash: $parent_hash, model: $model, usage: $resp[0].usage, status: ok, latency_ms: 0 } .agora/logs/${AGORA_RUN_ID}.jsonl第五步汇总 Token 统计jq -s map(select(.usage ! null)) | { calls: length, prompt_tokens: (map(.usage.prompt_tokens) | add), completion_tokens: (map(.usage.completion_tokens) | add), total_tokens: (map(.usage.total_tokens) | add) } .agora/logs/*.jsonl如果输出类似下面这样说明链路通了{ calls: 8, prompt_tokens: 24576, completion_tokens: 8192, total_tokens: 32768 }第六步生成 DAG 图文本和日志对照git log --graph --oneline --decorate --all .agora/logs/dag-graph.txt git log --prettyformat:%H %P %s .agora/logs/dag-parents.txt paste -d | .agora/logs/dag-parents.txt (jq -r [.commit_hash,.total_tokens] | tsv .agora/logs/summary.jsonl) 2/dev/null || true最后一步把 Token 统计和 DAG 节点写回实验记录但不要 amend 历史 commit。只追加一个新的记录 commitgit add .agora/logs/ git commit -m log: attach token stats for ${AGORA_RUN_ID}这样每个结果、洞察、验证仍然保持可检出、可复跑。需要创建 Key 时走 TaoToken 控制台https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_keys 。如果要做持续实验可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_plan 。8. 排障清单401、provider not found、Token 为 0、DAG 对不上第一401 Unauthorized。Claude Code 下检查ANTHROPIC_AUTH_TOKEN是否等于YOUR_API_KEYANTHROPIC_BASE_URL是否等于https://taotoken.net/api。Codex 下检查TAOTOKEN_API_KEY是否 export 成功config.toml的env_key是否写成了TAOTOKEN_API_KEY。不要把 Claude Code 的ANTHROPIC_*复制到 Codex。第二模型名 404 或 model not found。去模型对话页确认实际模型标识不要用展示名直接当 API 模型名。改ANTHROPIC_MODEL或 Codex 的model字段后重启对应工具。第三Codex provider not found。检查model_provider taotoken和[model_providers.taotoken]是否严格一致TOML 表名不能拼错。base_url不要带 UTM不要带尾部/v1统一写https://taotoken.net/api。第四Token 统计为 0。多数是因为流式响应没有返回 usage或者 jq 过滤条件写错。改用stream: false先验证或者在流式请求里显式打开 usage 选项。如果响应里 usage 为 null先看原始 JSON 落盘文件确认字段路径是usage.total_tokens还是嵌套在别的结构里。第五DAG 对不上。最常见是 rebase、amend、cherry-pick 导致 parent hash 变化。日志里要记录完整 hash并区分commit_hash和parent_hash。如果同一实验跨多个 agent必须用run_id agent_id commit_hash三元组做唯一键不能只用短 hash。第六日志串线。Claude Code 和 Codex 同时写.agora/logs/时必须每个 profile 独立AGORA_RUN_ID。切换 CC Switch 三件套后先跑echo $AGORA_RUN_ID确认环境变量已刷新再启动工具。完整的工具配置路径可以按这个顺序走先用模型对话页确认模型名再开 Coding Plan然后创建 API Key最后按 Claude Code 文档配置 settings.json。对应入口如下模型对话https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_chatCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_coding创建 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_apikeyClaude Code 文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentagora_git_dag_doc把 Base URL 固定为https://taotoken.net/api把YOUR_API_KEY放进环境变量把 commit hash 写进每次调用的 sidecar 日志再用 jq 生成 DAG 日志对照表你就能在不改 Agora 论文核心思路的前提下让每个 Git DAG 节点都带上一份可查、可复现、可统计 Token 的实验账本。