RAG 管线:面向企业知识的检索增强生成
没有知识接地的语言模型是一个会编故事的预言家。OctopusOS RAG 管线通过 8 阶段流水线将原始用户查询转化为有据可查、带引用的回答:查询改写、混合检索(关键词 + 向量)、权限过滤、LLM 重排序、Token 预算上下文组装 + PII 脱敏、接地回答生成、幻觉检测、审计摘要——全部作为一等 Port 接入 Worker Loop。
1. 为什么 AI OS 需要 RAG
大语言模型会产生幻觉。它们生成流畅且听起来权威的文本,但内容可能完全是编造的。对于企业级 AI 操作系统来说,这是不可接受的——错误答案侵蚀信任、产生合规风险、浪费人力验证时间。
RAG 通过将 LLM 回答接地到检索出的源文档来解决这个问题。答案中的每个论断都可追溯到一段经过验证的知识。当知识库没有相关信息时,系统会如实说明,而不是猜测。
OctopusOS 将 RAG 实现为内核原生管线——纯领域逻辑、零 IO,由 server 层可插拔的 embedding 和向量存储适配器提供支撑。
2. 8 阶段流水线
每次 RAG 查询经过 8 个确定性阶段。每个阶段都是 kernel/domains/rag/ 下的纯函数,可组合、可独立测试。
3. 查询改写
改写器将口语化用户输入转换为检索优化的查询。使用小型 LLM(通过 LLM_MODEL_SMALL 配置)和结构化 JSON 输出。
# kernel/domains/rag/query_rewriter.py
def rewrite_query(*, query, llm_provider, config, history=None) -> list[str]:
"""LLM 改写:从对话历史解析代词,
展开缩写,添加同义词。返回 1-3 个改写查询。"""
def rule_based_rewrite(*, query) -> list[str]:
"""回退:常见中文模式的同义词扩展
(退款 -> 退款 退钱 退费),停用词移除。"""
改写器还将查询意图分为 factual(事实性)、analytical(分析性)或 procedural(操作性)——此元数据贯穿整条管线,供下游优化使用。
4. 混合检索:关键词 + 向量
纯关键词检索会遗漏语义相似性。纯向量检索会遗漏精确词项匹配。OctopusOS 通过**倒数排名融合(RRF)**将两者结合。
倒数排名融合
RRF 合并两个排名列表,无需分数归一化:
RRF_score(d) = sum( 1 / (k + rank_i(d)) ) 对每个检索系统 i
其中 k=60(标准常数)。这自然处理了 BM25 和余弦相似度之间不兼容的分数分布。
5. LLM 重排序
混合检索返回候选结果后(过采样 3 倍 top_k),LLM 重排序器对每个段落评分 0.0-1.0 的查询相关性。
# kernel/domains/rag/reranker.py
def rerank_with_llm(*, query, candidates, llm_provider, top_k=5):
"""LLM 评估最多 20 个候选段落。
输出:JSON {"rankings": [{"chunk_id": ..., "relevance_score": 0.0-1.0}]}
回退:LLM 失败时保留原始检索顺序。"""
重排序是对回答质量影响最大的阶段——它能捕获仅靠嵌入相似度无法检测的语义不匹配。
6. 上下文构建与 PII 脱敏
上下文构建器在严格的 Token 预算内组装最终提示上下文。在任何文本到达 LLM 之前,会应用字段级 PII 脱敏。
检测的 PII 模式
| 模式 | 替换 | 示例 |
|---|---|---|
| 中国身份证号(18 位) | [MASKED_ID_CARD] | 110101199001011234 |
| 手机号(1xx-xxxx-xxxx) | [MASKED_PHONE] | 13812345678 |
| 国际电话(+xx …) | [MASKED_PHONE] | +86 138 1234 5678 |
| 邮箱地址 | [MASKED_EMAIL] | [email protected] |
| 信用卡/借记卡 | [MASKED_CARD] | 6222 0200 1234 5678 |
| 银行账号(16-19 位) | [MASKED_BANK_ACCT] | 6217001234567890123 |
| 护照号(E/G/D + 8 位) | [MASKED_PASSPORT] | E12345678 |
| 美国 SSN(xxx-xx-xxxx) | [MASKED_SSN] | 123-45-6789 |
可通过 extra_pii_patterns 在运行时注入自定义模式,用于领域特定字段(员工 ID、病历号等)。
Token 预算
构建器使用双语 Token 估算器:ASCII 约 4 字符/token,CJK 约 2 字符/token。贪心累积块直到预算(默认 3000 tokens)耗尽。每个块获得引用标记 [1]、[2] 等。
7. 接地回答生成
Q&A 生成器通过严格的系统提示强制接地回答:
RAG_QA_SYSTEM_PROMPT = """你是企业知识助手。
仅基于以下参考文档回答用户问题。
规则:
1. 仅使用参考文档中的信息。不要编造事实。
2. 每个事实陈述后,使用 [1]、[2] 等标记引用来源。
3. 如果文档不包含相关信息,请明确说明。
4. 使用与用户问题相同的语言回答。
5. 简洁准确。"""
置信度评分结合检索相关性(60% 权重)和引用使用率(40% 权重):
confidence = avg_chunk_score * 0.6 + (used_citations / total_citations) * 0.4
8. 幻觉检测
生成后,LLM 评估器检查答案中的每个论断与源文档的一致性,产生忠实度评分。
# kernel/domains/rag/hallucination_detector.py
def detect_hallucination(*, answer, source_chunks, llm_provider):
"""返回:
faithfulness_score: float 0-1
unsupported_claims: [{claim, reason}]
grounded_claims: [{claim, source_index}]"""
当 LLM 评估器不可用时,规则回退将答案拆分为句子并检查关键词重叠(>30% 重叠阈值)。
9. 支撑服务
10. Embedding 与向量存储适配器
Server 层提供两种 embedding 后端和两种向量存储后端,通过配置选择。
FAISS 向量存储
用于开发和单节点部署。每个 collection 存储为:
{root}/vector_stores/{collection}/index.faiss— FAISS 内积索引{root}/vector_stores/{collection}/metadata.json— 块元数据 sidecar
操作:create_collection、upsert、search(带元数据过滤)、delete(索引重建)。
Qdrant 向量存储
用于生产环境。使用 Qdrant gRPC/REST API,cosine 距离,批量 upsert(每批 100 条),通过 FieldCondition 原生元数据过滤。
11. Worker Loop 集成
RAG 作为一等 Port 接入主 Worker Loop,RAG 优先检索,优雅回退。
# kernel/runtime/_wl_memory_kb.py
def _query_kb_ref(self, *, run_id, kb_query_spec):
# 优先尝试 RAG 管线
rag_ref = self._query_rag(run_id=run_id, kb_query_spec=kb_query_spec)
if rag_ref is not None:
return rag_ref
# 回退到标准 knowledge port 查询
return self.knowledge_port.query(kb_id, kb_query_spec)
Worker Loop 为每个 intent 调用 _kb_query_spec(),生成包含 kb_id、query(来自 intent 目标)、top_k=5 和来源过滤器的查询规格。RAG 适配器将其桥接到完整的 8 阶段管线。
Bootstrap 装配
# server/shared/wiring/bootstrap.py
rag_backend = config.get("RAG_BACKEND", "faiss") # 默认启用
rag_port = create_rag_port(
config=config,
llm_provider=llm_provider_port,
knowledge_port=capability_bundle.ports.get("KnowledgePort"),
root_dir=root_dir,
)
# 注入 KernelWorkerLoop(rag_port=rag_port)
12. 多模态 RAG
管线通过 multimodal_query() 支持多模态输入。当 MultimodalContext(来自多模态感知层)到达时,提取融合文本并送入标准 RAG 管线。
# kernel/domains/rag/pipeline.py
def multimodal_query(*, context, kb_id, embedding_port, vector_store, ...):
"""从 MultimodalContext 提取 fused_text,委托给 rag_query()。
回退:主模态 content_ref。"""
这意味着图像描述、音频转录和文档提取都可以用作 RAG 查询——用户上传 PDF 并基于知识库提问。
13. 配置参考
| 配置键 | 默认值 | 用途 |
|---|---|---|
RAG_BACKEND | faiss | 启用 RAG 并选择后端模式 |
VECTOR_STORE_MODE | faiss | 向量数据库:faiss 或 qdrant |
EMBEDDING_MODE | local | Embedding:local(sentence-transformers)或 api |
RAG_REWRITE_ENABLED | true | LLM 查询改写 |
RAG_RERANK_ENABLED | true | LLM 重排序 |
RAG_PII_MASKING | true | PII 检测与脱敏 |
RAG_MAX_CONTEXT_TOKENS | 3000 | 上下文组装 Token 预算 |
RAG_MAX_ANSWER_TOKENS | 1024 | 生成回答最大 Token 数 |
VECTOR_STORE_ROOT | /tmp/octopus-vectors | FAISS 存储目录 |
EMBEDDING_MODEL | all-MiniLM-L6-v2 | 本地 embedding 模型 |
QDRANT_URL | http://localhost:6333 | Qdrant 服务器地址 |
14. 架构总览
15. 实现指标
| 指标 | 数量 |
|---|---|
| RAG 管线阶段 | 8 |
domains/rag/ 领域模块 | 13 |
| Frozen 合约 | 6(RAGQuery, RAGContext, RAGResponse, EmbeddingResult, VectorSearchResult, HybridSearchResult) |
| PII 检测模式 | 8(身份证、手机、邮箱、银行卡、银行账号、护照、SSN、国际电话) |
| 向量存储后端 | 2(FAISS, Qdrant) |
| Embedding 后端 | 2(本地 sentence-transformers, API) |
| 支撑服务 | 4(分类器、新鲜度监控、反馈存储、实体抽取器) |
| 引入的 gate 违规 | 0 |
16. 应用场景
企业知识问答
将产品手册、政策文档和 FAQ 上传到知识库。用户用自然语言提问,获得接地的、带引用的回答——PII 在到达 LLM 之前自动脱敏。
客户服务自动化
接入 CRM 和工单系统数据。RAG 管线检索相关案例历史和产品信息,生成带引用的准确回答,并通过反馈存储追踪用户满意度。
合规与审计
每个 RAG 回答都携带不可变的 audit_digest(SHA-256),关联查询、上下文、引用和回答。幻觉检测器为每个回答提供忠实度评分,支持自动化质量门禁。
多语言支持
查询改写原生支持 CJK 同义词扩展。上下文构建器的双语 Token 估算器正确处理 ASCII/CJK 混合内容预算。Q&A 生成器使用与用户问题相同的语言回答。