一、先看一个本地销售助手为什么还不是平台
先想一个公司内部的销售助理平台。它不只是“一个 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 能统一接入这些 owner,不表示“session → memory → tracing → approval”是一条固定流水线。
- 销售从网页或 Slack 发来请求,入口先确认用户身份并找到对应 session。
- AgentOS 根据路由找到销售 Agent,为它接上数据库、工具和事件存储。
- Agent 开始一个 run,查询客户资料,并把文字与工具事件持续返回给前端。
- 当模型提出更新 CRM,approval gate 保存待批准动作并暂停这个 run。
- 管理员批准后,平台从持久化状态继续同一个 run,而不是重新问一遍模型。
- 最终结果、事件、usage 和 session 状态保留下来,管理员可以追踪,用户也能继续对话。
这条链说明“平台”不是功能越多越好,而是一次请求从入口到恢复都有明确 owner。后面的 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 怎么写,而要问:这些产品责任最后落到哪个 owner。
阅读契约。
这篇不把 Agno 当成“更大的 Agent 类”读,而把它当成 agent platform 读。
Agent 负责一次运行需要的模型、工具和上下文;AgentOS 负责把 agents、teams、workflows、
database、API、approval、RBAC、scheduler、interfaces 和 observability 收到同一个运行面里。
证据边界。
源码链接固定到 Agno 当前公开快照 c581db4c65676765ac8956d79120454dc83a6795。
本文只基于公开 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 的生命周期
agent run 的 HTTP 路由显示得很直接:POST /agents/{agent_id}/runs 支持文本、媒体文件、session、
user、factory input、streaming SSE 和 background execution。background + stream 会把 agent 放进 detached task,
并把事件缓冲起来,供 resume endpoint 重连。非流式后台执行则立即返回 202,内容包含
run_id、session_id 和 status。
源码在
create_agent_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 为背景创建后续工作 |
七、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 与消息投影。
八、Human approval 是 side effect gate
销售助理如果只是读资料,风险不大;但如果要修改 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 接受更新并由用户或业务流程
采用,是三次不同的状态推进。
九、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;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 与新旧框架迁移边界上。