2026年4月29日 周三晚上19:30,来了解“企业AI训练师:从个人提效到构建企业AI生产力”(限30人)
免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

Karpathy的LLM Wiki + 3.5 万Star的Graphify:企业级 RAG 缺的真是知识图谱?

发布日期:2026-04-27 07:08:43 浏览次数: 1557
作者:韦东东

微信搜一搜,关注“韦东东”

推荐语

Karpathy的LLM Wiki与Graphify项目引爆技术圈,但企业级RAG真正需要的是结构化解决方案。

核心内容:
1. LLM Wiki与传统RAG的差异对比
2. 30份合成合同构建的测试基准分析
3. 企业级知识库的混合架构设计思路

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

4 月中旬的时候,知识星球里有盆友问到 Karpathy 的 LLM Wiki。当时只是粗略复现了下,没来得及系统测试。正好这周末得空,花了一天时间把 LLM Wiki,以及另一个更火的衍生项目 Graphify 都认真跑了一遍。

我写这篇的时候,Karpathy 那份 LLM Wiki gist 已经到 5000+Star,而 Graphify 已经有了3.5 万 Star 左右。一个讲知识预编译,一个讲自动知识图谱,看起来都很适合拿来改造企业 RAG。但真正跑到合同知识库这种场景里,结论其实并没有那么简单。

先说结论,个人知识库的最佳实践,不一定是企业知识库的最佳实践。LLM Wiki 给了一个很好的参考思路是,传统 RAG 少了一层知识预编译,这个思路值得抄。Graphify 可以借鉴的是,Agent 不一定每次都要从原始文件开始读,结构化导航也很重要。但企业级 RAG 真正缺的,不是再多一个酷炫工具,而是受控 schema、结构化字段、原文引用、权限边界和可复跑评测。

这篇试图说清楚:

我会先用大白话讲清楚 LLM Wiki 和传统 RAG 的差别,再用 30 份合成合同搭一个共同测试基准。然后分别复现 Graphify 的代码场景、跑一个我自己的 RAG 入库质检工具包,再把基础 RAG、LLM Wiki 小样本和受控 schema 综合方案放到同一套问题里比较。最后想讨论的不是哪个开源项目最强,而是企业级知识库到底应该把模型、向量库、结构化字段、关系表和高频综合页分别放在什么位置。

以下,enjoy:

1

   

先搭试验数据集:为什么是 30 份合同

老规矩,在正式开始之前,我先把后面用来测试的数据集说清楚。

1.1

   

为什么要先做共同基准

这篇文章会依次介绍 LLM Wiki、Graphify,以及我自己更倾向的企业级混合方案。为了让每类方案在同一个基准下比较,我先做了一个小型工程设计:用同一套文档,分别去跑 LLM Wiki、Graphify 和后面的问答评测。

1.2

   

为什么选合同这种文档

之所以选合同作为演示,是因为企业知识库真正麻烦的地方,通常不是处理单篇文档。单篇文档再长,也就是解析、切块、检索、引用这些问题。真正容易挑战系统能力边界的,往往是一堆文件之间的关系

合同场景正好有这个特点:主合同、技术协议、补充协议、验收单、售后协议不是孤立存在的,这些都围绕同一个项目不断叠加,当然更进一步来说还有更细节的金额、工期、验收、违约金、质保期这些业务字段。

1.3

   

为什么是水处理非标设备集成场景

具体的合同类型这次选的是水处理非标设备集成厂商的项目合同,这个 case 之前在售前报价 Agent 的时候专门写过两篇文章。

看过的盆友应该还记得,这类公司很多项目都要按现场条件、工艺要求、客户预算重新报价。售前阶段要看历史项目和报价,项目执行阶段要看合同、技术协议和补充协议,交付之后还要看验收和售后。销售、项目、财务、售后看的是同一个项目,但各自关心的字段不一样。拿这个场景来测知识库,比拿几份产品手册更接近企业实际。

从"找案例"到"出报价":一个售前报价Agent的7个工程决策

售前报价Agent落地案例拆解:检索优先 vs 生成优先

受限于商业条款限制,没法把实际项目中的合同文本放进文章里。不过为了更好还原实际的业务场景特征,我按这个业务结构,重新造了一组水处理设备合同样本。

所谓的造,也不是随便编 30 个文件凑数,业务结构还是按真实项目来的,只是客户名、金额、日期、合同编号全部做了虚构和脱敏。各位可以把它理解成一套可以公开复现的合同样例集,里面的行业逻辑、合同结构、项目关系尽量贴近真实业务,但不会指向任何真实企业。

1.4

   

这 30 份合同的设计

这组数据一共有 9 个项目,30 份合同文件。客户类型分成工业、市政、商业三类,文档类型包括主合同、技术协议、补充协议、验收单和售后服务协议。

1.5

   

测试埋点

可能会有盆友疑问为什么要做得这么麻烦,这是因为合同知识库真正难的地方,通常不是查一个合同金额。查金额、查日期、查甲乙方,这些问题只要解析别太差,传统 RAG 也能答个七七八八。真正容易翻车的是主合同、补充协议、验收单之间的关系。

比如在这个演示的水处理设备集成场景里,P-001 项目,主合同之后又签了一份补充协议,追加了除盐水机组,后面的验收单又记录了延期 45 天,但双方协商免除了违约金。这个问题如果只召回验收单,可能会看到延期。如果只召回主合同,可能会按违约金条款直接算钱。只有把主合同、补充协议、验收单串起来,才能知道它为什么延期,以及为什么没有扣违约金。

我在这 30 份合同里刻意埋了几类测试点。这些设计也是为了后面做评测时能拉开差距,基础 RAG、LLM Wiki、混合方案如果只测简单事实题,几种方案看起来都还行。但一旦问到主补关系、延期责任、质保差异、尚未验收这类问题,差距就会很明显。

说清楚了数据集长什么样,接下来再分别看下 LLM Wiki、Graphify 和最终的混合方案,在这套合同库上会跑出什么效果,我想各位再结合自己身边的场景,就会有更清晰的工程逻辑取舍的参考了。

2

   

LLM Wiki:先讲人话,再看实操

2.1

   

它不是一个新的 RAG 产品

LLM Wiki 这个东西,刚看到名字的时候很容易误会,以为它又是一个新的 RAG 框架,或者是一个现成的知识库产品,其实不是。

https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f 

Karpathy 那份 llm-wiki.md 更像一个想法说明,它没有给一个完整系统,也没有规定必须用某个数据库、某个 embedding 模型、某个前端。它说的更多算是一种工作方式:不要只在用户提问的时候临时检索文档,而是让 LLM 在资料进入知识库的时候,先把资料加工成一套长期维护的 Markdown Wiki。

这句话听起来有点抽象,我先不用合同讲。合同一上来就有主合同、补充协议、验收单、违约金,很容易把概念讲复杂。

2.2

   

普通 RAG 的问题在哪

假设你现在有三份资料,第一份是产品发布说明,说 v2.3 新增了批量导入功能,单次最多 5000 条,emoji 可能导致失败。第二份是客服工单,说最近 7 天有 42 个客户反馈批量导入失败,其中 31 个都和 emoji 有关,里面还有 12 个金融客户。第三份是销售会议纪要,说金融客户很关注批量导入能力,竞品已经支持 10000 条。

如果这时候有人问你,批量导入现在最大的问题是什么,对金融客户有什么影响。

普通 RAG 会先把这三份资料切成 chunk,再做 embedding,问题来了以后检索 top-k,然后把检索到的几段文本塞给大模型,让模型临时拼一个答案。

这个流程当然能用,过去两年大部分知识库项目都是这么做的。但它有一个问题:每次问类似问题,大模型都要重新拼一遍。 这次问金融客户,下次问企业版客户,再下次问竞品差距,它每次都要重新找片段、重新组合、重新判断。知识没有沉淀下来。

LLM Wiki 想尝试解决的就是这个问题。

2.3

   

它多做了一层知识预编译

它的做法不是等用户提问时再临时拼,而是在资料进来的时候,就先让 LLM 做几件事。

第一件事是给每份资料生成摘要页。比如产品发布说明有一页摘要,客服工单有一页摘要,销售会议纪要也有一页摘要。以后不用每次都重新读原文,先看摘要就能知道这份资料讲了什么。

第二件事是生成实体页。比如金融客户这个实体,在客服工单里出现过,在销售会议纪要里也出现过。LLM Wiki 会把这些分散信息汇总到同一个页面里。你再问金融客户相关问题时,不需要在三份资料里来回翻,它已经有一个汇总页。

第三件事,也是我觉得最有价值的一件事,是生成综合分析页。比如批量导入功能风险分析,这个页面可以提前把产品限制、客服反馈、金融客户影响、竞品差距放在一起,形成一个可以直接阅读的结论。

这就是 LLM Wiki 和普通 RAG 最大的区别。普通 RAG 是提问时临时找材料,LLM Wiki 是资料进入时先做知识编译。普通 RAG 的知识形态是 chunk,LLM Wiki 的知识形态是摘要页、实体页、概念页、综合页和索引页。

放在表里,大概是这些区别:

维度
传统 RAG
LLM Wiki
知识处理时机
提问时临时检索
资料进入时先加工
知识形态
文档 chunk
摘要页、实体页、综合页、索引
多文档综合
每次重新拼
提前沉淀成综合页
矛盾处理
通常靠提问时发现
ingest 或 lint 时提前标记
重复查询成本
每次都要检索和推理
前面编译一次,后面反复使用

所以我对 LLM Wiki 的理解很简单:它不是 RAG 的替代品,而是 RAG 缺失的知识预编译层。

这个思路当然也没什么破天荒,做企业知识库项目的时候,本身也经常人肉做类似的事。比如先把文档分类,抽关键字段,整理 FAQ,做专题页,标注风险条款。区别在于,LLM Wiki 把这件事明确成了一套可以让 Agent 持续维护的工作流。人负责放资料、提问题、判断方向,LLM 负责摘要、归档、交叉引用和更新。

Karpathy 原始文档里还有几个配套概念。index.md 是目录页,用来告诉人和模型有哪些页面。log.md 是操作记录,记录什么时候 ingest 了什么资料。lint 是定期检查 Wiki 里有没有矛盾、过时信息、孤立页面。Obsidian graph view 则是拿来浏览这些 Markdown 页面之间的连接。

这里顺道说一句,Obsidian 不是 LLM Wiki 的核心。它只是一个很好用的 Markdown 浏览器。真正有价值的是 Agent 生成并维护的那层 Wiki。

讲完这个通用例子,真正要判断 LLM Wiki 能不能用于企业项目,还是得拿合同这种更麻烦的文档试一下。合同库的难点不只是信息分散在多份文件里,更麻烦的是文件之间有版本关系、金额变化、工期顺延、验收状态和违约金处理。

2.4

   

用 5 份合同跑一个轻量实操

不过因为 LLM Wiki 的 ingest 不是建个索引这么轻,它每处理一份 source,都会更新 source summary、project page、clause page、synthesis page、index、log 等多个页面。Karpathy 原文里也提到,一份 source 可能触发 10 到 15 个 Wiki 页面更新。第一轮演示如果直接放 30 份,页面会一下子膨胀,各位反而看不清这个机制本身。

我的处理方式大致是这样的:

阶段
数据范围
目的
原始数据展示
samples/contracts/
 下 30 份合同
说明后续测试的数据集规模
LLM Wiki 轻量演示
llm-wiki-demo/raw/contracts/
 下 5 份合同
展示 Wiki 页面如何生成
后续正式评测
30 份合同加 48 题
对比基础 RAG、LLM Wiki、混合方案

llm-wiki-demo/ 里的结构也很简单。raw/contracts/ 放 5 份原始合同,wiki/ 下面放 Agent 生成的摘要页、项目页、条款页、实体页和综合分析页。AGENTS.md 是给 Codex 或 Claude Code 看的工作规则,规定它应该怎么 ingest,哪些文件不能改,生成页面放到哪里,事实性表述要带来源文件名。

这份 AGENTS.md 不是重新发明一套东西,而是把 Karpathy 的 Raw sources、Wiki、Schema 三层结构落到合同场景里。大的框架没变,只是把通用页面类型换成了合同里更有用的东西,比如项目页、补充协议变更、违约金、质保期、验收条款、售后服务。

实操的时候,我先在 Obsidian 里打开整个 demo vault。未筛选的 graph view 会把 README、AGENTS、CODEX_PROMPT、原始合同和 Wiki 生成页全部画进去,所以画面上会有一些噪音。但即便这样,中间已经能看到一团由 index、项目页、条款页、实体页、综合分析页组成的结构。

为了看清 LLM Wiki 真正生成的知识层,我又在 Obsidian 的 Graph View 里只保留 path:wiki,并关掉 orphan nodes。筛选后就清楚很多了。原始合同不再是重点,图里主要剩下项目、条款、客户实体和两篇综合分析页。

这个图说明的不是把合同放进 Obsidian 有多厉害。只把合同放进去,本质上还是一个能阅读的文件夹。LLM Wiki 真正多出来的是上面这一层:Agent 把原始合同预处理成了可以浏览、可以复用、可以继续维护的知识层。

2.5

   

为什么接着看 Graphify

这部分我先不展开更多细节,因为后面还有正式问答评测。这里只尝试给各位一个初步判断:source summary 和 project page 对快速理解合同库有帮助,synthesis page 对跨合同综合问题确实有价值。但它也有明显问题,比如引用颗粒度不够细、权限和审计没有现成机制、结构可控性依赖 AGENTS.md 写得好不好。

所以我对 LLM Wiki 的结论是思路值得抄,但不能原样当成企业合同知识库的生产方案。

这也是为什么接下来会给各位继续介绍 Graphify。它可以理解成开源社区里沿着这个方向继续往前拓展的一个工具,不是只让 Agent 维护 Markdown Wiki,而是直接把一个文件夹变成可查询的知识图谱。我查 GitHub 的时候,safishamsi/graphify 已经是 3.5 万 Star 左右,热度明显比 Karpathy 那份 idea file 更像一个具体产品。

Graphify 官方的说法是,它面向 Claude Code、Codex、OpenCode 这类 AI coding assistant,可以把代码、文档、论文、图片这些文件统一抽成知识图谱。代码部分主要靠 Tree-sitter 做静态分析,文档部分靠 LLM 做语义抽取,最后输出 graph.htmlgraph.json 和 GRAPH_REPORT.md

这听起来刚好击中合同知识库的痛点。既然合同难在关系,那能不能直接用图谱把关系抽出来?所以我接着跑了三个 case,结果挺有意思。

3

   

Graphify:先复现代码场景,再看它到底能说明什么

如果说 LLM Wiki 是让 Agent 把资料提前整理成 Markdown Wiki,那 Graphify 往前又走了一步,它希望直接把一个文件夹变成知识图谱。输入可以是代码,也可以是文档、论文、图片。输出主要是三个东西:一个可以点开的 graph.html,一个机器可读的 graph.json,还有一个给人看的 GRAPH_REPORT.md

https://github.com/safishamsi/graphify 

这个方向看起来确实很洋气,毕竟企业知识库最头疼的就是关系,合同之间有关系,条款之间有关系,项目和验收、售后、回款也都有关系。不过问题是,关系这件事不能只看有没有图,关键要看这张图到底画的是什么关系

3.1

   

先说人话,Graphify 到底做了什么

Graphify 在代码场景里的核心逻辑其实不难理解。它先扫一遍代码库,用 tree-sitter 这类工具抽代码结构,比如哪个文件里有哪些类,哪些函数,哪些 import,哪些调用关系。然后再把这些节点和边组织成图,用社区发现算法分成若干个社区,最后生成一份报告。

所以它不是单纯画图工具。graph.html 只是展示层,真正有用的东西在 graph.json 和 GRAPH_REPORT.md 里。前者是完整图数据,后者会告诉你哪些节点连接最多,哪些社区比较大,哪些关系可能值得关注。

代码场景天然适合这套逻辑,因为代码关系相对确定。A import B,A 调用 B,A 继承 B,这些关系不是靠拍脑袋猜出来的,至少有很大一部分可以从 AST 里直接抽出来。

文档场景就不一样了。文档里的关系通常不是显式调用,而是语义关系。比如一份补充协议修改了哪份主合同,验收单是否改变了违约金责任,售后协议是否覆盖了原质保条款,这些不是扫一眼语法树就能知道的。它需要业务理解,也需要受控规则。

3.2

   

先别被 71.5x 带偏

Graphify 项目里有一个很容易被传播的数字,叫 71.5x token reduction。这个数字看起来非常猛,但它的含义要说清楚。

它说的是,相比每次提问都把原始文件全部塞给模型,先用图谱和报告做结构化导航,可以减少查询时需要读的 token。这个结论在大代码库里是有意义的,因为你不可能每次问一个架构问题,都把整个仓库塞进上下文。

但这个数字不是准确率提升 71.5 倍,也不是企业知识库效果提升 71.5 倍。它只是说明,在某个代码基准里,用图谱导航比直接读全量原文更省上下文。

这个口径很重要。因为很多技术项目看起来很炸裂,实际落到企业知识库里,真正要问的是另外几个问题:它抽出来的关系准不准,能不能审计,能不能被业务人员理解,错了以后能不能修。

3.3

   

复现 httpx:图生成了,但不是我以为的那种代码关系图

我先按官方思路复现了 httpx。这里中间踩了一个小坑,值得单独说一下。

一开始我以为 graphify clone https://github.com/encode/httpx --out httpx 跑完以后,就会直接出现 graphify-out。实际上不是。这个命令只是把 GitHub 仓库 clone 到本地,真正生成图谱,还要让 Graphify 对这个目录跑一遍。

我这次在 Codex 里跑的时候,$graphify 这个环境入口没有挂上,所以最后走的是实际 CLI 入口,执行的是 graphify update .。跑完以后,确实生成了三个关键文件:

输出文件
作用
graphify-out/GRAPH_REPORT.md
图谱报告,适合先看
graphify-out/graph.html
交互式图谱,适合截图和点选
graphify-out/graph.json
原始图数据,适合后续程序读取

完整 httpx 仓库跑出来的数据是这样的:

指标
结果
文件数
60
节点数
1501
边数
6218
社区数
graph.json
 里是 37,报告 Summary 写的是 34
EXTRACTED 边占比
31%
INFERRED 边占比
69%

这个结果和官方 worked/httpx 小样例不是一回事。官方小样例是 6 个仿 httpx 架构的文件,结果大概是 144 个节点、330 条边、6 个社区。我们这次跑的是完整 encode/httpx 仓库,所以图一下子大了很多。还有一个小口径差异,graph.json 和 graph.html 里能看到 37 个社区,但 GRAPH_REPORT.md 的 Summary 写的是 34 个社区,后面引用数字时最好说清楚口径。

不过graph.html实际看下来不是我原来想象的那种清清楚楚的模块关系图,比如 Client 连到 Transport,Request 连到 Response,然后一眼能看懂 HTTPX 的架构。实际看到的是一团很密的网络,里面有源码节点,也有测试节点,还有不少 docstring 或属性说明被当成了节点。

从报告里看,最核心的节点是这些:

排名
节点
连接数
1
Response
326
2
Client
183
3
Request
167
4
URL
155
5
SyncByteStream
144
6
AsyncByteStream
144
7
Headers
126
8
codes
120
9
AsyncClient
116
10
MockTransport
111

所以这次复现的结论很简单:Graphify 能跑通,也能抓到 ClientResponseRequestURLHeaders 这些核心抽象,但它没有自动生成一张高质量架构图。对于完整代码库,真正有用的是 GRAPH_REPORT.md 里的核心节点和社区划分,graph.html 更像一个全量关系浏览器。

这也说明下一步不能继续拿全量图硬看。更合理的做法是先控制输入范围,比如只分析 httpx/ 源码目录,暂时排除 tests/ 和文档;或者在 graph.json 上做后处理,只保留核心节点的一跳邻居和高置信度边。换句话说,不是把这张 HTML 美化一下就行,而是要先把图的输入和过滤规则收敛掉。否则图再漂亮,本质上还是信息过载。

3.4

   

泛化性测试:RAG 入库质检工具包

为了避免只拿一个成熟开源库说事,我又跑了一下自己之前做的 RAG 入库质检工具包。这个工具包更接近我自己的工程场景,里面有 Python 后端、FastAPI 接口、扫描器、评分逻辑、报告生成,还有前端页面。

做了十几个知识库项目后,我把入库前的文档摸底流程产品化了

这次我没有直接全量跑整个目录。原因前面已经说过,项目根目录里有重复的前端 JS,还有样例导出 HTML 和缓存文件。如果全部丢进去,很容易又变成一张大而乱的图。所以第一轮只分析 run.pyrequirements.txtREADME.md 和 backend/,先看后端主干能不能被识别出来。

第一轮结果明显比 httpx 全量图清楚很多。

指标
第一轮结果
文件数
32
节点数
193
边数
403
报告里的有效社区
12
graph.html
 里的社区
21
EXTRACTED 边占比
59%
INFERRED 边占比
41%

从 GRAPH_REPORT.md 看,Graphify 第一轮抓到的主线是比较准的。ScanPipeline 是第一 god node,有 34 条边,这基本符合这个项目的真实结构。因为这个工具的核心就是扫描管线,入口、解析器、分析器、数据模型和导出逻辑都围着它转。

这个结果对我来说比 httpx 那张全量图更有参考价值。不是因为它更复杂,恰恰是因为它更受控。输入范围收敛以后,Graphify 确实能帮我快速复盘一个中小型代码工具的结构。它没有把所有关系都抓得很细,比如 FastAPI 的 include_router 关系、模板和导出函数之间的关系都偏弱,但它抓住了这个项目最重要的主干。

接着我又跑了第二轮,把 frontend/index.htmlfrontend/js/ 和 frontend/css/ 加进去,继续排除根目录重复 JS、js/ 目录、样例导出 HTML、缓存文件和 graphify-out。这轮的目的不是证明 Graphify 更强,而是看当前端加入以后,图谱还会不会保持可读。

两轮对比大概是这样:

指标
第一轮后端主干
第二轮加入前端
文件数
32
38
节点数
193
456
边数
403
703
graph.html
 原始社区
21
21
报告可见有效社区
12
12
EXTRACTED 边占比
59%
73%
INFERRED 边占比
41%
27%

第二轮的结论也比较清楚:图谱仍然可读,但 CSS 让图明显变宽了。frontend/css/style.css 生成了一个 217 个节点的 selector 社区,凝聚度只有 0.01。这个社区对理解业务逻辑帮助不大,更多是视觉噪声。

所以这两轮测试放在一起,结论就更清楚了:Graphify 在代码项目里不是没用,关键是要控制输入范围。后端主干、API、扫描管线、解析器、分析器这些关系,它抓得还可以;但 CSS、模板、重复前端文件这类东西很容易把图拉宽。它更像代码库摸底工具,不是能直接替代人理解系统设计的架构分析工具。

3.5

   

为什么这会影响后面的合同测试

httpx 这次复现给的提示是,Graphify 的图谱不能只看有没有生成,也不能只看节点和边多不多。节点多、边多、社区多,不等于更懂业务

在代码里,至少还有 import、class、function、call 这些相对确定的结构。即便全局图看起来很乱,我们仍然可以从报告里找到 ClientResponseRequest 这类核心抽象。

但合同不一样。合同里的关系不是函数调用,而是业务约束。主合同和补充协议之间是什么关系,验收单是否改变付款条件,延期是否触发违约责任,质保期到底按哪份文件执行,这些关系必须受控抽取,不能全靠模型自由发挥。

这就是后面我要继续跑 30 份水处理合同的原因。不是为了证明 Graphify 完全没用,而是要尝试厘清一件事:自动知识图谱在代码场景里有结构兜底,到了合同场景就必须有业务 schema 兜底。

3.6

   

先给一个阶段性判断

跑完 httpx 以后,我对 Graphify 的阶段性判断是这样的:

场景
关系性质
Graphify 的表现
代码库摸底
结构相对确定
可以帮忙找核心抽象,但全局图不一定好读
混合工程项目
后端、前端、配置混在一起
需要控制输入范围,否则容易信息过载
合同知识库
关系高度业务化
不能只靠自动抽取,需要受控 schema

换句话说,Graphify 值得看,但不能神化。它在代码场景里更像一个架构摸底工具,帮你知道从哪里开始读代码。放到合同场景里,它只能作为反例和启发,不能直接当生产方案。

4

   

合同知识库的正确架构:受控 schema + 工程化 RAG

前面跑完 LLM Wiki 和 Graphify,其实可以先得出一个中间判断:合同不是不能做图谱,问题是不能让图谱自由生成。

合同里的关系不是代码调用关系。它有业务含义,也有责任后果。主合同和补充协议是什么关系,验收单是否影响违约金,售后协议是否覆盖原来的质保条款,这些都不能只靠模型自己猜。合同知识库如果真要做成生产级系统,核心不是把图画出来,而是先把关系定义清楚。

4.1

   

合同图谱应该解决什么问题

个人判断是,合同图谱只适合解决那些跨文件、跨实体、跨时间的问题。单份合同里的金额、日期、甲乙方、付款节点,直接用结构化字段或者传统 RAG 就够了,没必要上来就做图谱。

真正需要图谱的是这些问题:

问题类型
是否适合图谱
原因
查某份合同的签订日期
不太需要
结构化字段就能解决
查某个项目有几份相关合同
适合
项目、主合同、补充协议、验收单之间有关系
查补充协议改了主合同哪些条款
适合
需要明确修改关系
查延期是否触发违约责任
适合
要同时看主合同、补充协议和验收单
查某客户历史项目里的高风险条款
适合
要跨合同聚合和归类
做一张全量合同关系大图
不建议
看起来信息很多,实际很难用于问答和审计

所以图谱在合同场景里的定位要收窄。它不是替代 RAG,也不是替代字段抽取,而是专门处理传统检索很难稳定回答的跨文档关系问题。

4.2

   

先定义业务 schema

如果要做合同图谱,第一步不是让 LLM 去抽关系,而是先定义业务 schema。也就是说,系统里允许出现哪些节点、哪些关系、哪些字段,先由业务和工程一起定下来。

比如接下来要演示的 30 份水处理合同里,节点类型可以先控制在这些范围内:

节点类型
说明
客户
甲方主体,可以继续扩展集团、子公司关系
项目
一个业务项目,下面可能有主合同、补充协议、验收单
合同
主合同、技术协议、补充协议、验收单、售后协议
条款
付款、违约金、质保、验收、售后等关键条款
风险事件
延期、免除违约金、质保延长、尚未验收等事件
设备
合同涉及的水处理设备或系统

关系类型也要控制住,不能让模型自由发明。

关系类型
示例
客户签署合同
A 客户签署 P-001 主合同
合同属于项目
P-001 主合同属于 P-001 项目
补充协议修改主合同
P-001-S1 修改 P-001 主合同
验收单对应项目
P-001-V 对应 P-001 项目
条款属于合同
违约金条款属于 P-001 主合同
风险事件关联合同
延期 45 天关联 P-001 验收单

这里最重要的是控制边界。LLM 可以参与抽取,但它只能按 schema 输出,不能自己决定什么节点重要、什么关系成立。否则图谱会很快变成一堆看起来有关、但业务上不能直接使用的关系。

4.3

   

抽取方式要可复核

落地实操阶段,我一般是把合同处理拆成三步。

第一步是结构化字段抽取。先把合同编号、客户、项目、金额、签订日期、付款节点、质保期、违约金、验收状态这些字段抽出来,存到数据库里。这一步能解决大量简单查询。

第二步是条款级切分和索引。合同不要按固定字数切块,而是尽量按条款切。后面用户问付款、质保、违约金、验收,都应该能引用到具体条款,而不是只返回一段上下文。

第三步才是按 schema 建关系。比如补充协议修改哪份主合同,验收单对应哪个项目,延期是否关联违约金条款。这一步每条关系都要保留来源文件、条款位置和置信度,方便后面审计和人工抽检。

简单说,不是先做图,再让人理解图。应该是先定义业务关系,再让模型按规则抽取,最后把抽取结果变成可查询、可审计的数据。

4.4

   

一个够用的工程架构

如果只讲一个最小可落地版本,我会把合同知识库拆成五层。

层级
作用
关键要求
文件解析
解析 Word、PDF、扫描件、表格
保留页码、标题、表格位置
合同结构化
抽取合同编号、客户、金额、日期、付款、质保、违约金
字段固定,结果入库
条款索引和受控图谱
条款级 chunk、metadata、schema 关系
关系必须有来源
问答层
权限过滤、条件筛选、混合检索、答案生成
答案必须引用原文
评测与审计
测试集、引用检查、权限检查、人工复核
用结果反推系统问题

这五层里,图谱只在第三层发挥作用。它不是整个系统的中心,也不应该替代解析、结构化、检索和评测。合同知识库的稳定性,往往来自这些基础工程的组合,而不是某一个单独技术。

4.5

   

四个需要点明的工程障碍

把 LLM Wiki 或 Graphify 这类工具直接搬到企业合同库里,目前阶段性实测发现主要会遇到四个工程障碍。

第一个是成本。合同越多,预编译、抽取、更新、复核的成本越高。不能每次新增一份合同,就无差别生成大量页面和关系。

第二个是可控性。合同关系必须按业务 schema 抽取,不能让模型自由生成。否则后面问答时很难判断一条关系到底能不能作为依据。

第三个是权限。合同天然有客户、部门、项目、角色的权限边界。知识库不是只要能答对,还要保证不该看的合同绝对不能被召回。

第四个是合规和审计。企业合同问答不能只给一个看起来合理的答案,还要能回到原文,能解释引用了哪份合同、哪一条款、哪一个字段。

所以这里的核心判断很简单:企业合同知识库可以借鉴 LLM Wiki 的知识预编译思路,也可以借鉴 Graphify 的结构化导航思路,但不能照搬它们的自由生成方式。生产级方案一定要回到受控 schema、结构化字段、条款级引用、权限过滤和评测审计。

接下来我会用这 30 份合成合同和 48 个测试问题,把基础 RAG、LLM Wiki 思路和受控 schema 综合方案放在同一套问题下对比。只有跑完这些问题,才能看清楚哪些能力是真的有用,哪些只是看起来完整。

5

   

3 种方案 × 30 份合同 × 48 个问题的实测对比

5.1

   

实验设计

前面讲了这么多方案,真正要比较的时候还是要回到同一套问题上。这里我不打算把实验设计搞得特别复杂,核心目标就一个:用 30 份合同和 48 个问题,看不同方案在合同知识库里到底差在哪里。

数据集还是前面那套水处理设备合同样本,一共 9 个项目、30 份 Markdown 合同文件。里面包括主合同、技术协议、补充协议、验收单和售后协议。所有客户名、地点、金额、合同编号都是合成数据,不对应任何真实客户。完整文件在 samples/contracts/,元数据在 samples/合同元数据.csv,测试问题在 samples/测试问题集.jsonl

这次测试问题分成两层。第一层是 24 个核心问题,用来快速判断一个方案有没有跑通。第二层是完整 48 个问题,用来做更细的对比。这样做的好处是,开发阶段不用每次都跑完整集,等方案稳定以后再跑全量。

问题集
数量
用途
核心集
24
快速验证流程是否跑通
完整集
48
做最终对比和 Bad Case 分析

问题类型也不追求面面俱到,而是围绕合同知识库最容易出错的几类问题设计。

类型
主要考察什么
单点事实
合同金额、签订日期、客户名称、质保期
条件筛选
按客户类型、项目类型、文档类型筛选
跨合同综合
同一项目下主合同、补充协议、验收单一起看
主补关系
补充协议修改了什么,是否影响金额、工期、范围
风险识别
延期、违约金、质保延长、尚未验收
统计汇总
按行业、年份、项目状态做简单聚合

评测也分两层。第一层是检索有没有找对材料,第二层是答案有没有说对。因为合同问答不能只看最终回答,很多时候答案错不是模型生成错,而是前面召回材料就错了。

指标
说明
Recall@5
标准答案对应的合同或条款是否出现在前 5 个召回结果里
Answer Accuracy
最终答案是否和标准答案一致
Citation Accuracy
引用的文件名、条款或片段是否支持答案
Multi-doc Accuracy
跨主合同、补充协议、验收单的问题是否答对
Cost / Time
建库、检索、生成分别消耗多少时间和 token

这里我暂时不会把 RAGAS 当成主评测工具。RAGAS 适合做辅助观察,但这次我们有自己设计的标准问题和标准答案,直接按标准答案、证据文档、证据条款来评更可控。后面如果需要,可以再加一个 LLM judge 做语义一致性判断,但主口径还是这套人工可解释的指标。

这轮实验也刻意不追求大而全。我的重点不是证明某个框架最好,而是看清楚三类方案在同一批合同上各自会卡在哪里。

5.2

   

方案 A:基础向量 RAG(baseline)

第一轮先跑基础向量 RAG。这里我没有故意做得很差,分块也没有用最粗糙的 512 字符固定切分,而是用了更接近实际项目的层级父子分块。

实现口径大致如下:

环节
做法
文档范围
samples/contracts/
 下 30 份 Markdown 合同
分块方式
Markdown 标题层级作为 parent chunk,再切 child chunk
向量库
本地 ChromaDB
Embedding
SiliconFlow 上的 Qwen/Qwen3-Embedding-4B
检索
先召回 child chunk,再回填 parent chunk
生成
用 .env 里配置的问答模型生成答案
评测
24 个核心问题,使用标准答案、期望文档和 LLM judge

这轮一共生成了 313 个 parent chunk 和 331 个 child chunk。注意,这里只索引了 30 份合同正文,没有把 合同元数据.csv 当作结构化外挂知识源接入。这个口径很重要,因为后面的很多失败样本正好和这个有关。

核心 24 题的结果如下:

指标
结果
Recall@5 文档命中
11/24,45.8%
Answer Accuracy
6/24,25.0%
Citation Accuracy
9/24,37.5%

按问题类型拆开看,差异就更明显了。

类型
数量
Recall@5
答案准确
引用准确
simple_fact
5
100.0%
100.0%
100.0%
field_filter
5
20.0%
0.0%
0.0%
cross_contract
4
0.0%
0.0%
0.0%
main_supplement
3
100.0%
33.3%
100.0%
relation_reasoning
3
33.3%
0.0%
33.3%
risk_identification
2
50.0%
0.0%
0.0%
cross_field
2
0.0%
0.0%
0.0%

这个结果其实挺有代表性。简单事实题全对,说明层级父子分块对单份合同里的局部问题是有效的。比如问 P-005 主合同金额、P-004 质保期、P-006 违约金条款,这类问题只要召回到正确条款,模型基本能答出来。

但一到全局清单、跨合同统计、主补关系和风险归因,基础 RAG 就明显吃力。比如问哪些项目属于市政类项目,模型只答出了两个,漏掉了 P-005 自来水厂项目。问工业客户项目的主合同总金额,模型直接说无法确认,因为上下文里没有稳定召回客户类型和所有金额。问 P-009 两份补充协议分别修改了什么,虽然引用文档找对了,但答案没有完整抽出 S1 和 S2 的修改内容。

这说明一个很现实的问题:只靠向量召回,很难稳定回答需要全局视角的问题。 它能在局部条款上表现不错,但不擅长做全局清单、跨文件聚合和业务关系推理。

所以方案 A 的结论很明确。它不是完全不能用,它适合作为 baseline,也适合解决单份合同里的局部事实题。但如果企业合同知识库只做到这一步,用户一问跨项目、跨合同、主补协议、验收状态,系统就会开始不稳定。

5.3

   

方案 B:LLM Wiki 模式(5 份样本估算 + 全量推算)

方案 B 我没有做 30 份合同全量 ingest,而是做了一个小样本验证。原因前面也讲过,LLM Wiki 的重点不是再做一个向量检索系统,而是验证知识预编译这件事到底有没有价值。

测试目录是 llm-wiki-demo/。里面有 5 份原始合同,分别覆盖 P-001 和 P-004 两个项目:

项目
原始合同
P-001
主合同、补充协议、验收单
P-004
主合同、售后服务协议

Wiki 侧一共生成了 20 个页面,包括 source summary、project page、clause page、entity page 和 synthesis page。最有代表性的两篇综合页是:

wiki/synthesis/P-001 延期但免违约金分析.md

wiki/synthesis/P-004 质保延长与售后服务分析.md

我单独建了一个小评测集,一共 10 题。其中 6 题来自原来的 48 题,都是和 P-001、P-004 相关的问题;另外补了 4 个 synthesis 问题,专门考它能不能利用项目页和综合页回答跨文档问题。

问题来源
数量
说明
原 48 题中 P-001 / P-004 相关问题
6
覆盖简单事实、主补关系、风险识别
新增 synthesis 问题
4
专门测试 Wiki 综合页效果
合计
10
只在 5 份 demo 合同范围内评测

实现上也很简单。方案 B 不用 ChromaDB,也不再临时做向量召回,而是让模型优先读取 wiki/index.md、项目页、条款页、source summary 和 synthesis page,然后回答问题。这个过程更接近 LLM Wiki 的原始思路:资料进入时先编译成 Wiki,问答时先读 Wiki。

这 10 题的结果如下:

指标
结果
Answer Accuracy
10/10,100.0%
Citation Accuracy
10/10,100.0%

按问题类型拆开看:

类型
数量
答案准确
引用准确
simple_fact
3
100.0%
100.0%
main_supplement
1
100.0%
100.0%
relation_reasoning
1
100.0%
100.0%
risk_identification
1
100.0%
100.0%
synthesis
4
100.0%
100.0%

这个结果看起来很好,但要注意口径。它不是说 LLM Wiki 在 30 份合同、48 题上全面超过方案 A。它说明的是,在小范围、已预编译的 Wiki 里,跨文档综合问题确实会变简单。

比如 P-001 的问题,如果用基础 RAG,模型需要临时召回主合同、补充协议、验收单,再自己拼出链路。LLM Wiki 里已经提前有项目页和 P-001 延期但免违约金分析,所以回答时不需要重新找齐所有碎片。P-004 也是一样,36 个月质保、质保后 3 年售后服务、年度服务费、SLA 这些信息已经被整理到项目页、条款页和综合页里。

这就是 LLM Wiki 最有价值的地方:它把一部分高频复杂问题提前整理好了。

但它的问题也同样明显。Wiki 页面是模型加工后的二级知识,虽然页面里保留了 source 文件名,但它不是严格的 chunk 级原文引用。对个人知识库来说,这样很方便;对企业合同知识库来说,后面还要面对权限、审计、更新、责任归因这些问题。

所以方案 B 的结论不是直接上 LLM Wiki,而是保留它的知识预编译思路。也就是说,高频复杂问题可以提前整理成综合页,但生产级系统里还要补上结构化字段、受控关系和原文引用。

5.4

   

方案 C:受控 schema + 关系表 + 原文索引

方案 C 这一步,我没有再换一个新的图谱工具,也没有继续把所有问题都交给向量库。前面方案 A 已经说明了一个问题:如果问题本身是在问全局筛选、统计、主补关系、风险识别,那向量召回很容易把范围找错。它可以找到相似片段,但不擅长稳定回答哪几个项目满足条件、哪些合同之间有关系、哪些条款超过标准模板。

所以方案 C 的做法是先把合同里应该结构化的东西结构化。这里直接读取前面那份 合同元数据.csv,生成一个 SQLite 数据库。数据库里有合同表、项目表、项目文档表、合同关系表、补充协议变更表和风险事件表。这样一来,合同金额、客户类型、行业、质保期、违约金比例、是否有技术协议、是否有验收单、补充协议改了什么,就不再靠模型临时判断,而是先进入受控字段。

这里仍然复用了方案 A 的 ChromaDB。方案 A 里已经把 30 份 Markdown 合同做了父子分块,并生成了 331 个 child chunks。到了方案 C,这个向量库不再负责决定全局范围,而是作为原文索引和引用补充。也就是说,先用 SQLite 和关系表把范围定下来,再需要回看原文时,才让向量库发挥作用。

本轮方案 C 生成的数据库情况是这样:

行数
contracts
30
projects
9
project_documents
30
contract_relations
21
risk_events
8
supplement_changes
8

这 8 条风险事件,主要覆盖了违约金加严、质保期超过标准、延期但免除违约金、延期并扣款、GMP 验证风险这些合同知识库里很常见的问题。它们不是为了展示图谱有多复杂,而是为了让系统在问到风险类问题时,能有明确的结构化入口。

然后我用方案 C 跑了核心 24 题,结果如下:

指标
结果
Answer Accuracy
24/24,100.0%
Citation Accuracy
24/24,100.0%

按问题类型拆开看:

类型
数量
答案准确
引用准确
simple_fact
5
100.0%
100.0%
field_filter
5
100.0%
100.0%
cross_contract
4
100.0%
100.0%
cross_field
2
100.0%
100.0%
main_supplement
3
100.0%
100.0%
relation_reasoning
3
100.0%
100.0%
risk_identification
2
100.0%
100.0%

不过这个结果要和各位讲清楚口径,它不是说方案 C 对任何合同问题都能 100% 正确,而是说在这 24 个核心问题里,绝大多数问题本来就应该通过结构化字段和关系表解决。比如哪些项目属于市政类项目、工业客户项目总金额是多少、哪些项目签有技术协议、哪些补充协议涉及金额变更、哪些合同的违约金条款更严格,这些问题如果还让模型从一堆 chunk 里猜,效果就会很不稳定。

所以方案 C 的价值不在于把技术堆得更复杂,而在于把问题分工讲清楚。结构化字段负责筛选和统计,关系表负责主合同、补充协议、技术协议、验收单、售后协议之间的关系,风险事件表负责提前标出高风险条款,向量库负责回到原文,模型负责最后组织答案。

这也是我认为更接近企业级合同知识库的做法。能用规则和数据表确定的事情,就不要让模型猜;需要模型发挥的地方,放在答案组织、解释和引用整合上。

5.5

   

三种方案放在一起看

为了更清晰的对比,这里我再把三种方案放在同一张表里。不过需要说明的是,方案 B 是 5 份合同的小样本 Wiki 测试,不能和方案 A、方案 C 的 30 份合同核心 24 题做完全等价比较。它的作用是证明预编译 Wiki 对跨文档综合问题确实有帮助。

维度
方案 A 基础 RAG
方案 B LLM Wiki 
方案 C  综合方案
测试口径
30 份合同,24 题
5 份 demo,10 题
30 份合同,24 题
Answer Accuracy
6/24,25.0%
10/10,100.0%
24/24,100.0%
Citation Accuracy
9/24,37.5%
10/10,100.0%
24/24,100.0%
Recall@5
11/24,45.8%
不适用
结构化入口,不按 Recall@5 评价
主要价值
局部事实题
预编译综合页
全局筛选、统计、关系推理、原文引用
主要限制
全局问题不稳定
不是全量生产方案
需要维护 schema 和结构化表

这个对比其实很直观。基础 RAG 在简单事实题上可以用,但一遇到全局统计和跨合同关系,就会明显费劲。LLM Wiki 在小范围内表现很好,尤其适合提前整理高频复杂问题,但它不是直接可上生产的全量方案。方案 C 这次效果最好,是因为它把合同知识库里最该受控的部分先做了工程设计。

换句话说,合同知识库不是只看模型能力,也不是只看向量库效果。真正影响结果的是,哪些信息应该进表,哪些关系应该显式建出来,哪些问题应该用检索回答,哪些问题应该提前沉淀成综合页。这个边界划清楚之后,后面的问答准确率才会稳定。

5.6

   

LLM Wiki 思路的降维用法:高频问题预编译综合页

跑完这三组实验以后,相信各位对 LLM Wiki 的看法其实更清楚了。

比如合同场景里,用户经常问的问题其实服从二八原则。这个项目的补充协议改了什么,这个客户的违约金条款严不严格,这个项目为什么延期但没有扣违约金,哪些项目的质保期超过标准,哪些项目还没有验收单。这些问题不是每次都应该临时从 30 份合同里召回、拼接、推理一遍。

如果这些问题已经在业务上反复出现,就应该提前生成一页综合说明。综合说明里可以把主合同、补充协议、技术协议、验收单、售后协议之间的关系先整理好,再把引用来源挂清楚。用户问的时候,系统先看有没有对应的综合页。如果有,就优先用综合页回答,同时回链到原文合同和结构化字段。

这就是我说的降维用法。不是把所有文档都编译成 Wiki,也不是把 LLM Wiki 当成最终知识库,而是把它当成工程化 RAG 里的一个辅助层。

个人知识库里,Wiki 页面写得顺就可以了。企业知识库里不行。综合页必须有来源,最好还能指回原始合同、条款位置、结构化字段和生成时间。否则这页内容越像答案,风险越大。因为一旦它说错了,用户很难判断错在原合同、错在抽取、还是错在模型总结。

所以企业版的做法应该是这样:

环节
做什么
触发条件
某类问题反复出现,或者属于明确的风控、统计、主补关系问题
生成方式
LLM 生成初稿,再经过规则检查或人工抽查
引用规则
每个关键结论都要能指回原始合同或结构化字段
更新机制
原文合同、结构化字段或风险事件变化后,综合页需要重新生成
使用方式
优先作为回答素材,不直接替代原文和数据库

这样处理以后,LLM Wiki 的价值就比较清楚了。它不是生产知识库的全部,而是把高频复杂问题提前整理好,让系统不要每次都从零开始推理。

原版 LLM Wiki 和企业级降维版的差异,大概可以这样对比:

维度
原版 LLM Wiki
企业级降维版
编译范围
更偏全量 source
只处理高频复杂问题
主要目标
让个人更快理解资料
让企业问答更稳定可追溯
生成方式
Agent 自动生成为主
LLM 初稿加规则校验,必要时人工复核
引用要求
source 文件名基本够用
必须能回到原文合同和结构化字段
更新方式
更偏个人维护
跟随合同、字段、风险事件变更
适用规模
小型资料库更舒服
可以作为企业 RAG 的一个辅助层

说白了,Karpathy 给的是个人知识库里的知识编译思路。而所谓企业级知识库要做的不是照搬工具链,而是把知识编译这个环节拆出来,放到企业知识库的工程流程里。前面有结构化字段和关系表,后面有原文引用和评测,中间再放一层高频综合页,这样它才是可控的。

6

   

写在最后

6.1

   

三个 gap:从好看到能用,再到好用

第一个 gap,是从好看到能用。LLM Wiki 和 Graphify 都很容易做出让人眼前一亮的效果,一个能把资料整理成 Wiki,一个能把代码库画成图。但企业项目不看第一眼好不好看,最终看的是权限、引用、审计、更新、评测这些东西能不能跟上。

第二个 gap,是从能用到好用。基础 RAG 不是不能用,简单事实题也能答,但一遇到跨合同、全局统计、主补关系和风险识别,就很容易不稳。方案 C 的核心不是换了一个更大的模型,而是把该进表的字段进表,该显式表达的关系显式表达,该回到原文的地方回到原文。

第三个 gap,是从模型能力到业务结果。现在的大模型通用能力已经很强,真正卡住的往往不是模型完全不会,而是业务问题没有被拆清楚,数据结构没有搭好,评测闭环没有建立。把这三个 gap 补上,AI 才能从演示里的效果,变成业务流程里能承担责任的系统。

6.2

   

从追新到工程主义

过去几年,大模型领域的概念换得很快。23 年大家追 LangChain、LlamaIndex 和最早一批 RAG 框架,24 年开始追 dify、RAGFlow,25 年下半年又是 Coding Agent、MCP、GraphRAG,到了 2026 年开年,LLM Wiki 又把知识预编译这个思路推到台前。每一个概念出来,都容易让人觉得不跟就落后。

但做企业项目多了以后,我越来越觉得,真正重要的不是追到最新,而是把大模型的通用能力变成垂直场景里的稳定能力。模型负责理解、推理、生成和工具调用,但它不是业务系统。合同知识库要回答得准,还需要合同字段、项目关系、风险事件、原文引用和评测体系。工控知识库、售前报价、工业质检也是一样,底层都是把通用能力接到具体业务对象上。

所以我说的工程主义,不是少用模型,也不是把系统做得很重,而是让模型在正确的位置发挥作用。能用结构化字段解决的,不交给向量召回猜;能用关系表确定的,不交给模型临时拼;需要语言表达、综合解释和人机交互的地方,再让模型上。这样做出来的系统可能没有 demo 那么炫,但它更接近企业真正愿意用的东西。

6.3

   

复现资料说明

这篇文章里的完整测试数据和脚本我已经发布在了知识星球和视频课程中,包括 30 份合成合同 Markdown、合同元数据 CSV、48 个测试问题和标准答案,以及方案 A、方案 B、方案 C 的实现代码和评测结果说明。这里最有价值的不是某一段代码,而是从数据设计、问题设计、方案对比到结果评测的完整过程。

如果你只是想看思路,看这篇文章基本够了。如果你想自己跑一遍,就按 A、B、C 三个方案复现一遍。真正跑完以后,为什么基础 RAG 会在全局问题上掉链子,为什么 Wiki 综合页对小样本有效,为什么方案 C 要先做结构化字段和关系表,这些问题会非常直观。

如果你也在做类似项目,欢迎找我交流。

加入知识星球限时赠送视频课程和书

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询