05

RAG 系统

双通道检索、Cypher 生成与 LLM 上下文组装

RAG = 检索 + 生成,CGB 的双通道设计

RAG 解决的核心问题是:LLM 不认识你的私有代码库。CGB 的 RAG 是 双通道检索——不只用向量相似度,还能把自然语言转成 Cypher 图查询, 两路结果融合后送给 LLM。这让回答既有语义广度,又有结构精度。

🔍
SemanticSearchService
向量通道。把 query 转向量,在 MemoryVectorStore 中找最相似函数。支持关键词提权再排序。
domains/core/search/semantic_search.py
🔮
CypherGenerator
图查询通道。把自然语言问题通过 LLM 翻译成 Cypher,执行后得到精确的结构化结果(调用链、继承关系等)。
domains/upper/rag/cypher_generator.py
🤖
RAGEngine
总协调器。驱动两路检索、组装 prompt 上下文、调用 Kimi LLM 生成答案、构建 RAGResult 返回。
domains/upper/rag/rag_engine.py
💡 双通道的互补性

向量搜索擅长"模糊意图匹配"——即使描述不精确也能找到相关函数。Cypher 查询擅长"精确结构查询"——"找所有继承了 BaseEmbedder 的类"这种问题向量搜索无能为力,Cypher 一条 MATCH 语句搞定。两路结果去重后融合,LLM 拿到的上下文既有广度又有深度。

CypherGenerator:NL → 图查询

CypherGenerator 的实现出人意料地简洁:给 LLM 一个描述图 Schema 的 system prompt, 把用户问题直接发过去,LLM 输出 Cypher。没有手写规则,没有 AST 解析——全靠 LLM 理解 Schema 后的 zero-shot 推理

Q
自然语言:找所有解析命令行参数的函数
MATCH (f:Function) WHERE f.name CONTAINS 'parse' RETURN f.qualified_name, f.signature LIMIT 50
Q
自然语言:找所有继承了 BaseEmbedder 的类
MATCH (c:Class)-[:INHERITS]->(b:Class) WHERE b.name = 'BaseEmbedder' RETURN c.qualified_name, c.path LIMIT 50

SemanticSearchService:向量 + 图上下文融合

语义搜索不只返回向量相似度结果——它还会从图数据库回填函数的完整元数据(源码、文件路径、行号), 以及可选的调用方/被调用方列表,形成 SemanticSearchResult 传给 RAGEngine 组装 prompt。

💬
Query
🎯
向量检索
🗄️
图查询
🔗
上下文增强
📋
SearchResult
点击"下一步"开始 Step 0 / 5
字段 类型 来源
score float (0-1) 余弦相似度 + 关键词奖励,4位小数
qualified_name str VectorRecord.qualified_name 直接透传
source_code str | None 图数据库补填,或从文件提取 start_line~end_line
type str Function / Class / Method 等,图数据库补填

RAGEngine:从 query 到最终答案

RAGEngine.query() 是整个 RAG 链路的入口。它驱动语义检索、 CodeContext 组装和 LLM 调用,最终返回带源码引用的 RAGResult。 LLM 后端使用 Kimi(Moonshot AI),temperature=0.7,max_tokens=4096。

组件对话 — query("embed_query 和 embed_documents 有什么区别") 执行过程
0 / 5 messages

配置与输出:RAGConfig 和 RAGResult

RAGConfig 由三个子配置组成,全部支持从环境变量读取(RAGConfig.from_env())。 RAGResult 是 RAG 系统的输出契约,包含答案文本、来源引用列表和执行元数据, 可直接通过 to_markdown() 渲染为 Markdown 文档。

配置项 默认值 环境变量
moonshot.model kimi-k2.5 MOONSHOT_MODEL
moonshot.temperature 0.7 ——
retrieval.semantic_top_k 10 RAG_SEMANTIC_TOP_K
retrieval.max_context_tokens 8000 ——
retrieval.include_callers True ——
retrieval.graph_max_depth 2 ——
💡 RAG 的价值在哪里

没有 RAG,AI 助手只能基于训练数据推测你的代码行为。有了 RAG,每次回答都基于真实检索到的源码——LLM 不是在"编",而是在"读你的代码再解释"。双通道(向量+图)确保无论是模糊的"语义查询"还是精确的"结构查询",都能找到相关代码,最终回答质量远高于直接问 LLM。