从零跑通 RAG Agent (LangChain) 的踩坑指南

Overview:
在 LangChain 1.0分包重构之后,Langchain与RAG的结合也有了较大更新。本指南将搭建本地 RAG并将其融合进大模型 Agent ,遇到的踩坑以及经验都列出。Source code here.

Issue 1:

Chroma依赖注入,LangChain 官方为了主包瘦身,防止社区包过于臃肿导致环境冲突,现在将各大第三方工具全部剥离成了独立的母包,如之前的vectorstore中的chroma移动到了单独的langchain_chroma,正确导入from langchain_chroma import Chroma

Issue 2:

新版的构建是通过LCEL语言去构建ragchain,替代原本的chains和固定的RetrieverQA。像这样:

rag_chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

当然这个基础的配置与经典的RetrieverQA流程是很类似的,所以优势主要在于需求更高自由度的时候,例如调用多个retriever:

from langchain_core.runnables import RunnableParallel, RunnablePassthrough

# 定义一个合并文档的辅助函数
def merge_docs(results):
    # results 会收到一个字典,包含两个 retriever 返回的文档列表
    local_docs = results["local_docs"]
    db_docs = results["db_docs"]
    # 把它们拼接成一个超长的上下文文本
    return "\n\n".join([doc.page_content for doc in local_docs + db_docs])

# ==================== 🔀 现代化多路检索 RAG 链 ====================
rag_chain = (
    # 1. 并发调用两个不同的检索器
    {
        "local_docs": doc_retriever, 
        "db_docs": db_db_retriever, 
        "question": RunnablePassthrough()
    }
    # 2. 将多路检索出来的文档进行自定义清洗、去重或合并
    | RunnableParallel({
        "context": merge_docs,
        "question": lambda x: x["question"] # 保持原问题继续向下传递
    })
    # 3. 正常的后续流程
    | prompt
    | model
    | StrOutputParser()
)

更高级的还有动态路由、文档重排等。

Issue 3:RAG如何导入到Agent中

langchain的create agent并没有retriever属性,如果要把RAG链接进去,就需要wrapper成工具,此外,在tool中写的Docstring,在运行时会被大模型当成“工具说明书”去阅读。通过调整工具的 Prompt 备注,可优化工具的使用体验。

Issue 4:多目标查询与拒答

当去询问问题的时候,如果一次询问多个目标object可能会因为找不到目标文档被拒绝回答。

这时候可以关注两个地方进行优化调整:

  1. 初始化检索器时:在配置retriever = vdb.as_retriever(search_kwargs={"k": num})时可以把k变大,提高粗筛阶段的文档覆盖率,让多个目标的语料有机会同时进入大模型的视野。
  2. 丰富本地语料与松绑 Prompt:如果数据过于干瘪,可以调整 RAG 内部的指令,允许模型在本地基础知识无法支撑时,结合其自身知识库进行合理的润色和补充。
posted @ 2026-07-01 19:23  M-T-Arden  阅读(24)  评论(0)    收藏  举报