本节摘要:模型的知识停在训练时点,公司内部文档、最新产品说明它一概不知。知识库解决这个问题:把文档导入向量数据库,智能体在回答前先检索相关内容,再结合检索结果生成答案——这就是检索增强生成(RAG)。本节用"产品文档问答"完整跑通这一流程。
阅读完本节,你应当能够:
"我们的产品支持哪些协议?""这个接口怎么调?"——这类问题模型答不了,因为答案在你的私有文档里,不在它的训练数据中。把文档喂给模型重新训练不现实,于是有了 RAG:回答问题时,先到文档库里检索相关片段,把片段拼进上下文,再让模型基于片段作答。知识库就是这套流程的"文档仓库"。
两段式流程:入库阶段把文档分块、向量化、存库;问答阶段把问题向量化、检索相似片段、拼入上下文让模型作答。智能体回答的是"检索到的内容",而不是模型自己背下来的旧知识。
Agno 中知识库由两部分组成:向量数据库(存向量,如 LanceDB)与知识来源(文档,如 PdfSource、UrlSource)。Source 负责读文档,VectorDB 负责存与检索,两者组合成一个 Knowledge 对象。
pip install agno lancedb # 解析 PDF 需要额外支持,按需安装
from agno.agent import Agent from agno.knowledge import AgentKnowledge from agno.vectordb.lancedb import LanceDb from agno.document.pdf import PdfReader # 1. 初始化向量数据库 vectordb = LanceDb(table_name="product_docs") # 2. 定义知识来源:读入 PDF 文档 knowledge = AgentKnowledge( reader=PdfReader(), vectordb=vectordb, ) # 3. 导入知识到向量库 knowledge.load_documents("product_manual.pdf") # 4. 创建智能体并挂载知识库 agent = Agent( name="doc_bot", knowledge=knowledge, search_knowledge=True, instructions=["优先依据知识库内容回答,知识库没有就明说"], ) # 5. 提问 agent.print_response("我们的产品支持哪些通信协议?")
五步走完:建库 → 定源 → 导入 → 挂载 → 问答。search_knowledge=True 是关键开关——它让智能体在回答前自动检索知识库。
💡 关键直觉:
search_knowledge=True决定智能体"要不要查知识库"。忘了开这个参数,知识库等于白挂——智能体会忽略它直接凭模型知识回答。
| 来源 | 类 | 适用 |
|---|---|---|
| PDF 文档 | PdfReader | 手册、报告 |
| 网页 | UrlReader | 官网、文档站 |
| 文本/文本文件 | TextReader | 笔记、规范 |
| CSV | CsvReader | 表格数据 |
| 现象 | 调整方向 |
|---|---|
| 答不到点子上 | 提高检索返回片段数,或改善文档分块粒度 |
| 知识过时 | 重新 load 最新文档 |
| 检索不到内容 | 确认文档已导入、向量库非空 |
| 回答太泛 | instructions 加"必须引用知识库内容" |
| 幻觉依旧 | 加"知识库没有就明说不知道"指令 |
⚠️ 常见坑:知识库只能缓解幻觉,不能根除。模型仍可能把检索到的片段和自己编的内容混在一起。生产环境要加"引用来源"要求,重要场景人工复核。
文档会变,知识库要跟着更新。简单场景每次全量重导(数据量小无所谓);大知识库用增量导入、按版本分表。定时任务里把"拉取新文档 → 入库 → 切换表"做成流水线,保证智能体永远回答最新内容。
原始文档的示例是一个"泰国美食专家"智能体,五步流水线值得完整复述,因为每一步都对应一个可复用的动作:
from agno.db.base import Db from agno.knowledge.vector import VectorDb # 向量库 from agno.knowledge.pdf import PdfSource # PDF 知识源 from agno.vectordb.lancedb import LanceDb # 1. 初始化向量数据库(本地文件型,零部署) vector_store = LanceDb(uri="temp/lancedb") # 2. 定义知识来源:一份泰国菜 PDF 文档 source = PdfSource(path="docs/thai_food.pdf") # 3. 导入知识:切块、向量化、入库(仅首次或文档更新时执行) vector_store.ingest(source) # 4. 创建智能体并关联知识库 chef_agent = Agent( knowledge=vector_store, instructions=["只依据检索到的内容回答,检索不到就直说"], ) # 5. 对话验证 chef_agent.print_response("泰国绿咖喱和红咖喱有什么区别?")
五步里最容易被误解的是第三步。ingest 是重操作:解析 PDF、切块、逐块调用嵌入模型、写入向量库,一份大文档可能要几分钟。它属于"建库"动作,与"问答"彻底分离——日常运行时向量库里已经有数据,智能体只做检索。原始示例特意把 ingest 那行注释掉并写明"除非需要重建知识库",就是怕初学者每轮都重导。
知识库问答的效果上限由两件不起眼的小事决定:怎么切块、怎么检索。
切块的矛盾在于粒度。块太大,一块里混多个主题,检索命中了但噪声多;块太小,上下文被切碎,答案支离破碎。经验起点是一两百词一块,允许相邻块保留少量重叠,然后拿真实问题回归测试调整。文档结构好的(章节清晰)按结构切,比机械定长好得多。
检索侧的关键词是"相关"而非"相似"。问题向量和文档块向量算相似度只是手段,真正要的是能支撑回答的片段。指令层面的兜底很重要:明确要求"只依据检索内容回答、检索不到就承认",能显著压低模型脑补的比例——这正是示例指令的用意。
| 现象 | 病因 | 调整方向 |
|---|---|---|
| 答非所问但引经据典 | 检索命中了错误片段 | 调块大小、换嵌入模型 |
| 一问三不知 | 压根没检到相关块 | 检查是否已 ingest、查询改写 |
| 答案支离破碎 | 块过小缺上下文 | 加大块或重叠区 |
| 旧信息当新知识 | 文档更新后未重建 | 重新执行 ingest |
| 长文档答得慢 | 检索返回块过多 | 收紧返回数量上限 |
⚠️ 常见坑:把企业全部文档一股脑塞进一个库,指望"总有一块能命中"。库越大,噪声越多。按业务域分库、给智能体配对的库,通常优于万能大库。
知识库管线里还有两个上游决策值得展开。一个是嵌入模型的选择:它决定"语义相近"在数学上意味着什么。选型时看三点——中英文效果(中文语料要选中文友好的)、维度与成本(维度高表达强但存储检索都贵)、与检索库的兼容性。评估方法沿用前面说的自测集:固定一批业务问题,换模型跑检索对比命中率,让数据拍板。切忌盲目追新,嵌入模型的提升常常不如把切块策略调对来得大。
另一个是知识更新策略。个人文档场景随手重建索引就好;企业场景要讲究:高频变更的知识(价格、库存、活动)考虑单独建"热库",更新勤、体积小;稳定的知识(产品手册、政策条文)放"冷库",偶发重建。冷热分库后,重建热库的成本被压到分钟级,知识时效性与维护成本都顾住了。
权限是文档进库前要想清的第三件事。谁的文档谁能查——按部门或角色拆库、检索时按用户身份过滤,是最朴素的实现。把全公司的文档混进一个库再指望指令约束"别泄露",是安全上的一厢情愿。
知识频繁更新、需要溯源、场景多样,选知识库;要改变的是文风、格式这类"行为模式",微调更合适。两者也能叠加。多数业务问题其实是"知识没喂到",先上知识库,成本最低见效最快。
PDF 是教程主用的例子,框架对常见文档格式与网页、数据文件都有对应的源适配。统一抽象是"Source":解析、切块、入库的动作一致,换格式只是换一个源类。
可以按主题组合。但组合越多检索噪声越大,更推荐的做法是按业务拆智能体或拆团队,每个成员守自己的库。
知识库智能体好用,但不是所有"让智能体更聪明"的需求都该用它解。判断的第一条:知识变化频率。如果知识每天都在变且结构规整(比如商品价格),它更适合放在数据库里由工具查询,而不是切块向量化——检索增强的优势在非结构化的文本知识,结构化数据走结构化通道永远更准。第二条:答案的确定性。需要精确计算的问题(汇率换算、库存数量)交给工具或代码,检索到的相似文本替代不了算术。第三条:知识的规模。总共就二十条问答对的话,直接塞进指令上下文比建一套向量库简单可靠得多。
划清边界后,知识库的真正主场浮现出来:篇幅长、更新慢、以自然语言为主的领域知识——产品手册、政策文件、技术文档、案例库。这类知识既塞不进上下文也不适合结构化,检索增强恰好在它们身上威力最大。选对战场,再谈调优,方向错了优化越多偏得越远。
实践里最省力的验证方法是先问一句:"这个知识如果给一个新员工,是发他一份文档让他查,还是教他一个公式让他算?"前者是知识库的地盘,后者交给工具。
进阶一阶的做法是给每个知识块附加元数据:来源文档、章节、更新时间、适用范围。成本只是入库时多写几个字段,收益却贯穿整个生命周期——检索时可以按元数据过滤(只搜今年更新的政策)、回答时可以标注出处(依据某文档第几节)、清理时可以按时间批量下架过期内容。没有元数据的库越用越浑,有元数据的库越用越清,这是知识库工程里投入产出比最悬殊的一个细节。
元数据该有哪些字段,由你的运营动作反推:打算按部门隔离就加部门字段,打算做时效管理就加时间字段,打算溯源到原文就加位置字段。先想清楚将来要怎么管,再决定现在存什么,这个顺序反过来就会反复重建索引。
智能体有了"外脑",下一节让它"组团队"——多个专业智能体分工协作,处理单打独斗搞不定的任务。