graphloom 用离线代码图谱辅助 Agent 查库
graphloom 将仓库中的导入、调用、建表语句和文档引用连接成图谱,为查询返回带文件行号的证据,并生成报告和离线交互视图。项目采用 MIT 许可,仅依赖 Python 标准库,作者列出 32 项离线测试。
AI 深度解读
Coding agent 查一个调用关系,经常要先搜关键词,再打开多个文件,读完一圈仍可能漏掉间接调用。graphloom 的思路是先离线给仓库建一张关系图,让 agent 用短查询拿到函数、表、文档之间的联系,以及对应的代码行。
作者用示例项目和 httpx 展示了它的价值:部分问题可以用几百字节的路径回答,不必读取整个文件。但这张图也有明确边界:它没有类型推断,图上存在一条路径,不代表程序运行时一定沿着它执行。
先把仓库连起来,agent 才能少读文件
graphloom 是一个采用 MIT 许可证的 Python 工具,要求 Python 3.10+,仅依赖标准库,原文称有 32 个离线测试。它先提取仓库里的实体,再建立关系,全程可以不调用模型。
不同文件的处理深度并不一样:
- Python 使用标准库
ast,提取模块、类、函数、导入和调用。 - JS/TS 使用小型扫描器,识别导入、导出、调用,以及
fetch("/route")里的 URL。 - SQL 提取
CREATE TABLE和外键,并关联 SQL 字符串中提到表名的代码。 - Markdown 把标题与反引号里的符号连接起来。
- TOML/YAML/JSON 提取配置键,再关联读取这些配置的代码。
这些关系把「某个名字出现在哪」推进到了「它和谁有关」。例如,查表时能一起看到建表位置、外键、写入函数和相关文档。
在仓库运行 graphloom build . 后,.graphloom/ 下会生成 graph.json、REPORT.md 和 graph.html。内置的 examples/harbor-shop 包含 Python 服务、SQL schema、浏览器购物车和两份文档,构建结果为 67 个节点、108 条边,其中 parsed 75 条、linked 33 条、llm 0 条。
之后可以用 query 找关联、path 查路径、explain 看解释。这三个能力离线可用,ask 才需要模型。
路径能定位代码,但不能替代运行时事实
作者用结账项目回答了一个具体问题:HTTP 入口怎样走到收据邮件发送函数?
下面这段查询解决的是跨文件调用追踪,输出保留了每一跳的代码证据:
graphloom path post_invoice send_receipt
path: post_invoice -> send_receipt
resolved: fn:backend/app.py:post_invoice -> fn:backend/notify/emailer.py:send_receipt
hops: 4
directed: yes
1. fn:backend/app.py:post_invoice
invokes [parsed] -> fn:backend/billing/invoices.py:create_invoice
backend/app.py:10 return create_invoice(payload, settings)
2. fn:backend/billing/invoices.py:create_invoice
invokes [parsed] -> fn:backend/billing/payments.py:record_payment
backend/billing/invoices.py:39 record_payment(str(payload["invoice_id"]), total, "card", str(payload["email"]))
3. fn:backend/billing/payments.py:record_payment
invokes [parsed] -> fn:backend/notify/emailer.py:queue_receipt
backend/billing/payments.py:12 queue_receipt(email, invoice_id)
4. fn:backend/notify/emailer.py:queue_receipt
invokes [parsed] -> fn:backend/notify/emailer.py:send_receipt
backend/notify/emailer.py:5 send_receipt(email, invoice_id)
要关注 directed: yes 和每条边的 [parsed]:这里展示的是沿调用方向解析出的路径,每一跳都有 file:line,agent 可以据此定点读代码。
查表则使用 graphloom query invoices --budget 1600。输出会列出 sql/schema.sql:17 的表定义、字段、外键,以及 backend/billing/invoices.py:35 的 INSERT INTO invoices。--budget 将输出限制在大约指定的 token 数,超出时标记 truncated: yes,适合给 agent 控制上下文。
边的来源也会显示为 parsed、linked 或 llm。例如写表关系标成 linked,就不能把它描述成模型凭空判断的结论,也不能与直接解析出的函数调用混为一谈。
关系图最有用的部分,是让结论带着证据和来源一起返回。
不过,来源可追溯不等于关系完整。作者查询 Client.get 到 HTTPTransport.handle_request 时,结果出现 directed: no,路径借道「Custom transports」文档标题。真正的调用是 self._transport.handle_request(...),工具没有类型推断,无法确定 self._transport 的具体对象。这时应该回到代码核实。
半秒构建有实测,省多少钱还缺对照
作者在 encode/httpx 的 b5addb6 提交上做了测试,输入约为 280 KB Python 代码加文档。构建得到 1767 个节点、3388 条边,其中 parsed 2244 条、linked 1144 条、llm 0 条,耗时 0m0.494s,无需网络。
REPORT.md 的关系数量排名也能辅助入门:Response 为 160,Client 为 152,MockTransport 为 101,Request 为 99,AsyncClient 为 84。不过,连接多只能说明关联密集,不能直接等同于业务重要性。
通过 graphloom path fn:httpx/_client.py:Client.get fn:httpx/_client.py:Client.send,作者拿到了两跳路径:Client.get → Client.request → Client.send。回答为 609 字节,而整个 httpx/_client.py 是 65,713 字节。这个例子说明返回内容可以很小,但不是完整 agent 任务的成本对照。
模型是可选层。graphloom build . --semantic --max-calls 4 只把文档片段发给模型,不发送源码,让模型提出概念与锚点;结果按内容哈希缓存,文档不变时再次构建无需重复付费。graphloom ask "question" 则检索小子图,再让模型引用节点 ID 和 file:line 作答。httpx 示例发送的上下文约 10 KB,即约 2.5k tokens,每次问题调用一次模型。
原文默认使用 AtmoRouter 和 zai/glm-5.3-flash,通过 ATMOROUTER_API_KEY 配置,也支持其他 OpenAI-compatible endpoint。文中宣传的 109 个模型、平均低于官方价格 83.7%,没有给出核算方式,不能拿来直接估算团队账单。
接入 Cursor 或 Claude Code 时,下面的配置把图查询暴露为 MCP 工具:
{
"mcpServers": {
"graphloom": {
"command": "graphloom",
"args": ["serve", "--graph", ".graphloom/graph.json"]
}
}
}
要关注 --graph 指向的文件。Cursor 放到 .cursor/mcp.json,Claude Code 放到 .mcp.json。服务通过 stdio 上的换行分隔 JSON-RPC 提供 graph_query、graph_path、graph_explain、graph_ask,只有最后一个需要模型调用。
我的判断
我认可先建立可查询关系、再让 agent 阅读必要代码的顺序。关键词搜索擅长找出现位置,关系图更适合回答调用链、表访问和文档关联。两者可以接力使用。
但作者没有提供与 grep、语言服务器或其他代码检索方案的完整对照,也没有给出关系识别的准确率、召回率,以及真实任务完成率。半秒构建和 609 字节回答是具体实测,「agent 因此更快、更便宜」仍缺端到端数据。
对前端团队还要多留一个判断:Python 用的是 ast,JS/TS 用的是小型扫描器。原文没有说明它对复杂别名、框架约定、动态调用的覆盖程度,也没有交代代码变动后的图更新策略。不能根据 Python 示例推断它同样理解大型 TypeScript 项目。
能拿来做什么
- 接手陌生仓库时,可以先运行
graphloom build .,结合报告和调用路径选择阅读入口,再打开证据指向的文件。 - 排查接口到数据库、通知函数之间的关系时,先用
path和带--budget的query缩小范围;遇到directed: no或文档关联路径,就回到源码确认。 - 在 Cursor 或 Claude Code 中接入 MCP 后,可以要求 agent 优先尝试
graph_path、graph_query,并在回答中保留边的来源和代码行号。 - 对 JS/TS 或 Node 仓库,先挑已有答案的调用链检查覆盖情况,再决定是否扩大使用;评估模型功能时,分别核对文档语义构建和
ask查询发送的内容。