给 AI Agent 装个“项目知识大脑“:ProjQA 技能开发笔记
给 AI Agent 装个"项目知识大脑":ProjQA 技能开发笔记
文档散落各处、排障靠口口相传、新人问完老人再问——这些场景每个技术团队都不陌生。本文记录了 ProjQA 技能从零到开源的完整开发过程:一个 Python 脚本 + LLM,不部署任何后端,不引入向量模型,让 AI Agent 直接基于本地项目文档回答运维问题。
一、谁都遇到过的困境
如果你在一个有几十个微服务的技术团队待过,以下场景大概率不陌生:
- 某个服务线上报错,翻遍 wiki、共享盘、个人电脑,找不到对应的排障文档
- 上周刚解决过同样的问题,但当时是群里口述处理的,没人记下来
- 某服务的部署文档存在某个离职同事的电脑里,他走了,知识也走了
- 新人入职,同样的部署流程、同样的注意事项,每来一波人就要讲一遍
- 知道有篇文档讲过这个问题的解决方案,但就是想不起来在哪个目录、叫什么名字
文档不是没有,而是散落在各处、没有统一检索入口、无法快速抵达。
很多人第一反应是上 RAG:搞个 Embedding 模型 + 向量数据库 + 检索后端。但真动手会发现——国内网络拉模型镜像慢、依赖安装各种报错、向量库还要单独部署维护。更关键的是,团队的文档量可能也就几十到上百个文件,用整套向量检索方案杀鸡用牛刀了。
于是问题变成了:能不能让 AI Agent 直接读本地文档回答问题,不部署任何后端,不引入向量模型?
这就是 ProjQA 的起点。
二、核心设计原则:三个"零"
动手之前,先定下三条原则,它们贯穿了整个开发过程:
原则一:零后端
不部署任何服务。不需要数据库,不需要 API 网关。一个 Python 脚本 + LLM 自身能力,就够了。
这不是偏执,而是务实。我们要的不是一个知识库"系统",而是一个即插即用的"技能"——把它丢给 Agent,它就能干活。不需要运维同学帮忙部署,不需要申请服务器资源,不需要担心某天服务挂了知识库就不可用。
原则二:零向量模型
不用 Embedding,不用向量数据库,不用相似度计算。
传统 RAG 的检索链路是:文档 → 切块 → Embedding → 向量存储 → Query Embedding → 向量相似度 → 取 Top-K。这条链路需要模型、需要数据库、需要 API 调用。
替代方案是:文件系统索引 + LLM 语义匹配。脚本扫描文件生成索引(关键词、简述、提问摘要由 LLM 补充),检索时 LLM 直接读索引匹配候选文档,再读文档内容回答。
你可能会问:在上下文里塞关键词做匹配,精度能比向量检索?
对于中小规模文档库(百级以下),LLM 的语义理解能力远超向量相似度。向量检索只能算"词面相近",而 LLM 能理解"订单服务"和 order-service 是同一个东西(配合别名映射),能理解"起不来"等于"启动失败"。这是质的区别。
原则三:智能体即 LLM
所有需要"理解"和"判断"的环节都由 LLM 完成,脚本只做确定性操作。
| 环节 | 执行者 | 为什么 |
|---|---|---|
| 文件扫描与增量比对 | Python 脚本 | 确定性操作,比 mtime/size,不需要理解力 |
| 关键词/简述/提问摘要生成 | LLM | 需要理解文档内容才能生成 |
| 别名映射 | LLM | 需要理解用户意图和映射关系 |
| 候选文档匹配 | LLM | 需要语义理解能力 |
| 回答生成 | LLM | 核心价值所在 |
脚本不做任何"智能"判断,只管文件系统的脏活累活。LLM 不碰文件系统细节,只管理解、匹配、回答。分工清晰,各自做最擅长的事。
三、第一版:跑通最小闭环
第一版只做了三件事:
1. 一个目录结构——按项目分类组织文档:
projqa-docs/
├── 电商平台/
│ ├── FAQ/ # 常见问题与解决方案
│ ├── 运维手册/ # 部署、运维、排障流程
│ ├── 服务资料/ # 单个服务的信息档案
│ ├── 架构设计/ # 系统架构、技术方案
│ └── 会议纪要/ # 决策记录
├── _index.md # 索引文件(脚本自动维护)
└── _aliases.md # 别名映射表(人工维护)
2. 一个扫描脚本(scan_projqa.py)——递归扫描文档目录,比对文件 mtime/size 做增量更新,生成索引文件。索引条目格式:
- [电商平台/服务资料/服务清单.md] | 关键词: 订单, 支付, 库存, K8S, 副本数 | 简述: 全部微服务信息档案 | 提问摘要: 有哪些服务? 某服务几个副本? | mtime: 2026-08-27 10:00:00 | size: 8192
脚本只负责结构维护和增量检测,关键词、简述、提问摘要这些语义字段留空,交给 LLM 在入库时补充。
3. 一份技能指令(SKILL.md)——告诉 Agent 怎么用这个知识库:先查别名映射,再扫索引匹配候选,读取文档,生成带来源标注的回答。
第一版跑通了基本闭环:放文档 → 跑脚本 → LLM 补充语义信息 → 用户提问 → Agent 检索回答。但实际用了几天就发现一堆问题。
四、第二轮迭代:从"能用"到"好用"
问题 1:用户说的是"订单服务",索引里写的是 order-service
用户提问不会用标准服务名,他们说"订单服务"“库存”"支付网关"这些业务称呼。直接拿这些词去匹配索引,命中率很低。
以电商中台为例,团队内部讨论用中文名,代码和配置里是英文服务名:
订单服务 -> order-service
库存中心 -> inventory-center
支付网关 -> payment-gateway
商品中心 -> product-center
用户中台 -> user-platform
解法:别名映射表(_aliases.md)
建一个人工维护的映射表,检索前必查。这个表格随用随补,发现新的口语称呼就加一条,渐渐的命中率越来越高。
问题 2:文档多了之后,关键词匹配不够用
文档从十几个涨到几十个后,单纯靠关键词匹配开始出现"候选太多、不确定读哪个"的尴尬。
比如有人问"支付服务超时怎么排查",索引里关键词包含"支付"的文档可能有四五篇——支付接入文档、支付网关部署手册、支付超时排障记录、支付对账说明。关键词都能命中,但只有第三篇是真正相关的。
解法:提问摘要字段
入库时除了关键词和简述,再生成 2-3 个"提问式描述":
提问摘要: 支付超时怎么排查? 支付网关连接池怎么调? §排障步骤: 超时链路分析
这种格式直接描述"这篇文档能回答什么问题",检索时 LLM 拿用户提问去匹配这些提问摘要,命中即高度相关。效果立竿见影,候选文档的精准度大幅提升。
问题 3:大文档全文读入太慢
有些运维手册几百行,Agent 一次性全文读取既慢又浪费上下文窗口。
解法:大文档分章节索引
入库时对大文档追加章节定位信息:
提问摘要: §部署步骤: 怎么部署? §环境变量: 需要配置什么? §常见故障: 启动失败/超时/内存溢出怎么处理?
检索时 LLM 先通过提问摘要定位到具体章节,再只读该章节的行号范围。500 行的文档可能只需要读 30 行。
问题 4:重复入库
同一个人写了个新文档放进来,和已有文档内容高度重叠,文件名略有不同。
比如已有 电商平台/FAQ/支付超时.md,又来一个 电商平台/FAQ/支付网关超时排查.md——内容差不多,只是标题不同。
解法:相似检测
扫描脚本增加 --check-similarity 参数,对新增文档与已有文档做文件名相似度比对,相似度 ≥60% 时提醒:
--- 相似文件提醒(可能重复)---
~[82%] 电商平台/FAQ/支付网关超时排查.md <--> 电商平台/FAQ/支付超时.md
最终是否重复仍由 LLM 读内容判断,脚本只做辅助提醒。
问题 5:补录质量不可控
入库流程要求 LLM 补充关键词/简述/提问摘要,但实际操作中有时会遗漏——补了关键词忘了简述,或者提问摘要没写就提交了。索引里出现大量空字段,检索效果直线下滑。
解法:分级待补清单 + 闭环校验
扫描脚本输出分级清单:
--- 待补[P0] 关键词/简述为空: 2 个文件(必须完成)---
!! 电商平台/FAQ/支付回调.md
!! 电商平台/运维手册/灰度发布.md
--- 待补[P1] 提问摘要为空: 1 个文件(增强检索)---
? 电商平台/服务资料/商品中心.md
P0(关键词/简述为空)必须完成,P1(提问摘要为空)建议完成。补完后重新跑脚本,确认输出"待补清单: 无"才算入库完成。形成了「扫描 → 补录 → 再扫描验证」的闭环。
五、第三轮迭代:多项目组织与开源准备
多项目知识库
最初所有文档混在一个目录里。随着项目增多到两三个,跨项目误命中越来越频繁——搜"用户服务"本意是找中台的用户中心,结果命中了电商平台的用户模块。
于是改为按项目分类:
projqa-docs/
├── 电商平台/
│ ├── FAQ/
│ ├── 服务资料/
│ └── 运维手册/
├── 技术中台/
│ ├── 架构设计/
│ └── 会议纪要/
├── _index.md
└── _aliases.md
第一级是项目名,第二级是分类名。索引统一在一份 _index.md 中,但路径包含项目名前缀,天然隔离。这个改动几乎零成本,但检索准确率提升明显。
从私有到开源
确定开源后,做了三件事:
1. 移除所有平台专有内容
原始版本绑定在特定 Agent 平台上,引用了平台专有技能名。开源版全部改为通用描述——"使用平台的 Word 文档解析能力"而非指定具体技能名,让任何 Agent 平台都能适配。
2. 路径通用化
所有硬编码的绝对路径改为相对路径 ./projqa-docs,并保留环境变量 PROJQA_DOCS_ROOT 覆盖机制。clone 下来就能跑,不依赖特定目录结构。
3. 补齐开源基建
README、CHANGELOG、CONTRIBUTING、架构文档、快速上手教程、索引/别名模板——让新人拿到手就知道怎么用。
六、关键设计决策回顾
回头看,有几个决策对最终效果影响最大:
决策 1:索引是文件系统快照,不是语义存储
索引脚本只比对 mtime/size,不读文件内容。语义信息(关键词/简述/提问摘要)由 LLM 在入库时补充,脚本只负责把结构维护好。
好处是脚本极其轻量和确定——不怕出 bug,不怕性能问题,上千文件也秒级扫描完。坏处是初次入库需要 LLM 参与补充语义信息。但这个 trade-off 是值得的:脚本做的事情越少越可靠,智能判断交给 LLM 越灵活。
决策 2:不引入向量模型,坚持到开源
开发过程中这个决策被反复质疑。“要不要加个 Embedding 做兜底?”"文档多了要不要上向量检索?"最后的答案是:不要。一旦引入向量模型,零后端的设计原则就被打破了,技能的即插即用性也没了。对于百级以下的文档库,LLM 的语义匹配能力完全够用。
决策 3:按项目分类而非按类型分类
最初文档按类型组织(所有 FAQ 在一起、所有运维手册在一起)。改为按项目组织后,跨项目误命中问题自然消失了。改动成本几乎为零(只是多一层目录前缀),但收益很大。
七、最终形态
项目结构:
projqa-skill/
├── SKILL.md # 技能主文件(Agent 读取的核心指令)
├── references/
│ └── retrieval-guide.md # 检索策略详细指南
├── scripts/
│ └── scan_projqa.py # 索引扫描与增量维护脚本
├── docs/
│ ├── architecture.md # 架构设计文档
│ └── quick-start.md # 快速上手教程
├── examples/
│ ├── _index.example.md # 索引文件模板
│ └── _aliases.example.md # 别名映射表模板
├── README.md
├── .gitignore
├── CHANGELOG.md
└── CONTRIBUTING.md
核心工作流程:
用户提问
→ 查别名映射(_aliases.md):口语称呼 → 标准服务名
→ 扫描索引(_index.md):关键词/简述/提问摘要 → 候选文档
→ 读取候选文档:按格式选择解析方式
→ LLM 综合内容生成回答 + 来源标注
入库流程:
放文档到目录
→ 运行 scan_projqa.py --check-similarity
→ 根据待补清单补充关键词/简述/提问摘要
→ 再跑脚本确认"待补清单: 无"
八、写在最后
ProjQA 不复杂——一个 Python 脚本、一份技能指令、一份检索策略指南,三个文件就是全部核心。它的价值不在于技术多精妙,而在于找到了一个恰到好处的平衡点:
- 比人肉翻文档快——几秒内定位到答案
- 比传统 RAG 轻——零部署、零运维
- 比口口相传可靠——答案有来源标注,可追溯
它适合的规模是百级以下的文档库,适合的场景是项目运维知识管理。如果你的团队也在被"信息散落、排障靠问人"困扰,ProjQA 可能就是那个最小够用的解。
更多推荐


所有评论(0)