一、先看一个本地销售助手为什么还不是平台
先想一个公司内部的销售助理平台。它不只是“一个 agent 能回答问题”:销售同事要从网页、Slack、Telegram 入口使用它; 管理员要看 traces 和 metrics;有些工具会修改 CRM,必须先审批;不同团队只能看到自己的 session; 定时任务还要在后台跑。这个时候,问题已经不只是 Agent Loop 怎么写,而是哪些模块负责身份、状态、审批、恢复和定时执行。
假设团队只是把本地 Agent 包成一个 HTTP 接口:网页和 Slack 各自创建一份历史,CRM 更新请求超时后没人知道是否成功, 管理员批准动作时原来的进程已经退出。单个对象仍然会回答,但用户、运行、审批和恢复没有被同一个系统接住。
二、Agent 平台先认识五个对象
Agent 平台,是让一组 Agent 能被不同入口长期调用,并统一管理身份、状态、风险动作和运行证据的服务层。 在 Agno 里,可以先按下面五个对象理解:
- Agent:一次工作所需的模型、工具、知识和行为。
- Run:Agent 处理一条请求的执行实例,可能流式返回、后台运行、暂停或继续。
- Session:把同一用户的一系列消息、run 和状态连起来,支持保存与恢复。
- AgentOS:把 Agents、Teams、Workflows、数据库和对外接口装进同一个服务应用。
- Approval 与身份规则:决定谁能看到什么,以及有风险的工具动作何时可以继续。
三、一条销售请求怎样走完
下面故意选择会修改 CRM、因此触发审批的分支。普通只读请求会在 Agent 返回答案后直接结束; Memory 与 Tracing 是运行时读取或旁路记录的能力,并不是每个 Run 都必须依次经过的步骤。把它们画在同一张平台图上, 表示 AgentOS 能统一接入这些模块,不表示“Session → Memory → Tracing → Approval”是一条固定流水线。
- 销售从网页或 Slack 发来请求,入口先确认用户身份并找到对应 session。
- AgentOS 根据路由找到销售 Agent,为它接上数据库、工具和事件存储。
- Agent 开始一个 run,查询客户资料,并把文字与工具事件持续返回给前端。
- 当模型提出更新 CRM,approval gate 保存待批准动作并暂停这个 run。
- 管理员批准后,平台从持久化状态继续同一个 run,而不是重新问一遍模型。
- 最终结果、事件、usage 和 session 状态保留下来,管理员可以追踪,用户也能继续对话。
这条流程说明“平台”不是功能越多越好,而是一次请求从入口到恢复都能找到负责的模块和持久记录。后面的 API、RBAC、Scheduler 和 Interfaces 都是在这条主线上增加入口、权限或运维能力。
Agno README 的开头不是说“一个更聪明的 agent 类”,而是说 Build, run, and manage agent platforms。它把定位写成 SDK for building agent platforms, 并强调可以用任何 agent framework 构建 agents,再把它们作为 production services 运行,带 tracing、scheduling、RBAC 和 single control plane。 这些话在 README introduction。
功能列表也很像产品运行时清单:Production API、Storage、100+ integrations、Context Providers、Human approval、 Observability、Security、Interfaces、Scheduling 和 Deploy anywhere。 这段在 README features。 所以读 Agno 不能只问它的 Agent Loop 怎么写,还要看身份、会话、审批、定时与接口分别由哪段代码处理。
读完后你应该能回答。
这篇不把 Agno 当成“更大的 Agent 类”读,而把它当成 agent platform 读。
Agent 负责一次运行需要的模型、工具和上下文;AgentOS 负责把 agents、teams、workflows、
Database、API、Approval、RBAC、Scheduler、Interfaces 和 Observability 接入同一个服务应用。
本文依据。
源码链接固定到 Agno 当前公开快照 85b6d1d178b70d59e8f2c0d432d2a66b35004f31。
本文只基于公开 README 与源码;对平台行为的描述来自可见类、路由、Session、Approval 和 Auth 结构。
先用一条销售助理 run 的形状把平台责任串起来。它不是 Agno 的完整请求 schema,而是读后面源码时要跟住的状态流:
POST /agents/sales-assistant/runs
request: {user_id, session_id?, message, stream, background}
AgentOS bootstrap
-> inject database / checkpoint / MCP tools
-> enable store_events for built-in routes
Agent run emits tool call: update_crm(...)
@approval(required) -> pause run
approval record:
{run_id, session_id, status: "pending", tool_name, user_id, context}
AgentSession.upsert_run(paused_run)
admin resolves approval
POST /agents/sales-assistant/runs/{run_id}/continue
-> require_approval_resolved
-> resume from persisted run state
-> stream missed and live events back to client
这就是 Agno 和“一个 agent 对象”的差别:对象可以回答问题,但平台要接住 HTTP 入口、用户隔离、 事件缓冲、审批记录、持久化 run,以及审批解决后的恢复路径。后面每一节都在拆这条链上的 owner。
四、Agent 对象已经带着平台接口
Agno 的 Agent 不是薄薄的“model + tools”。如果只按源码列表读会显得很散,
但它们其实在回答四个产品问题:谁在用、这次运行属于哪个 session、能查什么资料、运行过程怎样保存和观测。
| 产品问题 | 对应能力 | 为什么不能只写在 prompt 里 |
|---|---|---|
| 谁在用 | user、session、session_state、dependencies | 多人产品要区分用户、团队和运行上下文。 |
| 能查什么 | knowledge、memory manager、history、skills、tools | 资料、历史和工具要被复用、审计和按入口控制。 |
| 怎样保存 | database、checkpoint、media storage、structured outputs | 长 session、后台任务和失败恢复都需要持久化边界。 |
| 怎样观测 | events、telemetry、hooks、followups、reasoning | 产品运行需要 traces、metrics 和可回放的 run 记录。 |
对应源码集中在
Agent 的基础配置、
工具、上下文、输出与事件配置
和
初始化落点。
这说明 Agno 的 agent 从一开始就面向“运行很多次、被很多入口调用、需要存储和审计”的场景。
checkpoint 决定何时把 run state 写入数据库;store_events 决定 run response 是否保留事件;
store_history_messages 明确写出存储增长的代价:只存本轮消息是线性增长,存完整 history 会变成二次增长。
这些不是 prompt 技巧,而是平台运行时的成本边界。
Agent 配置与本轮执行
- model、tools、reasoning
- 本轮 history 投影、knowledge、memory 查询
- output schema 与运行事件
AgentOS 服务入口
- agents、teams、workflows
- 依赖注入、routes、interfaces
- registry、scheduler、tracing
持久记录与外部事实
AgentSession:runs 与 history- approval 表:决定与审计
- 外部 CRM:真正的客户变更
这三个格子不是三个平级类。Agent 是可运行对象,AgentOS 是装配和暴露它们的服务入口,
AgentSession、approval 表与 CRM 才分别保存运行事实、治理决定和业务事实。
“Agent 有 session_state 字段”不能替代后两者。
五、AgentOS 怎样组装整个服务应用
AgentOS 才是 Agno 最有辨识度的入口。它接住三类东西:agents、teams、workflows 和 knowledge
这些可运行对象;database、authorization、registry、scheduler 和 tracing 这些平台服务;
interfaces 与 MCP server 这些外部入口。也就是说,平台入口不是围绕单个 agent 展开,
而是把“有哪些可运行对象、怎么接数据库、怎么鉴权、怎么挂接口、怎么观测和调度”放到同一个地方。
它还要求至少传入 agents、teams、workflows、knowledge 或 database 之一,否则直接报错。
源码在
AgentOS.__init__。
初始化不是登记名称这么简单。_initialize_agents 会给没有 db 的 agent 注入 OS-level db,
给没有 checkpoint 的 agent 注入 OS-level checkpoint,收集 MCP tools,调用 initialize_agent,
并把 store_events 打开以支持内置路由。
teams 和 workflows 也会被注入 db、收集 MCP tools、打开事件存储,并传播后台 hook 设置。
相关源码在
初始化 agents/teams/workflows。
get_app 则把这些对象变成 FastAPI 应用:组合用户 lifespan、MCP tools lifespan、database lifespan、
scheduler lifespan 和 http client cleanup;随后挂上 session、memory、learnings、evals、metrics、knowledge、traces、
database、components、schedules、approvals、registry 等路由。内置路由还包括 agents、teams、workflows 和 websocket。
源码在
内置路由
和
get_app。
六、API 路由怎样创建、暂停与继续 Run
POST /agents/{agent_id}/runs 支持文本、媒体、session、factory input、SSE 和后台执行。
后台执行要求 Agent 配置数据库;启用 QueueConfig(durable=True) 后,可序列化、无媒体、未固定版本且来自已注册普通 Agent 的请求可以进入持久队列。
队列行提交才表示工作已受理,由领取任务的 Worker 执行;流式调用旁观事件,非流式调用返回 202 和 run 标识。
不符合队列条件的请求仍可回退到进程内后台路径;detached task 能跨客户端断线,却不自动跨进程崩溃。
见后台分流与队列配置。
后台请求 -> 检查数据库与队列条件
可入队 -> 持久队列接受 -> Worker 领取 -> 写入最终 run
不可入队 -> 进程内后台执行
202 / 已入队 ≠ 已完成;最终状态和输出仍需从 run 读取
队列还接受 Idempotency-Key:重复提交复用原 run,队列已满则返回 429;流式请求遇到同 key 的非流式任务会返回冲突,要求轮询原 run。
这只是提交去重,不是 CRM 写入的 exactly-once 保证。最终 run 记录与尽力而为的实时事件流也要分开验收。
continue 路由更能体现平台 owner。它不是单纯“再调一次模型”,而是根据持久化 run state 和 body shape 分派:
paused run 可以用工具结果继续,也可以等待 admin approval resolved 后空 tools 继续;running/error 可以从最后持久化状态恢复;
completed run 可以追加消息继续。它还支持 continue_from、fork、regenerate、
replace_original 和后台 resumable SSE。
源码在
continue_agent_run。
resume 路由说明事件流也是平台协议的一部分:客户端通过 last_event_index 重连,
runtime 会补发 missed events,并在 run 仍活跃时继续 live streaming;完成后的 run 可以从 buffer 或 database 回放。
源码在
resume_agent_run_stream。
6.1 continue 与 resume 解决不同中断
| 当前记录 | 调用 | 改变什么 |
|---|---|---|
| 刚创建或前台运行 | POST /runs |
创建 run,执行 agent,并产生新事件 |
| paused,已有工具结果或 approval 已解决 | /continue |
重新装载持久 run state,推进执行状态机 |
| running/error,需要从持久点恢复 | /continue |
按 route 支持的恢复形状继续计算 |
| 后台 run 仍在执行,只是 SSE 断线 | /resume?last_event_index=… |
补发事件并重连流,不重新执行 agent |
| completed 后继续对话 | /continue + 新消息 |
以旧 run ledger 为背景创建后续工作 |
恢复前还要确定“谁的哪一次运行”:continue 路由先核对 session 的用户归属与 run 的 Agent 归属。 若原 run 固定了组件版本,继续时会重新验证草稿预览权限并加载同一版本;factory 与 remote Agent 各走自己的解析路径。 因此一次审批等待期间发布新版本,不应悄悄改变已固定版本的工具实现。见运行归属与版本恢复。
七、Session 是可恢复运行记录,不只是 chat history
AgentSession 存的不是一个扁平消息数组。一个销售助理 session 里,可能有多次 run:
第一次查客户,第二次生成邮件,第三次等待审批后继续写 CRM。Agno 因此把 session、agent/team/workflow、
user、runs、summary 和 metadata 放在一起。
定义在
AgentSession 定义。
upsert_run 会用 run_id 更新或追加 run;get_messages 从 runs 里重建 model-visible 历史,
默认过滤 paused、cancelled、error、regenerated 等状态,还会跳过 from_history 的消息、tool-only 前缀和成员 team run。
这就是为什么 Agno 的 history 不是“把数据库里所有消息拼回去”。它维护的是可恢复 run ledger,再按运行语义投影成当前上下文。
源码在
run upsert 与消息投影。
get_run 返回独立的深拷贝,避免一个 continue 请求修改工具答案时,让其他读者在持久化之前就看到变化。
upsert_run 还会保留已有 queue_attempt,防止执行器整条保存 run 时抹去 Worker 写入的尝试代数。
这些是会话读取和写回的具体约束,而不是把共享对象当成已提交状态。
八、Human Approval 怎样暂停有副作用的工具
销售助理如果只是读资料,风险不大;但如果要修改 CRM、发送邮件、触发报价,就不能让模型直接执行。
Agno 的 @approval 装饰器不是给 UI 看看的注释。它可以直接作用在 Function 上,
设置 approval_type;当 type 是 required 时,如果工具没有其他 HITL 标记,就会自动打开
requires_confirmation。当 type 是 audit 时,它要求工具已经具备确认、用户输入或外部执行之一。
源码在
@approval
和
approval type。
run 暂停以后,Agno 会创建 approval record:记录 run_id、session_id、status、approval_type、pause_type、tool_name、 source_type、agent/team/workflow id、user_id、schedule id、requirements 和 context。随后把 approval_id stamp 回相关工具, 再把 paused run 存入 session。 相关源码在 同步 approval 创建、 异步创建与 stamp 和 agent pause handling。
approval API 负责 list、count、status、get、resolve 和 delete。resolve 会把 status、resolved_by、resolved_at
和 resolution_data 写回数据库;在 user isolation 打开时,读写还会按 caller scope 控制可见性。
agent continue 路由前置了 require_approval_resolved(os.db),所以 admin approval 未处理时,普通 continue 会被挡住。
源码在
approval router policy、
approval endpoints
和
continue 路由依赖。
| 生命周期步骤 | 持久状态怎样变化 | 最容易混淆的边界 |
|---|---|---|
| 工具请求审批 | run 暂停,pending approval 被保存,approval_id stamp 到工具上,paused run 写入 AgentSession。 |
恢复依据属于 approval record 和 session,不属于审批页面。 |
| 管理员解决审批 | status、resolved_by、resolved_at 和 resolution_data 被持久化。 | resolve 只记录决定,不会顺手执行工具。 |
| 客户端继续 run | 路由先检查 require_approval_resolved,再加载 run state,恢复并补发 missed/live events。 |
继续运行和作出审批决定是两个独立动作。 |
| 审批被拒绝或调用者越权 | 后续迁移仍受已保存的决定和 caller scope 约束。 | 管理员点过按钮,不等于绕过 user isolation 或 RBAC。 |
把主例继续走完:管理员批准只把 approval 变成 resolved;客户端随后调用 /continue,
runtime 才执行 update_crm。CRM 返回业务回执后,tool result 写回 run,run 完成并 upsert 到
AgentSession,用户最后看到更新结果。若管理员拒绝,工具被跳过,run 也应以拒绝事实生成回答。
因此 pending action 被产出、approval 被验证、CRM 接受更新并由用户或业务流程
采用,是三次不同的状态推进。
当销售 Team 的两个成员都暂停时,一张批准记录不能替另一个成员放行。
runtime 优先按工具上的 approval_id 找决定,再按所属 member_run_id 查找;没有作用域身份才允许 run 级回退。
同一工具调用号匹配多个成员时视为归属不明确,缺记录或仍 pending 都阻止 continue。数据库重载后,工具列表与 requirement 中的独立副本也要分别更新。
见逐工具匹配审批与决定应用。
九、RBAC 与 Interfaces 怎样保护产品入口
平台入口多了以后,权限也不能只写成“是不是管理员”。Agno 的 RBAC scope 采用 resource/action 和
resource/resource-id/action 格式,例如 agents:read、agents:web-agent:run、
agents:*:run 和 agent_os:admin。源码在
scopes.py。
HTTP auth 支持 security key、JWT middleware 和按 agno_pat_ 前缀分派的服务账户 token;scheduler 的 internal service token 会被授予 agents、teams、
workflows 和 schedules 相关 scopes。
user isolation 是 route-layer 约定:当普通用户带 JWT 且隔离打开时,get_scoped_user_id 返回 JWT sub,
读写端点必须把这个 user_id 传进 DB 调用。
相关源码在
authentication dependency
和
user isolation contract、
scoped user resolution。
interface 层则把同一个 control plane 暴露给不同产品入口。BaseInterface 要求实现
get_router 并返回 FastAPI router;AgentOS 会把传入的 interfaces 挂到应用里,如果开启 A2A 且没有显式传入,
还会自动构建 A2A interface。源码在
BaseInterface
和
interface 挂载。
目录里已有 A2A、AG-UI、Slack、Telegram 和 WhatsApp 入口。
十、和前几篇放在一起看
| 框架 | 最适合先看的 owner | 不要误读成 |
|---|---|---|
| AgentScope | 事件化 agent turn:message、tool call、event、context ledger。 | 只是一层 Chat Completions wrapper。 |
| ADK Python | code-first app runtime:Agent、Workflow、Runner、Event、Task API。 | 只有 workflow DSL,或只有 agent 类。 |
| Agno | agent platform control plane:AgentOS、API、storage、approval、RBAC、interfaces。 | 只是一个更大的 agent dataclass。 |
下一篇进入 AutoGen 和 Microsoft Agent Framework 这一组。重点会放在 multi-agent conversation、 topic/event runtime、hosted orchestration 与新旧框架迁移边界上。