它能写一个 FastAPI 接口,能解释一段 SQL,也能帮你重构函数。但一旦问题变成:
“这个报错为什么只在线上出现?”“这个接口改了会影响哪些模块?”“这个需求当初为什么这么设计?”
普通 AI 很容易开始猜。
原因很简单:它没有项目上下文。代码仓库、设计文档、错误日志、Issue 讨论,这些信息散在不同地方。AI 如果看不到,只能凭通用经验回答。
所以,很多团队现在开始做一件事:给 AI 编程助手接一个“第二大脑”。
不一定要很重。用 Python 搭一个轻量 RAG 工作流,就能先跑起来。
一、RAG 在编程场景里到底解决什么
RAG,全称 Retrieval-Augmented Generation,简单说就是:
先从你的资料里找相关内容,再把这些内容交给大模型回答。
放到研发场景里,它要接的不是百科知识,而是项目自己的材料:
这件事的价值不在于“让 AI 更聪明”,而是让它少胡说。
一个没有上下文的 AI,像刚入职第一天的高级工程师;一个接了项目资料的 AI,至少像看过文档、翻过日志、跑过仓库的同事。
二、最小可用架构
轻量版本不用上复杂平台,Python 就够了。
基本流程是四步:
收集资料 → 切分文本 → 向量索引 → 检索问答可以这样选型:
如果只是团队内部工具,我建议先用 Chroma 或 FAISS。别一上来就搞一套复杂知识库系统,容易把时间花在工程架子上,真正的问答质量反而没人调。
三、先把资料接进来
第一步是扫描项目目录,把有价值的文件读出来。
比如只索引这些类型:
from pathlib import PathROOT = Path("./my_project")EXTS = {".py", ".md", ".txt", ".log", ".yaml", ".yml"}docs = []for path in ROOT.rglob("*"):if path.suffix in EXTS and".git"notin path.parts: text = path.read_text(encoding="utf-8", errors="ignore") docs.append({"path": str(path),"text": text })这里有个小经验:不要无脑把整个仓库塞进去。
先排除这些内容:
node_modules/.venv/dist/build/.git/大体积数据文件自动生成文件否则检索结果会很脏,模型会被无关内容带偏。
四、代码和文档的切分方式不一样
RAG 质量好不好,很大程度取决于 chunk 怎么切。
文档可以按标题切,日志可以按时间段切,代码最好按函数、类、文件结构切。偷懒一点,也可以先按固定长度切,但效果会差一些。
一个最简单的切分函数:
defsplit_text(text, size=1200, overlap=200): chunks = [] start = 0while start < len(text): end = start + size chunks.append(text[start:end]) start = end - overlapreturn chunks对代码来说,我更建议给 chunk 加上元信息:
{"path": "app/services/order.py","type": "code","content": "...",}因为你问“订单取消逻辑在哪里”,答案里最好能直接带文件路径。否则它说一堆解释,你还是得自己翻仓库。
五、建立向量索引
以 Chroma 为例,大概是这样:
import chromadbclient = chromadb.PersistentClient(path="./rag_db")collection = client.get_or_create_collection("project_context")for doc in docs:for i, chunk in enumerate(split_text(doc["text"])): collection.add( ids=[f"{doc['path']}::{i}"], documents=[chunk], metadatas=[{"path": doc["path"]}] )真实项目里,你还需要处理“增量更新”。
最简单的办法是记录文件的 hash:
文件没变:跳过文件变了:删除旧 chunk,重新索引文件删了:删除对应索引这样每次不用全量重建,几十万行代码的仓库也能接受。
六、问答时别只把结果丢给模型
很多人做 RAG 的第一个坑是:检索出几段文本,然后直接问模型。
更稳的做法是加一个明确提示:
你是项目排障助手。只能基于给定上下文回答。如果上下文不足,直接说“不确定”,并说明还需要哪些文件或日志。回答中必须引用相关文件路径。这样可以减少一本正经地编答案。
检索部分类似这样:
question = "订单支付成功后为什么没有发通知?"results = collection.query( query_texts=[question], n_results=5)context = "\n\n".join(results["documents"][0])然后把 context + question 发给大模型。
我建议回答格式固定成三段:
可能原因依据建议排查步骤研发场景里,漂亮的长文不重要。重要的是能不能少走弯路。
七、日志是最容易被低估的数据
很多团队只索引代码和文档,不索引日志。其实排障场景里,日志往往最有用。
尤其是这些内容:
错误堆栈请求 ID接口路径异常时间服务名环境信息可以把日志按一次异常切成一个 chunk,而不是按固定长度切。比如用 traceback、ERROR 行、request_id 做边界。
这样你问:
“这个 ValueError 最近出现过吗?”
系统就能从历史日志里找类似报错,再结合代码给出判断。
这比单纯让 AI 看一段当前报错靠谱得多。
八、这个工具适合先做成内部命令行
别急着做 Web UI。
第一版可以就是一个 CLI:
python rag_index.py ./my_projectpython rag_ask.py "用户注册失败可能是什么原因?"团队里用起来后,再考虑接到飞书、Slack、企业微信,或者挂到 CI 里。
比如 PR 阶段自动问:
这次改动影响了哪些接口?有没有修改到鉴权、支付、任务调度相关逻辑?相关文档是否需要更新?这时它就不只是问答工具,而是项目上下文检查器。
九、几个实用建议
第一,先从一个仓库开始,不要一上来做全公司知识库。
第二,chunk 里一定带来源路径。没有来源的答案,很难信。
第三,提示词里要允许“不确定”。AI 在排障时最危险的不是不知道,而是不知道还硬答。
第四,定期清理索引。废弃文档、旧日志、生成代码都会污染结果。
第五,研发资料最好有基本规范。文档乱、日志乱、命名乱,RAG 只是把混乱放大了一遍。
夜雨聆风