首页
/ agno 检索增强生成(RAG)实战指南:传统 RAG、Agentic RAG、知识过滤与自定义检索器逐例精讲

agno 检索增强生成(RAG)实战指南:传统 RAG、Agentic RAG、知识过滤与自定义检索器逐例精讲

2026-09-08 21:21:23作者:宣聪麟

本指南以 agno 仓库 cookbook/02_agents/07_knowledge 目录下的 8 个官方示例(及其 README.md)为主体骨架,系统讲解如何在 agno Agent 上落地检索增强生成(RAG):从把知识直接注入上下文的传统 RAG,到把知识库检索变成工具调用的 Agentic RAG,再到重排序、推理工具、多语言向量模型、知识过滤、自定义检索器和引用格式控制等进阶能力。读完本文,你将能依据自己的数据形态与精度要求,选用或组合出合适的 RAG 方案,并在本地 PostgreSQL(pgvector)或 LanceDB 上复现全部示例。

一、目录概览:一条从“传统 RAG”到“Agentic RAG 全家桶”的学习路径

该目录是 cookbook 中"07_knowledge"专题的完整示例集,README 将其定位为 "Examples for retrieval-augmented generation, knowledge filters, and custom retrievers."(检索增强生成、知识过滤与自定义检索器示例),共 8 个可独立运行的文件:

示例文件 核心主题 关键 Agent 参数
traditional_rag.py 传统 RAG:检索结果注入用户上下文 add_knowledge_to_context=True, search_knowledge=False
agentic_rag.py Agentic RAG:知识检索作为按需工具 search_knowledge=True(默认开启)
agentic_rag_with_reasoning.py Agentic RAG + 显式推理工具 + 重排序 tools=[ReasoningTools(...)]
agentic_rag_with_reranking.py Agentic RAG + Cohere 语义重排序 reranker=CohereReranker(...)
rag_custom_embeddings.py 自定义向量模型(多语言) SentenceTransformerEmbedder/Reranker
knowledge_filters.py 静态过滤与 Agentic 过滤 knowledge_filters / enable_agentic_knowledge_filters
custom_retriever.py 用自定义检索函数替代 Knowledge knowledge_retriever=my_retriever
references_format.py 控制引用返回格式(JSON/YAML) references_format="yaml"

建议按表中顺序阅读与运行:前两个文件对照出"传统 vs Agentic"两种范式差异,随后四个文件层层叠加推理、重排序与自定义 embedding 能力,最后三个文件展示检索链路上的过滤、替换与输出控制技巧。

二、运行前置:环境、PostgreSQL 与启动方式

README 明确列出三个前置条件,这是本地复现所有示例的前提:

  1. 加载环境变量:使用 direnv allow 载入仓库环境配置(其中包含 OPENAI_API_KEY)。所有示例均默认调用 OpenAI 的模型与向量接口。
  2. 创建 demo 运行环境:执行 ./scripts/demo_setup.sh(位于仓库根目录 scripts/demo_setup.sh)创建虚拟环境,之后统一用 .venvs/demo/bin/python 运行 cookbook。
  3. 启动 PostgreSQL(pgvector):执行 ./cookbook/scripts/run_pgvector.sh(位于 cookbook/scripts/run_pgvector.sh),该脚本会启动一个内置 pgvector 扩展的 PostgreSQL 容器。

启动完成后,统一用如下命令运行任意示例:

.venvs/demo/bin/python cookbook/02_agents/07_knowledge/<file>.py

需要特别说明的是部分示例有额外第三方依赖。示例与目录内的 TEST_LOG.md 记录了真实验证结果:agentic_rag_with_reasoning.pyagentic_rag_with_reranking.py 因缺少 cohere 包、rag_custom_embeddings.py 因缺少 sentence_transformers 包而失败(ModuleNotFoundError)。其中 agentic_rag_with_reranking.py 的头部注释给出了完整安装命令:

uv pip install openai agno cohere lancedb sqlalchemy

即凡涉及 Cohere 重排序与多语言 embedding 的文件,需先自行补齐 coheresentence_transformers 依赖。其余 5 个文件在 pgvector 运行的环境下均已通过(PASS),可作为基线对照。

三、两种 RAG 范式的核心分野:注入上下文还是工具化检索

目录的前两个文件是理解 agno RAG 设计的钥匙。二者共用同一份 Knowledge 与同一数据源(一份泰国菜谱 PDF),差别仅在 Agent 的构造参数上。

3.1 传统 RAG:add_knowledge_to_context=True

traditional_rag.py 的核心代码如下:

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    # Enable RAG by adding context from the `knowledge` to the user prompt.
    add_knowledge_to_context=True,
    # Set as False because Agents default to `search_knowledge=True`
    search_knowledge=False,
    markdown=True,
)

传统 RAG 的语义是"每轮都检索":开启 add_knowledge_to_context 后,每次用户提问前,agnto 会把知识库中与问题相关的文档片段拼进(prompt)上下文,模型在生成时天然"看得到"外部资料。示例特意将 search_knowledge 置为 False,注释明确说明这是因为 Agent 默认 search_knowledge=True——必须显式关闭,才能让"注入上下文"成为唯一的知识来源。从源码角度,对应逻辑位于 libs/agno/agno/agent/_messages.py 的消息组装流程中:当 agent.add_knowledge_to_context 为真时,会基于用户消息内容检索知识并拼装上下文(_messages.pyadd_knowledge_to_context 分支调用知识检索后把文档注入消息上下文)。

3.2 Agentic RAG:search_knowledge=True(默认)

agentic_rag.py 的核心代码如下:

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    # Add a tool to search the knowledge base which enables agentic RAG.
    # This is enabled by default when `knowledge` is provided to the Agent.
    search_knowledge=True,
    markdown=True,
)

Agentic RAG 的语义是"按需检索":Agent 被赋予一个名为 search_knowledge_base 的工具,是否检索、检索什么、检索几次都由模型根据对话内容自主决策。示例注释强调:"当为 Agent 提供 knowledge 时该能力默认开启"。这一机制在 libs/agno/agno/agent/_default_tools.py 中有完整实现:search_knowledge_base(query) 工具会"优先检查 knowledge_retriever,若未设置则回退到 knowledge.search()",其返回的引用内容随后按 references_format 决定是否走过滤逻辑(详见后文)。

两类模式的取舍很直观:

  • 传统 RAG:确定性强、调用成本可预期,适合"每次回答都需要外部事实底座"的固定任务;
  • Agentic RAG:灵活节省 token,模型能判断"何时不需要查知识库",还能多轮追问式检索,适合开放域问答。

四、给 Agentic RAG 叠加推理与重排序

既然 Agentic RAG 把检索交给模型自主判断,检索质量的保障就显得关键。目录中两个进阶示例分别从"回答侧"与"检索侧"入手。

4.1 Agentic RAG + 显式推理工具(reasoning tools)

agentic_rag_with_reasoning.py 将知识底座从 pgvector 换成了 LanceDB,并同时引入两路增强:

from agno.knowledge.embedder.cohere import CohereEmbedder
from agno.knowledge.reranker.cohere import CohereReranker
from agno.tools.reasoning import ReasoningTools

knowledge = Knowledge(
    vector_db=LanceDb(
        uri="tmp/lancedb",
        table_name="agno_docs",
        search_type=SearchType.hybrid,
        embedder=CohereEmbedder(id="embed-v4.0"),
        reranker=CohereReranker(model="rerank-v3.5"),
    ),
)

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    search_knowledge=True,
    tools=[ReasoningTools(add_instructions=True)],
    instructions=[
        "Include sources in your response.",
        "Always search your knowledge before answering the question.",
    ],
    markdown=True,
)

值得注意的三处设计:

  1. 数据注入走异步批量接口:运行时调用 knowledge.ainsert_many(urls=[...]),即 Knowledge 提供的异步批量插入方法(对应源码 libs/agno/agno/knowledge/knowledge.py 中的 ainsert_many),适用于一次灌入多个文档 URL 的场景;
  2. 推理显式化ReasoningTools 把"思考"暴露为可调用的工具,配合 instructions 中"先检索知识库再回答、回复中附带来源"两条指令,让生成链路可解释;
  3. 重排序前置于向量库reranker=CohereReranker(model="rerank-v3.5") 被配置在 LanceDb 上,检索结果会先经 Cohere 语义重排再交给模型。

运行该示例时使用 show_full_reasoning=True,可完整观察到模型"先检索→再推理→后回答"的过程。

4.2 Agentic RAG + 纯重排序方案(reranking)

agentic_rag_with_reranking.py 则把注意力集中在"检索侧质量"这一件事上——用 OpenAI 做向量化、用 Cohere 做重排序,形成分工明确的流水线:

knowledge = Knowledge(
    vector_db=LanceDb(
        uri="tmp/lancedb",
        table_name="agno_docs",
        search_type=SearchType.hybrid,
        embedder=OpenAIEmbedder(id="text-embedding-3-small"),   # Use OpenAI for embeddings
        reranker=CohereReranker(model="rerank-multilingual-v3.0"),  # Use Cohere for reranking
    ),
)

在向量检索阶段,"初筛"靠 embedding 相似度,往往会把语义近似的文档一并召回;重排序阶段再让一个专用的排序模型(如 Cohere rerank-multilingual-v3.0)对召回结果做精细化打分,把最相关片段顶到最前。这是生产级 RAG 最常见的质量兜底手段,尤其适合召回量较大或文档主题相近的场景。

4.3 小结:两个示例的叠加关系

  • agentic_rag_with_reasoning.py = Agentic RAG(Cohere embedding + 重排)+ ReasoningTools 显式推理;
  • agentic_rag_with_reranking.py = Agentic RAG(OpenAI embedding)+ Cohere 重排,是"最简可复制的重排升级路径"。

两者都基于 LanceDB(本地文件数据库,uri="tmp/lancedb",无需额外容器),因此不需要启动 pgvector,但都需要 cohere 依赖。

五、完全本地化:多语言 embedding + 自托管重排序

rag_custom_embeddings.py 展示了一个"不走云厂商、全部本地模型"的多语言 RAG 实现。其示例数据本身颇具代表性——10 条关于护肤与美妆趋势的文本,分别用英语、德语、西班牙语、中文、日语书写,用于验证跨语言检索的正确性:

from agno.knowledge.embedder.sentence_transformer import SentenceTransformerEmbedder
from agno.knowledge.reranker.sentence_transformer import SentenceTransformerReranker

knowledge = Knowledge(
    vector_db=PgVector(
        db_url="postgresql+psycopg://ai:ai@localhost:5532/ai",
        table_name="sentence_transformer_rerank_docs",
        embedder=SentenceTransformerEmbedder(
            id="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
        ),
        reranker=SentenceTransformerReranker(model="BAAI/bge-reranker-v2-m3"),
    ),
)

两个值得留意的工程细节:

  1. 数据逐条写入并打元数据:示例用循环调用 knowledge.insert(text_content=result, metadata={"source": "search_results"}),印证了 Knowledge.insert 的签名能力——该方法支持 pathurltext_content 三种内容来源,并接受 metadatainclude/excludeupsertskip_if_exists 等参数(见源码 insert() 的实现与 docstring);
  2. embedding 与重排序全链路本地化SentenceTransformerEmbedder 使用 paraphrase-multilingual-MiniLM-L12-v2 做多语言向量化,SentenceTransformerReranker 使用 BAAI/bge-reranker-v2-m3 做跨语言重排序,数据不需出本地即可完成从向量化到排序的整条链路。

该示例同样会以 show_full_reasoning=True 的方式运行三条测试查询,其中第三条 "Compare skincare and makeup information across languages" 专门用于验证"跨语言归并检索"的能力——这正是多语言 embedding + 多语言 reranker 组合的价值所在。运行前请确保已安装 sentence_transformers(见 TEST_LOG.md 中的失败记录)。

六、知识过滤:静态过滤与 Agentic 过滤

knowledge_filters.py 解答了一个真实痛点:知识库里混着多类文档时,如何让检索只命中"对的那一簇"。其 README 定位为 "Filter knowledge searches with static or agentic filters"。

6.1 静态过滤:创建期写死过滤条件

from agno.filters import EQ

agent_static = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    search_knowledge=True,
    # Use FilterExpr objects for type-safe filtering
    knowledge_filters=[EQ("cuisine", "thai")],
    markdown=True,
)

静态过滤在 Agent 创建时设定,对每一次检索都生效。示例用 EQ("cuisine", "thai") 把检索范围限定在菜系为 thai 的文档内。注意注释强调应"使用 FilterExpr 对象做类型安全过滤"——对应仓库源码 libs/agno/agno/filters.py 中定义于基类 FilterExpr 之上的比较算子:EQ(字段等值)、IN(字段值落在集合内)等。FilterExpr 还通过运算符重载支持组合逻辑:|(OR)、&(AND)、~(NOT),可构造如 OR(AND(EQ("status","active"), GT("age",18)), EQ("role","admin")) 的嵌套表达式;源码中另有 MAX_FILTER_DEPTH = 10 的递归深度上限,用于防止深层嵌套表达式引发栈溢出,说明过滤表达式是被递归求值的。同时,Agent 侧参数 knowledge_filters 的类型为 Union[Dict[str, Any], List[FilterExpr]](见 libs/agno/agno/agent/_cli.pycreate_agent_cli 参数定义),既支持简洁的字典写法,也支持上面这种强类型的表达式列表。

6.2 Agentic 过滤:让模型在运行时决定过滤值

agent_agentic = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    search_knowledge=True,
    # Let the agent choose filter values based on the user's query
    enable_agentic_knowledge_filters=True,
    markdown=True,
)

Agentic 过滤与静态过滤相对:过滤键值不由开发者在创建期写死,而是由模型在每次收到用户问题时动态推导。例如对 "Find me a Thai dessert recipe.",模型可能自动产出 cuisine=thaidish_type=dessert 之类的过滤条件后再去检索。该参数在 Agent 内部会联动到工具构建逻辑与系统提示词:_default_tools.py 中的 search_knowledge_base_with_filters 工具支持将 Agent 传入的过滤器与运行时模型推导出的过滤条件合并(源码注释可见 get_agentic_or_user_search_filters 的处理流程),并且开启后 Agent 的系统提示会注入相应的"如何推导过滤条件"说明(对应 libs/agno/agno/agent/_messages.py 中以 enable_agentic_filters 为关键字的提示词拼接分支)。

示例在运行阶段对两个 Agent 分别提问:

print("--- Static filters (cuisine=thai) ---")
agent_static.print_response("What soup recipes do you have?", stream=True)

print("\n--- Agentic filters ---")
agent_agentic.print_response("Find me a Thai dessert recipe.", stream=True)

可直观观察到:静态过滤的 Agent 始终只检索 cuisine=thai,而 Agentic 过滤的 Agent 会针对不同提问生成不同过滤条件。生产建议是——过滤维度固定时用静态过滤(可控、省 token),过滤维度随用户意图变化时用 Agentic 过滤

七、用自定义检索函数替换 Knowledge:knowledge_retriever

custom_retriever.py 解决的是另一类问题:如果数据根本不在 agno 的 Knowledge/向量库体系里,而是散落在内部 API、数据库或搜索引擎背后,怎么办?

答案是不再构建 Knowledge 实例,而是写一个普通的 Python 函数当作 knowledge_retriever

def my_retriever(
    query: str, num_documents: Optional[int] = None, **kwargs
) -> Optional[List[dict]]:
    """Search documents by simple keyword matching."""
    query_lower = query.lower()
    results = [
        doc
        for doc in DOCUMENTS
        if query_lower in doc["content"].lower() or query_lower in doc["title"].lower()
    ]
    if num_documents:
        results = results[:num_documents]
    return results if results else None

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    # Use a custom retriever instead of a Knowledge instance
    knowledge_retriever=my_retriever,
    # search_knowledge is True by default when knowledge_retriever is set
    markdown=True,
)

要点解析:

  1. 函数签名契约:接收 query 与可选的 num_documents,返回 Optional[List[dict]]。dict 中可含 titlecontent 等字段;未命中时返回 None 而非空列表;
  2. 接入即工具:示例注释说明——当设置了 knowledge_retriever 时,search_knowledge 默认即为 True,该函数会被包装为 Agent 的 search_knowledge_base 工具。这与 libs/agno/agno/agent/_default_tools.py 的实现完全对应:工具的检索函数"优先调用 knowledge_retriever,未设置时才回退到 knowledge.search()";
  3. 示例本身是占位实现:文件头部注释明确写着 "In production, this could call an external API, database, or search engine"——示例用三篇内存文档 + 关键词匹配演示协议,生产环境中把函数体换成任意后端调用即可无缝接入 Agentic RAG。

八、控制引用格式:references_format

references_format.py 关注的是给模型的"检索证据"如何排版:

agent = Agent(
    model=OpenAIResponses(id="gpt-5.2"),
    knowledge=knowledge,
    search_knowledge=True,
    # Format knowledge references as YAML instead of the default JSON
    references_format="yaml",
    markdown=True,
)

文件 docstring 明确指出:默认情况下引用以 JSON 返回;将 references_format 设为 "yaml" 则改为 YAML。当多个文档被检索回来时,JSON 数组与 YAML 缩进块在 token 占用与模型可读性上会有差异——YAML 往往更紧凑易读,是降低上下文冗余的一种低成本手段。在源码侧,references_format 正是 search_knowledge_base 工具内部决定引用内容以何种结构返回的判断依据(见 libs/agno/agno/agent/_default_tools.pyif agent.references_format == "json": ... 的分支)。

九、验证与排障:以 TEST_LOG 为参照

目录内的 TEST_LOG.md 记录了 2026-02-13 在 .venvs/demo/bin/python + pgvector 环境下的逐文件实测结果,可作为运行预期与排障基线:

示例 结果 说明
agentic_rag.py PASS(18s) 无额外依赖
custom_retriever.py PASS(10s) 无需向量库
knowledge_filters.py PASS(14s) 需 pgvector
references_format.py PASS(13s) 需 pgvector
traditional_rag.py PASS(12s) 需 pgvector
agentic_rag_with_reasoning.py FAIL 缺少 cohere 依赖
agentic_rag_with_reranking.py FAIL 缺少 cohere 依赖
rag_custom_embeddings.py FAIL 缺少 sentence_transformers 依赖

对照此表可快速定位问题:报 ModuleNotFoundError: No module named 'cohere' 就执行 uv pip install cohere,报 sentence_transformers 缺失则补齐对应包。此外,凡是 db_url="postgresql+psycopg://ai:ai@localhost:5532/ai" 的示例都依赖 ./cookbook/scripts/run_pgvector.sh 启动的容器(ai:ai@localhost:5532 为该脚本的默认连接串);凡是使用 LanceDB 的示例则无需容器但会在 tmp/lancedb 下生成本地库文件。

十、延伸阅读建议

想深入这些示例背后的机制,建议继续精读以下仓库路径:

结语

通过 cookbook 02_agents/07_knowledge 这 8 个示例,可以清晰看到 agno 在 RAG 上的设计主线:以 Knowledge + VectorDB 为统一数据底座,通过 add_knowledge_to_context(传统注入)与 search_knowledge(工具化检索)两种开关切换范式,再用 rerankerReasoningToolsknowledge_filtersknowledge_retrieverreferences_format 等旋钮逐级调优检索质量、控制成本与输出结构。无论你的数据是 PDF、URL、纯文本,还是藏在内部系统中的专有接口,都能在 agno 上以"先跑通传统 RAG → 升级 Agentic RAG → 叠加重排/过滤"的路径快速落地一套生产可用的知识问答能力。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391