首页 / 文章

设计RAG流程,让AI智能体能够进行推理,而不仅仅是执行查询。

用于 AI 智能体的 RAG 流水线应能够展示置信度、信息来源的多样性以及覆盖范围,这样智能体就能发现不足之处,重新查询,并解释其得出结论的依据。

发布者:REACTAPP.TOP阅读约 5 分钟1252 词

来源: How to Design a RAG Pipeline So AI Agents Reason, Not Just Query It

智能体调用 RAG 流水线后会收到一份文档列表。接下来会发生什么?

在大多数智能体架构中,RAG 被视为一个搜索框:输入查询,获取返回结果,然后继续操作。智能体无法判断这些结果是否可靠,是否涵盖了问题的所有方面,也无法确定如果用更精准的假设再次尝试是否能找到重要信息。它实际上是在盲目工作。

这一点很重要,因为智能体总是依据不完整的信息来行动。幻觉检测器可以识别出编造的事实,但检索盲点则更难被发现。智能体会基于不完整的信息自信地做出判断,而没人会知道它遗漏了什么。常规的开发流程——输入数据、检索信息、生成结果——完全缺乏反馈机制。

让智能体能够看到检索过程

解决办法是在 RAG 流水线周围添加一个轻量级的框架,该框架能够提供结构化信号供智能体进行推理,而不仅仅是直接使用这些数据。

该框架不会仅返回文档列表,而是返回更丰富的对象。其中包含文档本身、置信度得分、来源多样性指标(不同领域的数量及时间范围)、涵盖信号(说明问题中哪些方面已得到解答、哪些尚未解决),以及检索元数据,如嵌入模型、分块大小、top-k 值以及是否进行了重排处理。

{
  "results": [Document, Document, Document],
  "confidence_score": 0.87,
  "source_diversity": {"domains": 3, "timestamps": ["2024-01", "2023-11", "2023-09"]},
  "coverage_signals": {
    "question_aspects_covered": ["technical", "cost"],
    "question_aspects_missing": ["compliance", "deployment"]
  },
  "retrieval_metadata": {
    "embedding_model": "text-embedding-3-large",
    "chunk_size": 512,
    "top_k": 5,
    "reranker_applied": true
  }
}

这样一来,该系统便拥有了反馈渠道。它能够发现覆盖范围不完整且信息来源较为有限。它可以决定从不同角度重新查询,向上级汇报,或将其推理过程中的缺陷记录下来。

三层结构

第一层:工具检索

首先获取系统已计算出的结果。向量数据库会返回相似度分数,重排工具会输出置信度,而数据块则包含时间戳和来源URL。这一层在不改变检索逻辑的情况下收集这些数值:执行常规查询,提取分数、来源和时间戳,将分数平均以得出大致的置信度数值,并统计不同的来源数量。

def retrieve_with_signals(query: str, top_k: int = 5):
    # Standard retrieval
    results = vector_db.query(query, top_k=top_k)

    # Capture raw signals
    similarity_scores = [r.score for r in results]
    sources = [r.metadata.get("source") for r in results]
    timestamps = [r.metadata.get("timestamp") for r in results]

    # Compute confidence as mean similarity
    confidence = sum(similarity_scores) / len(similarity_scores)

    return {
        "results": results,
        "confidence_score": confidence,
        "source_diversity": {
            "domains": len(set(sources)),
            "timestamps": sorted(set(timestamps))
        }
    }

这是一种非侵入式方法,因为您只需读取已存在的数据。

第二层:检测覆盖情况

接下来是將检索到的内容与原始问题对应起来的层次。只需进行简单的语义比对,无需进行完整的重新排序。

将问题拆分成各个方面。对于“如何在成本限制下部署模型?”这个问题,相关方面可能包括部署、成本和限制条件。然后检查这些方面是否出现在检索到的文本中。大型语言模型或简单的关键词提取工具即可生成这些方面列表,检查过程只需在合并后的文档文本中查找每个方面即可。该功能会说明哪些方面已被覆盖、哪些方面缺失,以及覆盖比例。

def detect_coverage(query: str, documents: list) -> dict:
    # Extract query aspects (simple approach: use an LLM or keyword extraction)
    aspects = extract_query_aspects(query)  # ["deployment", "cost"]

    # Check document coverage
    doc_text = " ".join([d.content for d in documents])
    covered = [a for a in aspects if a.lower() in doc_text.lower()]
    missing = [a for a in aspects if a not in covered]

    return {
        "question_aspects_covered": covered,
        "question_aspects_missing": missing,
        "coverage_ratio": len(covered) / len(aspects) if aspects else 1.0
    }

这就是智能体获取可据以采取行动的反馈的地方。若缺少某些方面,则应发起新的查询。为改进这一方法,应在数据导入时为每份文档标注相关方面,并在检索时对比这些标注。

第三层:将任务交给智能体

最后,为智能体提供一个能返回处理结果的工具。该工具接收查询以及可选的关注方面,利用信号进行检索,计算覆盖率,并给出建议:若覆盖率低于0.7则重新查询,否则继续执行后续操作。

tools = [
    {
        "name": "search_with_reasoning",
        "description": "Search the knowledge base and receive coverage signals",
        "parameters": {
            "query": "str",
            "aspect_focus": "optional str (e.g., 'deployment' or 'cost')"
        }
    }
]

def search_with_reasoning(query: str, aspect_focus: str = None) -> dict:
    retrieval_output = retrieve_with_signals(query, top_k=5)
    coverage = detect_coverage(query, retrieval_output["results"])

    return {
        **retrieval_output,
        "coverage_signals": coverage,
        "recommendation": (
            "re-query" if coverage["coverage_ratio"] < 0.7 else "proceed"
        )
    }

代理会收到该建议,可以选择遵循它,也可以利用领域知识予以否决。

确认这些信号值得信赖

只有当其信号准确时,该工具才有价值,因此需要测试三方面内容。

  • 信号准确性。置信度分数是否真的能预测检索质量?执行大约二十次查询,手动为结果打分(1到5分),并将评分与分数进行关联。0.75以上的关联度是一个合理的目标。
  • 覆盖范围检测。手动标记每份文档对每个问题中哪些方面的回答,然后通过大约十种不同类型的查询与检测工具的结果进行对比。精确度应保持在85%以上。
  • 代理行为。记录每一次重新查询的决策。如果覆盖率低于0.7时大多数情况下都会触发新的查询,说明代理正在重视这些信号。

成本与限制

这会增加延迟。覆盖范围需要再次进行语义处理,对于包含五份文档的检索任务,可能会额外多出50到100毫秒的延迟。如果这个延迟过高,可以缓存相关信号或异步计算它们。

该框架还假设检索层处于良好状态且能够正常提供数据。如果向量存储不返回评分,或者数据块不包含元数据,就必须先进行相关处理。

而且这些信号只是启发式方法而已。较高的置信度评分并不能保证推理的正确性。该框架为智能体提供的是更优质的输入,而非完美无缺的输入,因此仍需后续的幻觉检测步骤。

为何这样做值得

能够查看检索内部过程的智能体更加透明且可靠。它们可以解释为何再次进行搜索,标出不确定性,并在覆盖度较低时将任务交由人类处理。这正是搜索引擎与研究助手之间的区别:前者仅返回结果,而后者在返回结果的同时还会说明其不确定之处。

入门指南

  1. 本周完成第一层功能。展示置信度与信息来源的多样性,记录一天的数据并观察其中的规律。
  2. 为最常见的查询类型添加覆盖度检测功能,并手动检查十个示例。
  3. 将其集成到智能体中,检测在覆盖度较低时是否会重新查询,以及其推理能力是否有所提升。

一旦有了这个框架,更多的功能就能轻松集成:语义漂移检测、内容新鲜度检查、事实核查接口。这些功能都能为智能体提供更多分析依据。从简单之处开始,建立反馈机制,让智能体学会倾听这些反馈。

相关阅读

  • 在智能体内存测试中grep与向量搜索的对比,以及框架的重要性 —— 对116道LongMemEval题目的研究显示,grep的表现优于向量检索技术,但框架呈现结果的方式对准确率的影响与检索器本身相当。由此可得出哪些结论。