Agno 从入门到精通(二):工具、知识库与记忆,让 Agent 真正可用

📅 2026/8/3 19:00:05
Agno 从入门到精通(二):工具、知识库与记忆,让 Agent 真正可用
Agno 从入门到精通二工具、知识库与记忆让 Agent 真正可用上一篇我们把 Agno 的第一层跑通了什么是 Agno为什么它最近在 Agent 框架里热度很高以及怎样写一个只读项目清点智能体。如果说第一篇解决的是“Agent 能不能跑起来”这一篇要解决的是更关键的问题Agent 怎样从一个会聊天、会调工具的 demo 变成一个能查知识、记住上下文、受工具边界约束、并且后续可服务化的系统这个问题很朴素但也很容易被低估。很多 Agent demo 看起来惊艳是因为只处理一轮对话、一个工具、一个理想问题。真正放进业务系统时问题马上变得现实用户问的问题来自公司知识库不在模型预训练语料里。用户会追问“刚才那个方案为什么这么排”Agent 需要记住会话历史。用户会让 Agent “顺手保存一个跟进事项”这就从只读问答变成了写操作。工具调用一多就要考虑权限、成本、次数限制和失败回滚。线上出错以后团队需要知道到底是模型错、检索错、工具错还是上下文错。所以 Agno 第二篇我不打算继续堆概念而是围绕四个最实用的基础能力展开Tools 让 Agent 做事 Knowledge 让 Agent 查资料 Storage 让 Agent 记住本次会话 Memory 让 Agent 记住用户长期事实最后我们会实现一个“小型技术支持知识库 Agent”它能先查本地知识库再按步骤回答并且在用户明确要求时调用自定义工具记录跟进事项。本文基于检索到的 Agno 官方文档、GitHub、PyPI 和 Git 标签快照整理。数据会变化代码接口也可能随版本演进具体工程里请以你安装版本的官方文档为准。1. 先看当前快照Agno 仍在高速迭代先补一眼最近状态避免我们拿着过期印象写系列文章。截至 2026-08-03 通过 GitHub API 抓取的快照项目信息主仓agno-agi/agnoGitHub 描述Build, run, and manage agent platforms.许可证Apache-2.0star / fork约 41551 stars / 5725 forks最近 push2026-08-03T03:34:06Z当前 PyPI 版本agno 2.8.6PyPI 上传时间2026-07-30T13:52:18Z最新 GitHub Releasev2.8.62026-07-30 发布和上一篇写作时的2.8.5相比2.8.6的变化很有代表性。Release notes 里新增了 Smallest AI 文本转语音工具、OpenSearch 向量数据库支持、AgentOS 指标刷新状态接口也修复了 AgentOS 指标刷新阻塞 worker、工具包装时重复读取 Pydantic 版本造成的热路径开销等问题。这些更新说明 Agno 的重点并不只是“再接一个模型”或“再加一个小工具”而是在补三个生产化方向更多工具与外部系统连接。更多知识库/向量库选择。更强的运行时观测、指标和后台任务能力。再看官方组织下的 AgentOS 模板仓库也能看到这个趋势。agentos-railway、agentos-docker、agentos-aws、agentos-gcp、agentos-azure、agentos-fly、agentos-render、agentos-modal、agentos-helm等仓库在 2026-07-29 附近集中更新说明 Agno 的设计重心已经明显从 SDK 走向“Agent 平台怎么部署、管理、观测”。这也是本系列后续的主线第一篇跑通一个 Agent 第二篇工具 知识库 会话让 Agent 有用 第三篇Storage、Memory、Learning做长期可改进的 Agent 第四篇AgentOS把 Agent 服务化 第五篇Teams / Workflows多智能体与流程编排 第六篇评测、Tracing、权限与上线清单当然节奏可以调整。这一篇先把最常用的四块基础能力讲透。2. Tools工具不是插件列表而是 Agent 的行动边界在 Agno 里工具可以是官方 Toolkit也可以是你自己写的 Python 函数。官方Agent with Tools示例用的是HackerNewsTools()而Custom Tool for Self-Learning示例强调了一个很重要的点任何函数都可以成为工具但函数名、类型注解和 docstring 会直接影响模型是否能正确调用它。初学时可以这样理解LLM 负责判断“现在该不该调用工具、该传什么参数” Agno 负责把 Python 函数或 Toolkit 包装成模型能看懂的 schema 工具函数负责真正执行外部动作 工具结果再回到模型上下文里继续生成最终回答。这比“给模型一个插件”更严肃。因为工具一旦能写数据库、发邮件、下单、删文件、发消息它就不再是展示能力而是进入了业务系统的权限边界。2.1 工具函数怎么写一个好的工具函数至少满足五点要点原因函数名清晰模型会根据名字判断用途参数有类型注解Agno 可以构建更明确的工具 schemadocstring 写清楚使用场景这是给模型看的说明书返回结构化结果方便模型继续推理和引用副作用明确写文件、发请求、改数据库都要被标出来比如一个记录跟进事项的工具可以这样写fromdatetimeimportdatetime,timezonefromtypingimportLiteralimportjsondefrecord_follow_up(owner:str,task:str,priority:Literal[P0,P1,P2]P1,)-str:Record a follow-up action item after the user asks for one. Args: owner: Person or team responsible for the follow-up. task: Concrete action that should be tracked. priority: P0 for urgent, P1 for normal, P2 for low priority. item{owner:owner,task:task,priority:priority,created_at:datetime.now(timezone.utc).isoformat(),}withopen(support_action_items.jsonl,a,encodingutf-8)asf:f.write(json.dumps(item,ensure_asciiFalse)\n)returnfRecorded follow-up for{owner}:{task}({priority})这里的重点不是这段代码多复杂而是它的边界很清楚只有一个动作记录跟进事项。参数都是业务可理解的词。priority用Literal限制枚举。docstring 明确说明“用户要求后才记录”。返回值是明确确认不让 Agent 猜执行结果。2.2 工具不是越多越好很多人做 Agent 的第一反应是“把能接的工具都接上”。这通常会带来三个问题。第一选择空间变大。模型看到几十个工具时会更难判断该用哪个尤其是工具名和参数描述不清楚时。第二权限面扩大。一个只需要查知识库的客服 Agent不应该顺手拥有删除订单、修改用户等级、批量发邮件的能力。第三排错更困难。回答错了你很难判断是模型理解错、检索错、工具错还是工具之间互相干扰。Agno 官方示例里有两个很实用的控制点tool_choiceauto# 让模型自己决定是否调用工具tool_choicenone# 禁止工具调用tool_call_limit1# 限制一次运行最多调用几个工具工具治理的基本原则可以写成一句话只暴露当前任务需要的最小工具集只读工具默认允许写操作需要明确触发高风险工具要审批。3. KnowledgeAgentic RAG 不是“把资料塞进 prompt”第二块是 Knowledge也就是知识库。Agno 官方文档对Agent with Knowledge的说明很直接Knowledge 给 Agent 一个运行时可搜索的知识库这种模式叫 Agentic RAGAgent 会根据用户问题决定什么时候搜索。这和传统 RAG 的区别在于传统 RAG 用户问题 - 系统固定检索 - 拼接上下文 - 调模型 Agentic RAG 用户问题 - Agent 判断是否需要检索 - 调用知识库搜索工具 - 基于结果继续回答看起来只是顺序差异工程含义却很不同。在传统 RAG 中检索通常是固定前置步骤。无论用户问什么系统都先查一遍知识库。这样简单、稳定、容易评估但灵活性有限。在 Agentic RAG 中知识库搜索变成 Agent 可以主动调用的工具。它可以先判断问题是否需要外部资料也可以在回答中途发现信息不足再检索。灵活性更高但也带来新问题模型可能忘记检索、检索太多、检索错方向或者把低质量片段当成证据。3.1 Agno 的 Knowledge 基础结构官方示例大概是这种结构fromagno.knowledge.embedder.openaiimportOpenAIEmbedderfromagno.knowledge.knowledgeimportKnowledgefromagno.vectordb.lancedbimportLanceDb,SearchType knowledgeKnowledge(vector_dbLanceDb(uritmp/lancedb,table_namerecipes,search_typeSearchType.hybrid,embedderOpenAIEmbedder(idtext-embedding-3-small),),)knowledge.insert(urlhttps://example.com/document.pdf,)它背后有几件事组件作用Reader读取 PDF、文本、URL 等内容Chunking把文档切成适合检索的片段Embedder把文本转成向量Vector DB存储向量并支持相似度检索SearchType控制语义、关键词或混合检索Agent search tool让 Agent 在需要时搜索知识库Agno 文档里的 LanceDB 示例使用SearchType.hybrid也就是语义检索和关键词检索结合。这个细节很重要很多企业知识库里有版本号、错误码、产品名、客户 ID、配置项单靠语义检索容易漏掉只靠关键词检索又抓不住同义表达。混合检索通常是更稳的起点。3.2 Knowledge 的三个常见坑第一个坑是“资料越多越好”。不是。知识库越大越需要元数据、过滤条件、chunk 策略和评测集。否则 Agent 查到的可能只是“看起来相关”的片段。第二个坑是“不区分知识来源”。正式手册、历史工单、Slack 讨论、个人笔记的可信度不同。生产环境里最好给知识片段加来源、时间、版本、作者、业务线等 metadata。第三个坑是“检索结果直接当真”。RAG 不是证明系统。Agent 应该告诉用户依据来自哪里、是否有资料缺口、哪些结论需要人工确认。我更建议初期把 Knowledge 当成“受控证据池”而不是“万能知识外挂”。4. Storage会话历史不是 Memory很多人会把 Storage 和 Memory 混在一起。Agno 文档分得很清楚能力保存什么作用范围典型问题Storageconversation history按 session“刚才我们说到哪”Memoryuser preferences and facts按 user 跨会话“这个用户长期偏好什么”先说 Storage。Storage 解决的是会话连续性。比如第一轮用户问帮我分析知识库检索慢的问题。第二轮用户接着问刚才你说的第一步为什么优先如果没有 Storage 和历史上下文Agent 很可能不知道“刚才”指什么。Agno 的Agent with Storage示例展示了这种写法fromagno.db.sqliteimportSqliteDb dbSqliteDb(db_filetmp/agents.db)agentAgent(dbdb,add_history_to_contextTrue,num_history_runs5,)agent.print_response(Give me a quick analysis of NVIDIA,session_idfinance-session)agent.print_response(Compare that to AMD,session_idfinance-session)关键参数是db保存运行、会话等状态。session_id同一个会话线程。add_history_to_contextTrue把历史消息放回上下文。num_history_runs5控制最多带入多少轮历史。为什么要限制历史轮数因为上下文不是垃圾桶。历史越多成本越高噪声越多模型越可能被无关旧信息带偏。5. Memory长期记忆要少而准Memory 解决的是另一个问题用户长期事实或偏好。比如这个用户偏好中文回答。 这个用户是平台工程师。 这个用户关注私有化部署和安全审计。 这个用户不希望 Agent 自动执行写操作。这些信息不属于某一次会话而是跨会话都可能有用。Agno 官方Agent with Memory示例里MemoryManager和enable_agentic_memoryTrue会让 Agent 具备更新用户记忆的能力。但 Memory 是一把双刃剑。它带来个性化也带来治理问题什么可以记谁可以看用户能不能删除记错了怎么改是否会把短期上下文误提升为长期事实我自己的建议是第二篇实践先不自动启用长期 Memory只使用 Storage 保存会话历史。等你把工具和知识库跑稳再进入长期 Memory。因为长期记忆一旦质量差会持续污染后续对话。一个实用规则是Storage 默认可开Memory 谨慎开启。6. 四块能力合起来一个可用 Agent 的最小架构到这里Agno Agent 的可用结构就比较清楚了用户问题 - Agent 读取当前指令、会话历史、用户上下文 - 判断是否需要搜索 Knowledge - 如需检索调用 knowledge search tool - 判断是否需要业务工具 - 如需执行调用受限工具 - 组合证据、工具结果和历史上下文 - 输出答案 - 会话写入 Storage - 必要时更新 Memory 或记录学习这一套里面模型只是一个决策器。真正让系统稳定的是边界Knowledge 限定依据来源。Tools 限定动作范围。Storage 限定会话连续性。Memory 限定长期用户事实。Tracing 限定排错路径。Approval 限定高风险动作。如果没有这些边界Agent 很像一个很聪明但没有岗位职责的人它什么都想帮忙但你很难放心把真实系统交给它。7. 实践做一个技术支持知识库 Agent下面做一个小实践目标不是炫技而是把 Tools、Knowledge、Storage 三件事组合起来。它会把几段技术支持手册写入本地知识库。使用 LanceDB 做本地向量库。使用 SQLite 保存会话历史。暴露一个record_follow_up自定义工具。要求 Agent 先查知识库再回答。只有当用户明确要求“记录/保存/跟进”时才调用写工具。7.1 安装依赖uv venv--python3.12source.venv/bin/activate uv pipinstall-Uagno openai lancedb sqlalchemyexportOPENAI_API_KEYyour_openai_api_key_here如果你不想发送 Agno 遥测事件可以按官方 README 说明关闭exportAGNO_TELEMETRYfalse如果你没有gpt-5.2权限把代码里的模型 ID 改成你当前可用、并且支持工具调用的模型。7.2 完整代码保存为support_playbook_agent.pyfrom__future__importannotationsimportjsonfromdatetimeimportdatetime,timezonefrompathlibimportPathfromtypingimportLiteralfromagno.agentimportAgentfromagno.db.sqliteimportSqliteDbfromagno.knowledge.embedder.openaiimportOpenAIEmbedderfromagno.knowledge.knowledgeimportKnowledgefromagno.knowledge.reader.text_readerimportTextReaderfromagno.models.openaiimportOpenAIResponsesfromagno.vectordb.lancedbimportLanceDb,SearchType ROOTPath(__file__).parent TMPROOT/tmpTMP.mkdir(exist_okTrue)ACTION_FILETMP/support_action_items.jsonlPLAYBOOKS[{title:知识库检索慢的排查手册,body: 当用户反馈 RAG 或知识库检索慢时优先检查四类问题 1. 文档切分是否过碎导致检索候选过多。 2. 向量库是否只做语义检索缺少关键词或 hybrid search。 3. top_k 是否过大导致过多上下文塞进模型。 4. 是否每次请求都重复写入或重建索引。 推荐处理顺序 先确认是否重复 ingest再看向量库查询耗时然后调小 max_results 最后再评估 chunking、embedding 模型和 rerank。 ,},{title:工具调用安全边界,body: 给 Agent 暴露工具时默认采用最小权限 只暴露当前任务真正需要的工具写操作要有明确确认危险工具要有审批 工具返回值要结构化方便模型继续推理生产环境要记录 tool call、参数和耗时。 如果一个工具会写数据库、发邮件、下单、删除文件或触达外部用户 应当被视为高风险工具不能和普通只读查询工具混在一起。 ,},{title:会话历史与用户记忆的区别,body: Storage 保存的是一次会话的历史适合回答“刚才我们讨论了什么”。 Memory 保存的是跨会话的用户事实或偏好适合回答“这个用户长期偏好什么”。 不要把所有聊天历史都塞进 Memory。能从 session history 里恢复的内容 通常不应该提升成长期记忆。长期记忆应当少而准并允许用户查看、修改和删除。 ,},]dbSqliteDb(db_filestr(TMP/agents.db))knowledgeKnowledge(nameSupport Playbook,vector_dbLanceDb(uristr(TMP/lancedb),table_namesupport_playbook,search_typeSearchType.hybrid,embedderOpenAIEmbedder(idtext-embedding-3-small),),max_results4,contents_dbdb,)defseed_knowledge()-None:Insert the demo playbooks into the local knowledge base.fordocinPLAYBOOKS:knowledge.insert(namedoc[title],text_contentdoc[body],readerTextReader(),skip_if_existsTrue,)defrecord_follow_up(owner:str,task:str,priority:Literal[P0,P1,P2]P1,)-str:Record a follow-up action item after the user asks for one. Args: owner: Person or team responsible for the follow-up. task: Concrete action that should be tracked. priority: P0 for urgent, P1 for normal, P2 for low priority. item{owner:owner,task:task,priority:priority,created_at:datetime.now(timezone.utc).isoformat(),}withACTION_FILE.open(a,encodingutf-8)asf:f.write(json.dumps(item,ensure_asciiFalse)\n)returnfRecorded follow-up for{owner}:{task}({priority})support_agentAgent(idsupport-playbook-agent,nameSupport Playbook Agent,modelOpenAIResponses(idgpt-5.2),knowledgeknowledge,search_knowledgeTrue,tools[record_follow_up],dbdb,add_history_to_contextTrue,num_history_runs5,add_datetime_to_contextTrue,tool_call_limit4,instructions[你是一个谨慎的技术支持知识库助手。,回答前先搜索知识库优先依据知识库内容给出步骤。,如果用户明确要求记录、创建、保存或跟进事项才调用 record_follow_up。,不要编造不存在的内部流程资料不足时说明缺口并给出下一步排查建议。,输出使用中文 Markdown包含判断、排查步骤、风险提醒、是否需要跟进。,],markdownTrue,debug_modeTrue,)if__name____main__:seed_knowledge()session_iddemo-support-sessionuser_iddemo-usersupport_agent.print_response(客户反馈私有化部署后知识库检索变慢。请给一个排查顺序如果需要跟进请记录给平台组优先级 P1。,session_idsession_id,user_iduser_id,streamTrue,)support_agent.print_response(刚才你建议先检查哪两件事为什么,session_idsession_id,user_iduser_id,streamTrue,)7.3 这段代码在做什么先看 KnowledgeknowledgeKnowledge(vector_dbLanceDb(...),max_results4,contents_dbdb,)这里用 LanceDB 做本地向量库用OpenAIEmbedder做 embedding用SearchType.hybrid做混合检索。max_results4是一个很好的提醒不要把太多知识片段塞进上下文。上下文越多不一定越准很多时候只是越吵。再看seed_knowledge()knowledge.insert(namedoc[title],text_contentdoc[body],readerTextReader(),skip_if_existsTrue,)这对应官方文档里knowledge.insert(url/path/text_content)的用法。生产环境里可以把text_content换成 PDF、网页、S3、GCS、数据库文档等来源但原则相同先 ingest再检索。然后是自定义工具tools[record_follow_up]这说明 Agno 不要求你把所有工具都做成复杂类。一个普通 Python 函数只要命名、类型和 docstring 写得清楚就可以成为模型可调用工具。最后是 Storagedbdb,add_history_to_contextTrue,num_history_runs5,这让第二轮问题“刚才你建议先检查哪两件事”能够接上第一轮上下文。没有这组设置Agent 可能只看到一个孤零零的“刚才”然后开始凭空补全。7.4 为什么这个例子有意限制工具调用代码里有一行tool_call_limit4这不是装饰。生产 Agent 必须有资源和行为边界。如果工具是只读查询限制可以宽一点如果工具有写操作限制应该更严格。比如这个例子里record_follow_up会写本地 JSONL 文件所以 instruction 里明确写了如果用户明确要求记录、创建、保存或跟进事项才调用 record_follow_up。这就是一种轻量的工具治理。更严肃的生产系统里还应该加写操作二次确认。高风险工具 human approval。工具参数校验。工具执行审计。失败重试与幂等键。按用户角色动态暴露工具。Agno 后面可以通过 AgentOS、Approvals、Authorization、Tracing、MCPServerConfig 等机制继续加强这件事。第二篇先把心智模型建立起来。8. 从这个例子推广什么时候用 Tools、Knowledge、Storage、Memory可以用这张表做判断需求应该用什么不该怎么做Agent 需要查实时外部数据Tools / Toolkit把过期数据写死进 promptAgent 需要查企业文档Knowledge把整本文档塞进系统提示词用户会连续追问Storage让模型猜“刚才”指什么用户有长期偏好Memory把所有聊天历史都当长期记忆工具有写操作Tools approval / limit让模型自由执行上线后要排错Tracing / logs只看最终回答多入口调用 AgentAgentOS API / MCP每个入口单独复制一套逻辑这也是 Agno 和很多轻量 Agent wrapper 的区别。它不只关心“这一轮模型怎么回答”还关心运行状态放哪里。工具调用怎么记录。Agent 如何变成 API。如何接 Slack、Telegram、WhatsApp、AG-UI、A2A、MCP。如何做 tracing、authorization、scheduler。如何在 Control Plane 里管理运行态。9. 生产化时最容易忽略的五个细节9.1 工具返回值要可被模型消费不要让工具返回一大段格式混乱的日志。最好返回 JSON、短文本、表格或明确状态。坏例子done好例子{status:created,action_id:act_20260803_001,owner:platform-team,priority:P1}模型看到后能继续解释也方便前端展示。9.2 Knowledge 要有版本意识企业文档会过期。一个 2024 年的部署手册可能已经不适用于 2026 年的产品。知识库片段最好带上来源 URL 或文件名。文档版本。更新时间。业务线。可见范围。是否已废弃。如果缺少这些 metadataAgent 看起来在引用知识库实际上可能在引用“历史包袱”。9.3 Storage 不是越长越好num_history_runs要根据任务设置。客服排障可能需要最近 5 到 10 轮一次性数据问答可能只要 2 到 3 轮代码生成长会话可能需要摘要机制。上下文历史的价值会衰减但 token 成本不会自动衰减。9.4 Memory 要允许纠错如果 Agent 记住了“用户偏好英文回答”但用户后来改成长期希望中文回答系统必须允许更新。记忆系统没有编辑和删除能力会很快从个性化变成污染源。Agno AgentOS 的 Memory API 提供了 create/list/update/delete 等操作这一点在做产品时很重要。9.5 Tracing 是上线前就该加的Agno 的 AgentOS tracing 文档说明tracingTrue可以记录 run、模型调用、工具调用、团队协作、workflow step 等 span并存入 Agno database。这不是锦上添花。没有 tracing你只能看到“最终答案错了”。有 tracing你能看到Agent 有没有查知识库。查到了哪些片段。调了哪个工具。工具参数是什么。哪一步耗时最长。哪一步报错。这会决定你是盲修 prompt还是能真正定位系统问题。10. 第二篇小结Agno 的关键不是“会调工具”而是边界清楚这一篇我们把 Agno 的基础能力往前推了一步。第一篇里Agent 像一个会读目录的小助手。第二篇里它开始像一个可以接入业务知识和业务动作的小系统Tools 让它能做事。Knowledge 让它有依据。Storage 让它能接住多轮上下文。Memory 让它未来能理解用户长期偏好。tool choice、tool call limit、instruction 让它不至于乱动。AgentOS、Tracing、MCP 给后续服务化和治理留下接口。我的判断是Agno 最近真正值得关注的不是它能不能写一个简单 Agent。简单 Agent 现在很多框架都能写。它更有价值的地方在于它把 Agent 周边那些“不性感但很要命”的工程能力放到了主线上包括 storage、knowledge、memory、approval、tracing、authorization、scheduler、MCP、部署模板和 Control Plane。如果你只是写一个周末 demo可能感受不明显。但如果你要把 Agent 接进客服、数据分析、代码平台、企业知识库、内部自动化系统这些能力会从“可选项”变成“救命绳”。下一篇我会继续沿着系列往下走重点讲 Agno 的 Storage、Memory 与 LearningAgent 怎么从“每次重新认识你”变成“在可控边界里持续改进”。参考来源Agno GitHub 主仓https://github.com/agno-agi/agnoAgno READMEhttps://github.com/agno-agi/agno/blob/main/README.mdAgno PyPIhttps://pypi.org/project/agno/Agno v2.8.6 Releasehttps://github.com/agno-agi/agno/releases/tag/v2.8.6Agno Docs Indexhttps://docs.agno.com/llms.txtAgent with Toolshttps://docs.agno.com/agents/usage/agent-with-toolsAgent with Knowledgehttps://docs.agno.com/agents/usage/agent-with-knowledgeAgent with Storagehttps://docs.agno.com/agents/usage/agent-with-storageAgent with Memoryhttps://docs.agno.com/agents/usage/agent-with-memoryAgentic RAG examplehttps://docs.agno.com/examples/agents/knowledge/agentic-ragCustom Tool for Self-Learninghttps://docs.agno.com/examples/basics/custom-tool-for-self-learningTool Call Limithttps://docs.agno.com/examples/agents/tools/tool-call-limitTool Choicehttps://docs.agno.com/examples/agents/tools/tool-choiceAgentOS Runtimehttps://docs.agno.com/agent-os/overviewAgentOS Tracinghttps://docs.agno.com/agent-os/tracing/overviewAgentOS as MCP Serverhttps://docs.agno.com/agent-os/mcp/mcpAgno cookbook READMEhttps://github.com/agno-agi/agno/blob/main/cookbook/README.md