对Agno的Cookbook中的例子深入研究下。
最基本的Agent
源码
1 | """🗽 Basic Agent Example - Creating a Quirky News Reporter |
点评
对这个例子大体总结下:
- 目标:用 agno.Agent 快速创建一个带“纽约新闻记者”人格的对话代理。
- 风格来源:通过 instructions 设定语气、结构和结尾口号,形成稳定的人设输出。
- 演示场景:调用 agent.print_response(…, stream=True) 报道 “时报广场突发新闻”,并以流式打印结果。
上面纽约新闻记者的行为特性包括:
- 开头使用 emoji 的“标题党”风格。
- NYC 的语气、简洁且有趣的叙述、适度的本地俚语。
- 最后带固定的签名语(如“Back to you in the studio!”)。
- 强调“在有趣前提下仍要核实事实”的指令。
可调用工具的智能体
源码
1 | """🗽 Agent with Tools - Your AI News Buddy that can search the web |
点评
这个例子相比于第一个例子,其中的agent能够进行“搜索网络”(通过集成DuckDuckGo搜索工具)。提示词的最后,明确提出要通过“Web Search”来“Always verify facts”。
对于DuckDuckGo这个tool,具体实现是:
- 基类:继承自 agno.tools.toolkit.Toolkit ,通过“注册函数”的机制把搜索能力暴露为可调用工具
- 依赖:使用第三方库 ddgs 作为 DuckDuckGo 的元搜索客户端(需 pip install ddgs )
- 提供两个工具方法: duckduckgo_search (通用搜索)与 duckduckgo_news (新闻搜索)
如果想创建自己的Tool,可参考Agno Tool官方教程。
带知识库的智能体
源码
1 | """🧠 Agent with Knowledge - Your AI Cooking Assistant! |
点评
这个例子构建了一个“带知识的泰菜烹饪助手”代理,将本地知识库与网页搜索结合,优先使用可信 PDF 食谱知识,必要时用网页补充;
通过向量数据库检索 PDF 中的内容,实现“问答—检索—生成”的闭环。
核心组成:
- 知识库与向量检索:Knowledge + LanceDb,使用 SearchType.hybrid 与 OpenAIEmbedder(“text-embedding-3-small”) 进行嵌入与混合检索
- 知识来源:添加泰国菜谱 PDF ThaiRecipes.pdf,并在Agent的参数中传入Knowledge
- 工具:DuckDuckGoTools 用于网页搜索补充.
工作流程:
用户提问后,先查询向量知识库(优先且权威),若知识库不足或问题更适合网页,调用 DuckDuckGo 搜索进行补充,并清晰标注来自网页的信息,这些都是通过提示词实现的。
知识库核心目标是把原始资料(文件、URL、文本)转成可检索的“语义块”,通过向量数据库实现相似度检索,并按需融合关键字全文检索与重排序,供智能体生成答案。关键组件包括:
- Reader 读取与切分:按来源类型选择读取器(PDF/网页/CSV/文本),并进行分块与清洗,产出 Document 对象
- Embedder 向量化:将每个 Document.content 编码为向量,保存使用信息与维度
- VectorDb 存储与检索:负责落库、去重、相似度搜索、全文搜索与混合检索
- Knowledge 工作流:统一管理“添加内容→选择读取器→分块→嵌入→写入向量库→检索”
在该示例中使用了LanceDB,主要原因是:
- 零外部依赖、即开即用:本地文件型数据库,指定 uri=”tmp/lancedb” 即可使用,无需启动 Postgres 或外部服务,适合入门与轻量知识库
- 原生混合检索:支持 SearchType.hybrid 同时结合向量相似度与全文关键字查询,对 PDF 食谱这类结构化弱、名词专有名的内容检索效果更好
- 全文索引集成:内置创建 FTS 索引,默认用 tantivy 加速全文检索
- 性能与存储结构:基于 Arrow 列式格式,插入时固定维度存储,提高检索与转换效率
- 便捷的嵌入批处理与异步:支持批量异步嵌入以减少调用成本,插入/更新使用同步写入保证表一致性
与其它向量库的选择建议:
- 已有数据库基础设施:若团队已有 Postgres,选择 PgVector 更便于运维与数据共存;
- 云托管与大规模:需要多副本、向量专用引擎或托管服务时,可选 Pinecone 、 Qdrant 、 Milvus;
- 图检索与复杂关系:对关系与路径依赖强的内容可用 LightRAG
创建自定义工具
源码
1 | """🛠️ Writing Your Own Tool - An Example Using Hacker News API |
点评
这个例子演示了如何把一个普通的 Python 函数注册为代理可调用的“工具”,并通过该工具拉取 Hacker News 数据再由大模型进行总结,这个函数可以替换为任意外部 API 或本地能力(天气、股票、日程、数据库、文件操作等)。
工作流程:
- 用户提问与工具匹配:代理根据指令和问题语义决定调用工具函数(此处为 HN 拉取),工具返回结构化 JSON
- 模型生成:LLM读取工具返回的数据进行筛选、归纳、排序和写作,以设定的表达风格输出摘要与洞见
- 输出呈现:启用 markdown 与 stream ,提升可读性与交互体验
这里的工具将获取story的数量作为了入参,所以可以适配用户的具体的“拉取多少篇数据”的指令。
结构化输出
源码
1 | """🎬 Agent with Structured Output - Your AI Movie Script Generator |
点评
这个示例目的是:
- 展示如何用“结构化输出”约束代理返回结果的形状与字段,生成格式良好的电影概念
- 同时对比两种实现路径:传统的“JSON 模式”与更严格可靠的“结构化输出”模式
核心结构包括:
- 数据模型:用 pydantic 定义 MovieScript ,明确字段与描述,作为 output_schema 提示或约束
- 两个代理:
- JSON 模式代理: use_json_mode=True ,同样设置 output_schema
- 结构化输出代理:仅设置 output_schema ,不启用 JSON 模式
- JSON 模式
- 原理:把 output_schema 作为系统附加提示,引导模型“以 JSON 形式且包含指定字段”输出
- 实现参考:Agno 内部会构造 JSON 字段提示文案
- 优点:通用、几乎所有模型都支持;缺点:严格性依赖模型遵守提示,偶发字段缺失或格式偏差
- 结构化输出
- 原理:利用模型/提供方的“结构化输出能力”或函数调用能力,将 output_schema 作为强约束
- 可靠性:更稳定、字段更完整;在支持严格模式的大模型中,可设 strict_output=True 强制结构
- 退化路径:若大模型不支持严格模式,可用“guided mode”(如 strict_output=False )或退回 JSON 模式
改进建议:
- 错误处理:为 JSON 模式增加健壮的解析与字段缺失兜底逻辑,避免对下游处理造成影响
- 一致性校验:在拿到 RunOutput.content 后进行 pydantic 验证,确保字段类型与必填项符合预期
- 提示工程:适当强化风格与长度约束(例如对 storyline 的句子数、 characters 的数量范围)
- 严格模式优先:若模型支持,优先走“结构化输出(strict)”,当不支持时再回退 JSON 模式
适用场景:
- 需要“固定字段结构”的生成任务:产品文案、工单、报告、合规摘要、表单填充
- 与业务系统对接:前后端或数据管道期待稳定 JSON/对象结构,便于持久化与检索
带存储的智能体
源码
1 | """🧠 Agent with Storage - Your AI Thai Cooking Assistant! |
点评
示例概览
- 构建了一个“带存储的泰餐烹饪助手”,在保留知识库检索与网页搜索的同时,支持持久化会话与聊天历史
- 通过
SqliteDb管理会话与历史,支持“新会话/继续上次会话”的 CLI 交互
核心组成
- 知识库:
Knowledge + LanceDb + OpenAIEmbedder,使用混合检索SearchType.hybrid,添加泰菜 PDF - 模型与工具:
OpenAIChat作为模型,DuckDuckGoTools进行网页补充 - 存储层:
SqliteDb(db_file="tmp/agents.db")持久化会话与聊天记录 - CLI 入口:用
typer进行命令行交互并运行代理应用
工作流程
- 启动时询问是否开启新会话;若选择继续,读取用户的历史会话并复用
session_id - 创建智能体时注入
user_id与session_id,使得对话与上下文与用户绑定并可延续
存储与会话
- 会话读取:
db.get_sessions(user_id=user, session_type=SessionType.AGENT)获取历史会话并挑选一个继续 - 历史注入方式:
- 直接读取聊天历史:
read_chat_history=True(已启用) - 自动将历史加入模型上下文:
add_history_to_context=True(示例中给出可选注释)与num_history_runs控制注入条数
- 直接读取聊天历史:
- 会话可见性:启动或继续会话时打印
session_id以便确认与追踪
检索策略
- 优先知识库:使用向量+全文混合检索(
hybrid)提升召回与精准度,适合 PDF 菜谱这类专有名词密集内容 - 适时补充网页:当知识库不足或问题更适合网页信息,调用
DuckDuckGoTools搜索补充,并在回答中优先使用知识库结果
价值与场景
- 将“检索增强生成”与“持久化记忆”结合,适合知识助手、教程助手、客服问答等需要长周期多轮对话的应用
智能体状态
源码
1 | """Test session state management with a simple counter""" |
点评
原始代码报错
问题定位
- 异常来源:
get_session_state()调用会通过“读取会话”获取状态;当前代理未配置存储且未启用会话缓存,get_session()返回None,抛出 “Session not found” - 现象解释:你看到的递增结果来自运行期的
run_context.session_state,已用于渲染输出;但未持久化到数据库,也未缓存,会话读取失败
修复选项
- 选项 A(最简且推荐):使用
agent.run()获取返回对象并读取其中的session_state- 原理:
RunOutput.session_state在每次运行结束时由运行期状态填充,无需数据库 - 用法示例:把最后两行改成
run_output = agent.run("Let's increment the counter 3 times and observe the state changes!")print(f"Final session state: {run_output.session_state}")
- 原理:
- 选项 B(无需DB、当前进程可读):在创建
Agent时加cache_session=True,让会话缓存在内存中- 原理:运行过程中会创建会话对象;开启缓存后,
get_session()可返回缓存会话,get_session_state()不再报错 - 位置:
cookbook/getting_started/07_agent_state.py:30附近创建Agent的参数中加入cache_session=True
- 原理:运行过程中会创建会话对象;开启缓存后,
- 选项 C(持久化、跨进程可读):为
Agent配置数据库(如SqliteDb),并传入db与可选user_id- 原理:运行结束会执行
save_session,会话与session_state落库;get_session_state()从DB读取 - 参考实现:见带存储示例
cookbook/getting_started/06_agent_with_storage.py:49、:66–:70;需要依赖sqlalchemy
- 原理:运行结束会执行
验证步骤
- 选项 A:运行
python cookbook/getting_started/07_agent_state.py,检查最后输出应包含Final session state: {'count': 3, ...} - 选项 B:同上;确认不再出现 “Session not found”
- 选项 C:首次运行打印
Started Session: <session_id>;再次运行同一session_id仍可读取到状态
推荐选择
- 若仅需打印本次运行的最终状态且不需要跨进程保留,采用选项 A
- 若希望在同一进程里继续读取会话状态(不落库),开启
cache_session=True(选项 B) - 若需要持久化与跨进程可用的会话与历史,配置
SqliteDb(选项 C)
更多点评
这个例子演示了如何用会话状态驱动工具执行与回复生成,构建“能记住计数器”的轻量 Agent,本身无实际价值;但state本身具有很大价值:
概念与作用
- 状态是代理在会话中的“可编程记忆”,用于在多轮交互、工具执行之间传递和累积信息
- 入口与载体:
- 运行期状态:
RunContext.session_state,工具读写的共享字典 - 会话状态:持久化在会话对象里,从存储或缓存加载、合并与保存
- 运行期状态:
- 注入到模型上下文:
- 变量替换:
resolve_in_context=True把状态中的键作为模板变量注入指令libs/agno/agno/agent/agent.py:6842–:6847 - 明文附加:
add_session_state_to_context=True将状态以<session_state>...</session_state>段落加入系统消息
- 变量替换:
实际价值
- 工具协调与流程控制
- 在多次工具调用间维护进度、迭代计数、上次结果键,避免“从零开始”的推理与重复工作
- 例:计数器、分页抓取、重试策略、长期任务的阶段标记
- 个性化与偏好
- 存储用户偏好、语言风格、过滤条件,让回应保持一致并降低提示开销
- 将用户参数作为模板变量或状态段注入,使模型“看到”并遵守设定
- 事务型对话与跨轮记忆
- 在一次会话内保持结构化上下文(购物车、当前话题、待办项),与长期记忆系统(用户记忆、会话摘要)互补
- 与会话持久化结合可跨进程延续,
get_session_state()直接读存储状态
- 可控上下文注入与降噪
- 通过状态变量替换减少冗长 Prompt;通过选择性附加状态段,避免把不必要历史塞进上下文,降低 token 成本
- 支持“只注变量、不注全文状态”或“注入精选字段”的策略
libs/agno/agno/agent/agent.py:6993–:6995
- 可观测性与治理
- 状态中可记录工具执行痕迹、上次检索过滤条件、评价分数,便于响应审核、重放与实验
- 与会话指标联动:读取会话指标与更新逻辑
libs/agno/agno/utils/agent.py:757–:771
- 与检索/知识的协同
- 状态可持有“当前检索过滤器”或“内容主题”,与“代理自主选择过滤器”配合,提升 RAG 精度
libs/agno/agno/agent/agent.py:6788–:6812、:5389–:5407 - 在工具侧将过滤器与检索引用写回运行输出,形成可追踪的检索链路
libs/agno/agno/agent/agent.py:9472–:9512
- 状态可持有“当前检索过滤器”或“内容主题”,与“代理自主选择过滤器”配合,提升 RAG 精度
使用模式
- 初始化与合并
- 传入默认状态
session_state={...},运行时与存储状态按“运行参数 > DB状态 > 代理默认”顺序合并libs/agno/agno/agent/agent.py:5814–:5829 - 需要覆盖存储状态时设
overwrite_db_session_state=Truelibs/agno/agno/agent/agent.py:189、:527–:528
- 传入默认状态
- 让模型“自更新”状态
- 开启
enable_agentic_state=True后自动注入工具update_session_state,模型可主动写入状态键值libs/agno/agno/agent/agent.py:5375–:5377、:9458–:9470 - 适合“模型决定何时变更偏好/阶段”的场景,并保留可观测性
- 开启
- 读取与持久化
- 仅本次运行:从
RunOutput.session_state读最终状态(不依赖存储)libs/agno/agno/utils/print_response/agent.py:127–:137 - 同进程:
cache_session=True缓存会话,get_session_state()可用libs/agno/agno/agent/agent.py:5868–:5899 - 跨进程:配置
db(如SqliteDb)以保存与读取会话状态cookbook/getting_started/06_agent_with_storage.py:49、:66–:70
- 仅本次运行:从
设计建议
- 状态分层
- 短期运行时(ephemeral)用于工具协调;长期会话(persistent)用于用户偏好与业务上下文
- 注入策略
- 优先用模板变量传关键字段;必要时再附加
<session_state>,避免上下文过重
- 优先用模板变量传关键字段;必要时再附加
- 并发与一致性
- 明确“谁写状态”:工具、模型工具调用或业务逻辑;对可能的并发写做好合并与优先级控制
libs/agno/agno/agent/agent.py:5814–:5829
- 明确“谁写状态”:工具、模型工具调用或业务逻辑;对可能的并发写做好合并与优先级控制
- 安全与隐私
- 不将敏感信息直接注入状态或上下文;对持久化状态进行脱敏与访问控制
总结:智能体的 state 是把“上下文记忆”变成可编程的控制面,用来精准地引导工具链、降低提示成本、提升多轮一致性和可治理性。在 Agno 中,它既能在运行时高效传递,也能根据需要持久化与注入,从而让代理的行为更可控、更可观测、更贴近业务。
智能体上下文
源码
1 | """📰 Agent with Context |
点评
示例概览
- 展示把“外部依赖”作为上下文注入给代理:在每次运行前执行依赖函数,生成最新数据并写进提示信息
- 与“工具调用”不同:上下文依赖是预先计算并固定在消息里;工具则由模型在对话过程中按需调用
核心结构
- 依赖函数:
get_top_hackernews_stories(num_stories: int = 5) -> str抓取 HN Top IDs 并逐条获取详情,返回整洁的 JSON 字符串/Users/qixinbo/test/agno/cookbook/getting_started/08_agent_context.py:17–:40 - 代理配置:
dependencies={"top_hackernews_stories": get_top_hackernews_stories}将函数名映射到依赖变量- 在
instructions中使用{top_hackernews_stories}占位符,运行时自动替换为函数结果
工作机制与优势
- 运行时评估:每次
agent.print_response/agent.run前,依赖函数会被执行,确保上下文是“最新数据”而非陈旧缓存 - 上下文直达:把结构化 JSON直接拼入系统提示,模型无需再决定是否调用工具,降低一次性任务的复杂度
- 可控提示体量:通过函数裁剪字段(比如移除
kids)限制冗余,减少上下文负载 - 与工具的差异:
- 依赖:强制“输入前即注入”,适合确定性数据的“展示/分析”
- 工具:模型自主调用,适合“交互式信息获取或多步决策”
实践建议
- 数据体量控制:为依赖函数设置字段白名单与数量上限(
num_stories),防止提示超长 - 健壮性与性能:
- 为
httpx.get增加超时、重试与异常处理,避免网络波动影响生成 - 可加简单缓存(TTL)减少重复抓取,或在依赖函数接受
since/score等参数实现过滤
- 为
- 可读性与结构:
- 维持返回 JSON 的简洁与一致,避免把大段 HTML 或长文本注入提示
- 如需进一步程序化处理,考虑在指令中明确“需输出的结构化维度”(标题、链路、分项趋势)
- 何时改用“工具”:
- 需要模型“按需”抓取更多页或做交互式探索时,用工具而非依赖
- 需要在对话中多次调用同一接口(分页、筛选),用工具让模型在不同阶段自由选择参数
适用场景
- 报告类任务:把“最新数据快照”注入后让模型分析与总结(新闻、行情、监控)
- 依赖注入:将配置、上下文数据、环境信息注入提示,无需复杂的工具编排
总结
- 该示例展示“依赖即上下文”的模式:每次运行自动评估依赖并将结果注入提示,使 LLM 专注于分析与写作
- 在实际应用中,选择“依赖”或“工具”取决于是否需要“交互式调用与决策”,以及对上下文长度与时效性的要求
智能体会话
源码
1 | """🗣️ Persistent Chat History i.e. Session Memory |
点评
示例概览
- 构建“带持久会话记忆”的代理,使用
SqliteDb存储聊天历史与会话元信息,支持继续上次会话 - 在每次回答时将最近的历史消息注入上下文,提升多轮对话的一致性和连贯性
核心流程
- 会话选择与恢复:交互式选择“新会话/继续会话”,读取用户的历史
AgentSession并传入session_id - 代理初始化:配置
db=SqliteDb(...),开启历史注入add_history_to_context=True并限制条数num_history_runs=3 - 会话标识输出:启动或续接时打印当前
session_id,方便定位与追踪 - 历史可视化:调用
agent.get_messages_for_session(),以“用户消息 → 助手回复”的配对视图输出历史
关键点解析
- 历史注入机制:勾选
add_history_to_context=True时,代理在生成前将最近 N 次对话加入消息上下文,模型能“看到”先前语境 - 历史构建方法:
get_messages_for_session()将各轮用户消息与助手回复配对,过滤历史标记消息,便于展示与调试;实现见libs/agno/agno/session/agent.py:238–:271 - 会话读取与状态:使用
SqliteDb提供的get_sessions(user_id=..., session_type=...)拉取历史列表,选择一个session_id继续
优点点评
- 连贯性提升:通过注入最近历史,回答能够延续上下文,不再“断片”
- 生产可迁移:使用 SQLite 起步,后续可替换为 Postgres 等持久化库;接口不变,迁移成本低
- 可视化友好:将历史格式化输出便于调试和演示,快速验证历史注入是否按预期工作
改进建议
- 会话列表选择:当前默认选择第一个会话,可改为列出会话供用户选择,避免错误续接
- 注入策略优化:对长会话增加“摘要注入”,减少 token 压力;或结合
num_history_runs自适应调整 - 错误与回退:为数据库读写添加异常处理和回退逻辑(例如无历史则降级为新会话)
- 命名与检索:支持自定义
session_name与搜索,提升多会话管理体验;相关读取接口见libs/agno/agno/utils/agent.py:675–:681
适用场景
- 客服与咨询:需要跨多轮甚至多次会话保持上下文
- 学习助手与入门教程:能够回顾先前问题与结论,持续深化主题
- 任何需要“对话延续”的应用:把历史当作一等公民输入,提高相关性与用户体验
长周期用户记忆和会话摘要
源码
1 | """🧠 Long Term User Memories and Session Summaries |
点评
示例概览
- 目标:为代理加上“长期用户记忆 + 会话摘要 + 历史持久化”,并在响应时自然引用过去信息
- 存储:用
SqliteDb保存会话与记忆,支持跨会话继续对话和读取记忆
核心配置与机制
- 会话续接:交互式选择是否继续旧会话,若继续则取用户的第一个会话
session_id - 代理初始化:
- 记忆开关:
enable_user_memories=True - 摘要开关:
enable_session_summaries=True - 历史注入:
add_history_to_context=True和num_history_runs=3 - 个性化描述:强调“友好语气、使用记忆、真实回忆”
- 记忆开关:
记忆系统工作原理
- 管理器挂载:当启用用户记忆或显式提供管理器时,代理内部设置
MemoryManager/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:835–:839、:789–:805 - 默认注入策略:未显式设置时,
add_memories_to_context会被自动打开,只要启用用户记忆或有管理器/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:801–:805 - 自动提取记忆:
- 同步路径:在运行结束阶段调用
create_user_memories根据用户消息抽取并写入数据库/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:5238–:5267 - 异步路径:同逻辑的
acreate_user_memories/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:5279–:5310 - 当未启用“代理自主记忆”(
enable_agentic_memory=False)时,记忆创建在后台任务中并行进行/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:1008–:1010、:1224–:1226、:1860–:1862
- 同步路径:在运行结束阶段调用
- 读取与展示:示例调用
agent.get_user_memories(user_id=agent.user_id)并富格式输出/Users/qixinbo/test/agno/cookbook/getting_started/10_user_memories_and_summaries.py:107–:116,底层读取见libs/agno/agno/memory/manager.py:159–:172
会话摘要工作原理
- 管理器挂载:当启用摘要或显式提供管理器时,代理挂载
SessionSummaryManager/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:806–:818、:846–:848 - 生成时机:每次运行结束将本轮
RunOutput写入会话,再生成摘要并标记为已更新(同步与异步均支持)/Users/qixinbo/test/agno/libs/agno/agno/agent/agent.py:1094–:1101、:1947–:1953、:2266–:2285 - 摘要内容:系统提示要求输出简洁的
summary与topics列表/Users/qixinbo/test/agno/libs/agno/agno/session/summary.py:91–:116 - 读取与展示:示例用
agent.get_session_summary()打印摘要/Users/qixinbo/test/agno/cookbook/getting_started/10_user_memories_and_summaries.py:119–:137,数据结构见libs/agno/agno/session/summary.py:20–:41
历史注入与可视化
- 历史注入:最近
num_history_runs=3的消息进入上下文,提高连续性 - 历史配对展示:
agent.get_messages_for_session()以“用户→助手”的配对输出,便于审阅与调试/Users/qixinbo/test/agno/cookbook/getting_started/10_user_memories_and_summaries.py:91–:104,实现见libs/agno/agno/session/agent.py:238–:271
优点与价值
- 长期个性化:自动提取用户事实与偏好,并在后续会话自然引用,提升体验与一致性
- 语境浓缩:会话摘要减少 token 压力,提供“快速可读”的上下文摘要
- 生产友好:用 SQLite 起步,接口通用(可替换为其他 DB),历史与记忆读取 API 完整
改进建议
- 选择会话:当前默认续接第一个会话,可提供会话列表供用户选择,避免误续接
- 注入策略:长会话建议优先注入“摘要 + 少量关键历史”,权衡上下文长度与成本
- 健壮性:为 DB 读写与摘要/记忆生成增加异常与重试、超时设置;记录失败事件
- 隐私治理:避免把敏感信息写入记忆;为记忆增加话题过滤与脱敏策略;限制公开展示
适用场景
- 私人助理与客服:需要稳定记住用户信息与偏好,并跨会话延续
- 学习/辅导:会话摘要帮助持续复盘进度,记忆支持个性化建议
- 任务型对话:对历史与关键事实的稳定引用提升准确性
总结
- 该示例将“用户记忆 + 会话摘要 + 历史注入”整合为可生产的记忆体系:自动采集、可视化、可引用
- 默认策略合理且可扩展;按需优化会话选择、注入体量与隐私控制,可直接用于实际应用的多轮对话与个性化场景
补充点评
详细对比一下用户记录和聊天历史之间的区别。
核心区别
enable_user_memories=True- 启用“用户记忆系统”:从用户消息中自动抽取并存储事实/偏好等长期记忆到数据库,后续会话可复用
- 影响“记忆的生成与读取”,并可将记忆注入系统提示以引导模型个性化回答
- 相关实现:
libs/agno/agno/agent/agent.py:209–:216、:835–:839、:789–:805、:5238–:5267、:5279–:5310、:6858–:6869
add_history_to_context=True- 启用“聊天历史注入”:在当前生成前,把最近的原始聊天消息加入到本次模型上下文
- 影响“上下文拼装”,不做摘要或抽取,直接携带原始多轮内容,提升连贯性
- 相关实现:
libs/agno/agno/agent/agent.py:224–:227、:7621–:7653、:1536–:1539;历史读取:libs/agno/agno/session/agent.py:128–:220
分别适用场景
enable_user_memories- 长期个性化:记住姓名、城市、偏好、工作背景等,后续自然引用
- 跨会话延续:换会话也能读回记忆,适合私人助理、客服画像、学习档案
- 低上下文成本:将记忆以简短系统段落注入,减少 token 压力
- 代码参考:示例中启动记忆
cookbook/getting_started/10_user_memories_and_summaries.py:61,读取展示:107–:116;读取实现libs/agno/agno/memory/manager.py:159–:172
add_history_to_context- 近期语境连贯:需要严格引用上一轮或最近几轮的原话、工具结果、链路细节
- 一次性任务分析:对当前话题的短期连续跟进,避免“断片”
- 精准引用:原始消息进入上下文,不依赖摘要;适合需要保留对话细节的场景
- 代码参考:示例开启历史注入
cookbook/getting_started/10_user_memories_and_summaries.py:64;注入逻辑libs/agno/agno/agent/agent.py:7621–:7653;历史汇总libs/agno/agno/session/agent.py:128–:220
组合与取舍
- 可同时开启:既注入近期原始历史保证细节,又利用用户记忆提供长期个性化与低成本上下文
- 成本与隐私:
- 历史注入会增加上下文长度,长对话需控制
num_history_runs/num_history_messageslibs/agno/agno/agent/agent.py:224–:227 - 用户记忆涉及敏感信息时需治理(话题过滤、脱敏、访问控制)
- 历史注入会增加上下文长度,长对话需控制
- 依赖要求:
- 历史注入需要能读取会话(一般需配置
db),否则会警告并不注入libs/agno/agno/agent/agent.py:1536–:1539 - 用户记忆需要
db才能持久化与读取(未配db时会退化或警告)libs/agno/agno/agent/agent.py:789–:793
- 历史注入需要能读取会话(一般需配置
选择建议
- 需要“长期个性化与跨会话复用”→ 开启
enable_user_memories - 需要“当前多轮的原始上下文连贯”→ 开启
add_history_to_context并合理设置历史条数 - 对话很长/成本敏感→ 优先用记忆与摘要,历史注入限量或改用摘要注入
- 对话短且需要精准回顾→ 历史注入优先,记忆可按需开启
示例中的两行
enable_user_memories=True在10_user_memories_and_summaries.py:61用于开启记忆抽取与存储,后续通过agent.get_user_memories(...)查看add_history_to_context=True在10_user_memories_and_summaries.py:64用于把最近 3 轮(由num_history_runs=3控制)的原始消息加入本次模型上下文,保障回复衔接与引用准确
调用重试函数
源码
1 | from typing import Iterator |
点评
示例概览
- 演示在工具调用前通过
pre_hook执行校验逻辑,必要时抛出RetryAgentRun让代理自动重试并改写参数 - 通过计数控制前两次尝试触发重试,直到满足“更有趣”的参数再执行工具
核心机制
- 工具定义:
@tool(pre_hook=pre_hook)将预处理函数绑定到工具调用 - 预钩子签名:
pre_hook(fc: FunctionCall)能访问函数名与参数,打印并决策是否重试 - 重试控制:首次调用抛出
RetryAgentRun,代理捕获并“重新规划”,第二次通过后继续执行工具逻辑 - 输出与流式:工具本体打印输入并
yield文本,代理流式展示结果
关键代码与框架行为
- 异常类型:
RetryAgentRun标记“可重试”,不会终止整个运行libs/agno/agno/exceptions.py:23–:37 - 预钩子处理:框架在工具执行前调用
FunctionCall._handle_pre_hook,若抛出AgentRunException(含RetryAgentRun),将该错误冒泡到上层,由代理处理重试libs/agno/agno/tools/function.py:687–:719 - 事件流:预钩子会发出
PreHookStarted/Completed事件,便于观测与调试libs/agno/agno/run/agent.py:306–:331、事件创建libs/agno/agno/utils/events.py:198–:242
优点点评
- 可控质量门槛:在工具执行前强制参数满足条件(例如“更有趣”的输入、完整必填项、格式校验)
- 轻量化防御:通过抛出特定异常触发重试,避免在工具内部做复杂容错分支
- 可观测性:预钩子事件与日志让失败原因与重试过程可追踪
实践建议
- 重试信息:在
RetryAgentRun中提供清晰的user_message或agent_message,指导模型如何调整参数(示例里仅用字符串,可升级为结构化提示)libs/agno/agno/exceptions.py:23–:37 - 幂等性与副作用:预钩子应尽量无副作用;若需要维护状态(如示例中的
num_calls),注意并发与多会话隔离 - 终止条件:对于不可恢复错误改用
StopAgentRun直接终止并返回原因libs/agno/agno/exceptions.py:40–:54 - 参数自修复:结合工具描述与 few-shot,让模型在重试时能自动改写更合理的参数(比如从“boring”变成“funny”)
适用场景
- 参数校验:必填字段缺失、类型不符、范围不合理
- 内容质量:要求“非泛泛而谈”、更具创意或更具体的输入
- 资源约束:API 速率、额度限制时,预钩子判断是否需要降级或延迟执行
总结
- 该示例展示“预钩子 + 可重试异常”的简洁控制面:在工具执行链前卡住不合格输入,提示模型重试并改写参数
- 在真实项目中,配合更详细的重试指导与参数校验,可大幅提升工具调用的成功率和结果质量
人类在环
源码
1 | """🤝 Human-in-the-Loop: Adding User Confirmation to Tool Calls |
点评
示例概览
- 目标:为工具调用加入“人审环节”,在模型决定调用工具后暂停执行,等待用户确认,再继续或取消
- 方式:工具声明
requires_confirmation=True;代理运行返回“暂停态”,外部交互收集用户选择后用continue_run续跑
核心流程
- 工具定义:
@tool(requires_confirmation=True)标记该工具需要人工确认 - 代理初始化:注册工具与提示风格
- 触发与暂停:
agent.run(...)返回的响应若含需确认的工具则为暂停态,response.is_paused为 True - 人工确认:遍历
response.tools,提示工具名与参数,用户选择 y/n;若继续则将该工具的confirmed=True - 继续执行:调用
agent.continue_run(run_response=response),代理基于更新后的工具确认状态继续执行,输出结果
框架行为与事件
- 暂停事件:当工具需要确认时,模型层发出
tool_call_paused,代理组装为RunPausedEvent,携带待确认工具列表libs/agno/agno/models/base.py:1549–:1580、:1785–:1800,事件封装libs/agno/agno/utils/events.py:136–:157 - 暂停响应属性:
run_response.is_paused表示暂停libs/agno/agno/run/agent.py:547–:557tools_requiring_confirmation提供需要确认的工具集合(也可在集成里使用)libs/agno/agno/run/agent.py:553–:557
- 继续运行:
continue_run/acontinue_run接收更新后的工具状态或结果,恢复执行直到完成;在多端集成中同样使用该机制libs/agno/agno/os/router.py:988–:1023、libs/agno/agno/integrations/discord/client.py:143–:159
价值与适用场景
- 安全与合规:对“敏感操作”(调用外部 API、写数据库、发交易、删除资源)先征得用户确认
- 可审阅:提供工具名与参数,让用户在执行前检查、修正或拒绝
- 人工协作:在自动化链路中插入人审节点,兼顾效率与控制
实践建议
- 交互体验:为确认提示显示简明参数摘要;在需要时提供“查看详细 diff/请求体”选项
- 多工具场景:支持批量确认或逐一确认;未确认的工具默认不执行或视为拒绝
- 审计与记录:记录确认时间、操作者、工具名与参数,用于合规和回溯
- 兜底策略:用户拒绝后提供替代方案或解释;必要时用
StopAgentRun终止并返回说明
总结
- 该示例把“人审机制”无缝嵌入 Agno 的工具调用链:当工具声明需要确认时,自动暂停并等待用户决定,确认后继续执行
- 适合任何需要在自动化与审慎执行之间取得平衡的场景,具备良好的扩展性与可观测性
图像智能体
源码
1 | """🎨 AI Image Reporter - Your Visual Analysis & News Companion! |
点评
这个例子实现了如下功能:
- 构建“图像+新闻”多模态代理:接收图片,先进行视觉分析,再调用搜索工具整合最新相关资讯
图像生成
源码
1 | """🎨 Image Generation with DALL-E - Creating AI Art with Agno |
点评
构建了一个“AI 艺术生成”代理:用 DalleTools 调用 DALL·E 生成图片,并将结果保存在会话中,随后读取并打印图片 URL。
音频交互智能体
源码
1 | """🎤 Audio Input/Output with GPT-4 - Creating Voice Interactions with Agno |
点评
示例概览
- 构建“语音交互”代理:支持音频输入与音频输出,适用于语音分析、情绪识别与自然语音回复
- 模型配置启用多模态与语音输出,输入示例来自公开的 wav 文件,最终将回复音频落盘保存
核心结构
- 模型与多模态配置:
modalities=["text","audio"]、audio={"voice":"sage","format":"wav"},启用音频输入与音频输出 - 拉取输入音频:从 URL 下载 wav 数据,作为原始字节传入代理
- 执行与保存:运行后检查
run_response.response_audio,将模型生成的音频保存为本地文件
工作机制
- 输入音频打包:将
Audio(content=..., format="wav")转为 OpenAI 多模态消息部件,使用 base64 编码并携带格式信息libs/agno/agno/utils/openai.py:13–:26、:35–:39 - 消息格式化:当消息包含音频,模型消息内容转为
[{"type":"text",...}, {"type":"input_audio",...}]的多段结构libs/agno/agno/models/openai/chat.py:289–:351 - 输出音频填充:模型返回音频后,代理将其写入
run_response.response_audio,用于后续保存与展示libs/agno/agno/agent/agent.py:4685–:4687 - 文件写入:
write_audio_to_file将 base64 的音频内容解码写至磁盘
优点与价值
- 端到端语音链路:从字节级音频输入 → 多模态推理 → 语音输出,一次性打通
- 语音分析增强:提示中明确“分析内容与语气”,适合做情绪识别、语音摘要与可读性评估
- 输出可落盘:将回复音频保存为
wav文件,便于集成到应用或后续播放
常见注意点
- 音频格式:输入建议提供
format="wav";若是 URL,系统会尝试根据路径猜测格式libs/agno/agno/utils/openai.py:41–:52 - 非流式输出:示例使用
agent.run(非流式),返回整体结果后再保存音频;若需边播边存,可考虑流式事件与分片处理(模型事件会分段累积音频)libs/agno/agno/agent/agent.py:4978–:5020
使用场景
- 语音问答:将语音问题转文本分析并给出语音回复
- 语音摘要与情感:对录音进行主题提取、要点总结与情绪识别
- 多语言与口音适配:通过提示策略支持跨语言与不同口音的理解与回应
多智能体
源码
1 | """🗞️ Multi-Agent Team - Your Professional News & Finance Squad! |
点评
- 演示了一个“多智能体协作”的新闻与金融分析工作流: Web Agent 负责抓取与综合新闻, Finance Agent 负责财务与行情分析,团队充当“主编”整合输出,形成一篇结构化的金融报道
- 展示了如何为不同智能体设置各自的角色、工具与风格指南,并由团队统一编辑规范和最终呈现