OpenClaw RAG 集成:让 Agent 拥有自己的"图书馆"

凌晨四点,一个 Agent 正在绞尽脑汁回答用户的问题。它翻遍了训练数据,却找不到最新的产品信息。它不知道你们的定价策略上周刚改了,也不知道 v2.0 新增了三个功能。这不是 Agent 智商的问题——它缺少一个"图书馆"。今天,我们聊聊 RAG(检索增强生成),如何让 Agent 从"闭卷考试"变成"开卷考试"。

什么是 RAG?

RAG(Retrieval-Augmented Generation,检索增强生成)是一种让 LLM 在回答前先检索相关文档的技术。就像学生考试前先翻书查资料,然后再写答案——准确性大幅提升。

RAG 的核心价值:

OpenClaw RAG 架构

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  用户问题    │────▶│  检索器       │────▶│  相关文档    │
│             │     │  (Retriever) │     │  (Context)  │
└─────────────┘     └──────┬───────┘     └──────┬──────┘
                           │                    │
                    ┌──────▼───────┐     ┌──────▼──────┐
                    │  向量数据库   │     │  LLM 生成   │
                    │  (Vector DB) │     │  (Generate) │
                    └──────┬───────┘     └──────┬──────┘
                           │                    │
                    ┌──────▼───────┐     ┌──────▼──────┐
                    │  Embedding   │     │  最终答案    │
                    │  模型        │     │  (Answer)   │
                    └─────────────┘     └─────────────┘

第一步:选择向量数据库

数据库 类型 优点 缺点 适合场景
Pinecone 托管 易上手、自动扩容 成本较高 快速起步
Weaviate 自托管/托管 混合搜索、GraphQL 资源消耗大 企业级
Milvus 自托管 高性能、开源 部署复杂 大规模
ChromaDB 嵌入式/自托管 轻量、Python 友好 不适合生产 开发/原型
Qdrant 自托管 Rust 编写、高性能 社区较小 高性能需求

第二步:配置 RAG 系统

基础配置

# .openclaw/rag.yaml

rag:
  enabled: true
  
  # Embedding 模型
  embedding:
    model: "text-embedding-3-small"  # OpenAI
    # model: "bge-large-zh-v1.5"     # 中文优化
    # model: "cohere-embed-v3"       # 多语言
    dimension: 1536
    batch_size: 100
    
  # 向量数据库
  vector_db:
    backend: "pinecone"  # pinecone | weaviate | milvus | chroma | qdrant
    
    pinecone:
      api_key: "${PINECONE_API_KEY}"
      index_name: "miaoquai-knowledge"
      environment: "us-east-1"
      
    # 备选:本地 Chroma
    # chroma:
    #   persist_directory: "./data/chroma"
    #   collection_name: "knowledge"
    
  # 文档分块策略
  chunking:
    strategy: "semantic"  # fixed | semantic | recursive
    chunk_size: 512
    chunk_overlap: 50
    separators: ["\n\n", "\n", "。", "!", "?", ";"]
    
  # 检索配置
  retrieval:
    top_k: 5              # 返回前 5 个结果
    score_threshold: 0.7  # 最低相似度阈值
    rerank: true          # 启用重排序
    rerank_model: "cohere-rerank-v3"

数据导入

# 导入文档到知识库
openclaw rag ingest \
  --source "./documents/" \
  --recursive \
  --formats "pdf,md,txt,html" \
  --batch-size 50

# 导入单个文档
openclaw rag ingest \
  --source "product-manual.pdf" \
  --metadata '{"type": "product", "version": "2.0"}'

# 导入网页
openclaw rag ingest \
  --source "https://docs.example.com/api-reference" \
  --type "webpage"

# 查看知识库状态
openclaw rag status
# 输出:
# Documents: 1,247
# Chunks: 8,932
# Index: pinecone://miaoquai-knowledge
# Last updated: 2026-04-30 01:00

第三步:检索优化

混合搜索(Hybrid Search)

rag:
  retrieval:
    # 混合搜索:向量检索 + 关键词检索
    hybrid:
      enabled: true
      weights:
        vector: 0.7    # 向量相似度权重
        keyword: 0.3   # 关键词匹配权重
      keyword_engine: "bm25"  # bm25 | tfidf
        
    # 多路召回
    multi_recall:
      enabled: true
      routes:
        - name: "semantic"
          top_k: 10
          method: "vector"
        - name: "keyword"
          top_k: 5
          method: "keyword"
      fusion:
        method: "rrf"  # rrf (Reciprocal Rank Fusion) | weighted
        final_top_k: 5

查询改写(Query Rewriting)

rag:
  query:
    # 自动改写用户查询
    rewriting:
      enabled: true
      strategies:
        - "expand"     # 同义词扩展
        - "decompose"  # 复杂问题拆解
        - "hyde"       # 假设性文档生成
        
    # HyDE 示例
    hyde:
      model: "claude-3-haiku"
      prompt: "基于以下问题,生成一个假设性的答案段落:{query}"

上下文压缩

rag:
  compression:
    # 检索后压缩相关文档
    enabled: true
    
    # 方法一:LLM 提取
    llm_extract:
      model: "claude-3-haiku"
      max_tokens: 2000
      prompt: "从以下文档中提取与问题相关的内容:"
      
    # 方法二:重排序截断
    rerank_truncate:
      model: "cohere-rerank-v3"
      top_k: 3
      max_context_tokens: 3000

第四步:在 Agent 中使用

SOUL.md 配置

# SOUL.md

## 知识库

### RAG 配置
- 知识库已启用,检索范围为产品文档、API 参考、常见问题
- 回答问题时优先引用知识库内容
- 如果知识库中没有相关信息,明确告知用户

### 引用格式
回答时使用以下格式引用来源:
> 根据文档《产品手册 v2.0》第 3 章:...

### 不确定时
如果检索结果与问题匹配度不高:
1. 说明匹配程度
2. 提供已有的相关信息
3. 建议用户提供更多上下文

代码集成

import openclaw

# 创建带 RAG 的 Agent
agent = openclaw.Agent(
    name="knowledge-assistant",
    model="claude-3-sonnet",
    rag={
        "enabled": True,
        "knowledge_base": "miaoquai-knowledge",
        "top_k": 5,
        "threshold": 0.7
    }
)

# 询问问题(自动检索 + 生成)
response = await agent.chat("v2.0 新增了哪些功能?")

# response 包含:
# - answer: 生成的答案
# - sources: 引用的文档来源
# - confidence: 置信度
print(response.answer)
print(f"引用来源: {response.sources}")

RAG 评估指标

指标 说明 目标值 测量方法
召回率 (Recall) 检索到的相关文档占总相关文档的比例 > 0.85 人工标注 + 自动评测
精确率 (Precision) 检索到的文档中相关文档的比例 > 0.80 人工标注 + 自动评测
答案正确率 生成的答案是否正确 > 0.90 人工评审
幻觉率 答案中不真实的内容比例 < 0.05 人工审核 + 事实核查
延迟 从提问到回答的总时间 < 3s 系统监控

常见踩坑

坑一:分块太碎或太大

太碎:丢失上下文,语义不完整 → 512 tokens 左右最佳

太大:噪音太多,检索不精准 → 设置 overlap 弥补

坑二:Embedding 模型不匹配

中文内容用了英文 Embedding 模型,检索效果奇差无比。

解法:中文场景用 bge-large-zh-v1.5 或 multilingual-e5-large。

坑三:没有定期更新知识库

产品文档更新了,但 RAG 知识库还是旧的 → 答案就过时了。

解法:设置定时更新任务。

# cron 定时更新知识库
openclaw rag ingest --source "./documents/" --mode "incremental"
# 每天凌晨 3 点执行

相关资源