一句话:codegraph 让 agent 不必自己理清代码关系;docmap 让 agent 不必自己摸索该读哪份文档,并且把"文档被读了多少次、烧了多少 token、有没有读到过期结论"量出来。
对任何 Markdown repo 都能建图;Claude Code 可零配置采集,其他 Agent 通过标准
JSON/NDJSON 事件流接入。绝不往目标仓库写任何文件(缓存全落
~/.cache/docmap/<slug>/)——这样目标仓库能当对照组。
bin/docmap --repo ~/repo build # 建图 + 采遥测 + 标定 token 系数
bin/docmap --repo ~/repo report # 九类诊断(人看)
bin/docmap --repo ~/repo serve # 图谱(浏览器画布,实时)
bin/docmap --repo ~/repo route "更新 API 鉴权" # 该读哪几份(agent 用)
bin/docmap --repo ~/repo plan-change "更新发布状态" # 新建/插入/修改?
bin/docmap --repo ~/repo impact src/auth # 哪些文档需要复核?
bin/docmap --repo ~/repo validate # 检查当前 Git diff
bin/docmap --repo ~/repo baseline # 历史任务的阅读成本基线python3 docmap.py …、python3 -m docmap …、pip install -e . 后的 docmap … 三种入口等价。核心零依赖;只有读 profile 需要 pyyaml。
| 做什么 | 缺什么 | |
|---|---|---|
| Obsidian graph | 画链接图 | 不知道谁读过、花了多少;表达不了"谁推翻了谁" |
| token-dashboard 等 | 算 token 成本、文件热力 | 不知道文档之间的关系,给不出"该读/别读" |
| codegraph | 代码知识图 | 不管文档 |
| docmap | 图 × 遥测交叉 | — |
文档之间的关系有三种来源,它们打架的地方就是文档该重组的地方:
| 边 | 来源 | 说的是 |
|---|---|---|
structure / tree |
目录(纯路径推导,免费) | 当初怎么归类的。每个目录一簇,簇心=该目录 README/index(没有就取 git 改动最多的),簇心辐射同目录成员、子簇心串父簇心 |
link / index / supersedes |
markdown 链接、裸路径、wikilink | 作者觉得该连什么 |
coread |
遥测:同 session 前后脚被读 | 实际上要一起读。判据用共现的 session 数而非原始次数——同一 session 来回翻会把次数刷高,但只是一次工作 |
| 诊断 | 抓什么 | 为什么贵 |
|---|---|---|
🔴 stale_read |
文档带勘误,但 agent 跳读时没覆盖到勘误行 | 拿走的是已作废结论,而且它自己不知道 |
🔴 zombie |
已整篇作废,却仍在被读 | 错误结论直接污染判断 |
🔵 mismatch |
三族边打架:隐形依赖 / 松散目录 | 目录结构和实际用法对不上 |
🟠 fat |
高读取 × 高 token | 成本集中在少数几份,拆了立刻省 |
⚪️ cold |
在库里、零读取 | 出库候选(比"没人提及"的 orphan 判据强) |
🟡 route_miss |
session 开头连读多份才动手 | 入口没指准,每次都白花开场 token |
📏 drift |
同一冻结数字散落多处 | 改一处别处不同步 |
🧭 entry_gap |
声明入口 vs 实测首读 | 索引写了没人走 |
📦 ext |
Agent 反复读取 repo 外文件 | 活知识没有被项目正式收编 |
docmap 不代替 Git 或 Agent 写文件。它在编辑前给出依据,在编辑后验证依赖:
# 1. 现有文档是否能承接?应该新建、插入还是修改?(只读)
bin/docmap --repo ~/repo plan-change "更新 API 发布状态"
# 已知目标时消除模糊匹配
bin/docmap --repo ~/repo plan-change "更新发布状态" --target docs/api/STATUS.md
# 2. 修改一个文档或 repo 路径会触及谁?(只读)
bin/docmap --repo ~/repo impact docs/api/STATUS.md
bin/docmap --repo ~/repo impact src/auth
# 3. Agent 正常编辑后,检查整个工作树的 Git diff
bin/docmap --repo ~/repo validate
bin/docmap --repo ~/repo validate --staged
bin/docmap --repo ~/repo validate --strict # CI 可选择让 warning 也失败validate 只让确定性问题默认失败:新文档缺职责/scope、断链、显式 repo 锚点
不存在、doc_id/canonical_for 冲突、继续引用已整篇作废的文档。代码变化触及
文档 scope、重文档和弱关系只报 warning;它们表示“需要复核”,不冒充语义漂移。
新文档可用最小 front matter 声明强关系:
---
doc_id: api-release-status
doc_type: status
scope:
- src/auth
canonical_for:
- api_release_status
depends_on:
- docs/architecture/AUTH.md
owner: platform
status: gated
---旧文档无需一次性补齐。治理门槛只强制作用于新增文档;现有文档可以按真实使用
热度渐进补元数据。所有命令支持 --json,便于以后封装成少量 MCP tools。
bin/docmap --repo ~/repo serve # 盯实时
bin/docmap --repo ~/repo serve --replay busiest --speed 60 # 回放,零 token页面提供两个互补视角:
- 文档关系:分别开关显式引用/依赖、目录结构、历史共读,避免把不同置信度的边混成一类。
- Agent 阅读流:按每个 Agent 自己的时间顺序画有向箭头;右侧保留可访问的事件列表,避免把并行 Agent 之间的相邻时间误画成因果关系。
- 灰点是本次未读,黑点是本次已读;红/黄色边框同时用状态文字表达作废或勘误,不只依赖颜色。
- 点击节点查看入链、出链、共读伙伴、历史读取成本和诊断;支持搜索、关系筛选、拖拽、缩放与
F全图定位。 - 超过 450 个节点时保留目录预布局但跳过二次方力导向;关系超过 7000 条时明确提示并限绘,避免大仓库把浏览器主线程拖死。
页面自包含无外部依赖(离线可用),只监听 127.0.0.1。
bin/docmap --repo ~/repo watch # 字符星图
bin/docmap --repo ~/repo watch --plain # 纯文本流(可管道 / 无 TTY)
bin/docmap --repo ~/repo watch --sessions # 列出可回放的 sessionbin/docmap --repo ~/repo stream | jq -c 'select(.type=="read")'先一行 {"type":"graph",…},之后每次阅读一行 {"type":"read",…}。VS Code / Cursor 扩展将来就是起这个子进程、把 stdout 转给 webview——Python 侧一行不用改,扩展只做一层薄壳。
message.usage 给出每步 context 总量;相邻两回合之差减去上一回合 output = 这中间读进来的量。取"该回合的 tool_result 全是文档读、且消息没挂别的内容块"的干净样本,对 (CJK 字数, 其余字数, 常数) 做三参最小二乘。
本仓实测:CJK 1.46 tok/字、其余 0.657 tok/字,中位相对误差 14%(n=2002)。中英密度差 2.2 倍,用单一常数必错。
三个必踩的坑写在 docmap/telemetry.py 顶部:同回合多行共享 usage(按 requestId 去重)、并行 Read 共享同一增量(按回合汇总回归)、无截距会把固定开销摊进斜率。第四个坑在 collect():增量运行样本远少于全量,拟合更差时不许覆盖已有标定,否则 token 口径每次 build 都漂。
~/.claude/projects/<slug>/ 下三类 jsonl,三类都要收,少一类就低估成本:
<sid>.jsonl 主驾
<sid>/subagents/agent-*.jsonl Agent 子 agent
<sid>/subagents/workflows/<wf>/agent-*.jsonl Workflow 扇出
Read 走精确路径与行窗口;Grep/Glob/Bash(cat/head/sed/grep)也计入,但 Bash 一次摸多个文件时按份数均摊 token,是近似值。
核心图谱和 UI 不依赖 Claude。任何 Agent、IDE 或 MCP 宿主都可以逐行输出以下事件:
{"type":"prompt","provider":"my-agent","session":"s1","ts":"2026-08-12T10:00:00Z","text":"了解鉴权模块"}
{"type":"read","provider":"my-agent","session":"s1","agent":"main","ts":"2026-08-12T10:00:01Z","path":"docs/auth.md","tokens":420,"partial":false}
{"type":"action","provider":"my-agent","session":"s1","ts":"2026-08-12T10:00:03Z","kind":"edit_source","path":"src/auth.py"}bin/docmap --repo ~/repo --events /tmp/agent-events.ndjson serve --speed 60
bin/docmap --repo ~/repo --events /tmp/agent-events.ndjson baseline最小可视化事件只需要 type=read、path 和 session;prompt/action 用于
baseline。tokens 缺失时保留为未知成本 0,工具不会伪造精度。当前 canonical
文件按已录事件自动回放;真正的跨宿主实时流将在 MCP transport 层复用同一 schema。
baseline 把 transcript 按真实的人类 prompt 切成 task episode,再按 profile 中
可审计的关键词规则分类。它同时统计文档读取数、估算 token、重复/整份读取、首次工作
前阅读量、编辑与验证动作,并明确区分:
cold_start:该 transcript 的第一个用户请求;warm_followup:已经继承当前 transcript 上下文的追问。
两类不能混成等价样本。Session 也不能直接当任务:真实 session 可能跨很多天、包含 多个用户目标。
bin/docmap --repo ~/repo --profile ./docmap.yml baseline
bin/docmap --repo ~/repo --profile ./docmap.yml baseline \
--scenario onboarding --include-episodes --json关键词命中只是历史样本初筛,不是任务真值;时间戳是可观测工具活动,不是人的注意
时间;Write 调用也不能证明文件最终落盘。准确率和任务成功率不在 transcript 中,
必须另做固定 prompt、人工评分的 A/B 实验。
数据边界:为了允许 profile 动态重分类,本地 telemetry cache 会保留每个真实用户
prompt 的前 4000 字;动作只保留类别、工具名和路径,不复制 shell 命令或编辑正文。
缓存仍在 ~/.cache/docmap/,权限设为仅当前用户读写。这是本地分析数据,不是 Agent
长期记忆;如仓库涉及敏感请求,应把该缓存纳入本机数据清理策略。
看效果 → 回放。 已录的 transcript 里躺着几千次真实阅读,纯读盘重放:
bin/docmap --repo ~/repo watch --sessions
bin/docmap --repo ~/repo serve --replay busiest --speed 60测实时通路 → 模拟器。 造一份假的"正在跑"的 session(含子 agent),只读目标仓库的文档当素材,不写它一个字节:
python3 tools/simulate.py --repo ~/repo --interval 1.5 # 终端 A
bin/docmap --repo ~/repo --transcripts /tmp/docmap-sim serve # 终端 Bpython3 tests/test_units.py # 分层用例,每个对应一次真实事故或统计口径
python3 tests/test_end_to_end.py # 临时仓库 + 人造 transcript 全链端到端那个额外验证一件事:目标仓库零改动。
零配置能跑(track 按目录推断、入口自动认 CLAUDE.md/AGENTS.md/各级 README)。要覆盖就写 profile:
bin/docmap --repo ~/repo --profile ./docmap.yml reportprofiles/kmc.yml 只是大型科研仓库的验收样例,不属于核心默认逻辑。