Day 02 / 共 20 天 · 第 1 周 核心概念

Agent:自主智能体

第一个核心概念。今天读数据模型看清 Agent 到底是什么,并揭示 SuperAGI 最关键的"啊哈"点——它的自主循环不在代码里,而在数据库和消息队列里

📍 你在整门课的位置 · 第 1 周 核心概念(D1-5)· 昨天看了全景,今天钻进第一个概念 Agent
D01 全景架构 D02 Agent D03 工具 D04 运行平台 D05 完整旅程· 第2周 Agent执行· 第3周 工具/记忆/资源· 第4周 平台/异步/生态
L01

Agent 表极简

🤔 "Agent 智能体"听起来很高级,它在代码里到底是个啥? 很多人以为智能体是一段很聪明的、会自己思考的复杂代码。翻开源码前你可能预期看到一个几百行的 class Agent,里面全是决策逻辑。
💡 一句话本质:Agent 只是数据库里几张表的记录,不是"聪明代码" 在 SuperAGI 里,Agent 不是一个装满逻辑的类,而是数据库里的一条身份记录 + 一堆配置行。"聪明"来自运行时反复调 LLM,而不是 Agent 类本身。所以读 Agent,就是读几张表的字段——今天全程都在看表结构。
贯穿今天的类比是"公司员工档案"Agent 表 = 员工工牌(只印工号、姓名、部门,稳定不变);配置 = 员工的档案袋(职责、权限,随时往里加纸);一次 Execution = 这名员工的一天出勤记录;Feed = 他的工作日志本

Agent 模型(models/agent.py:20)——出乎意料地简单:

class Agent(DBBaseModel):
    __tablename__ = 'agents'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    project_id = Column(Integer)          # 归属哪个 Project
    description = Column(String)
    agent_workflow_id = Column(Integer)   # 绑定一个工作流
    is_deleted = Column(Boolean, default=False)
读法:Agent 表只存"身份 + 归属 + 绑哪个工作流",非常精简。它的目标、指令、工具、模型等都不在这张表里——拆到了 AgentConfiguration(L02)。
为什么 Agent 表这么"空"? 因为一个 Agent 的"可变配置"(目标、工具、模型…)很多且经常增改。如果全塞进 Agent 表,字段会爆炸、加新配置要改表结构。SuperAGI 把"身份"(Agent 表,稳定)和"配置"(AgentConfiguration,多变)分开——身份表精简稳定,配置用灵活的 key-value 存。这是数据建模的"稳定/多变分离"。
L02

配置存 key-value(EAV 模式)

# models/agent_config.py:15
class AgentConfiguration(DBBaseModel):
    __tablename__ = 'agent_configurations'
    agent_id = Column(Integer)
    key = Column(String)     # 如 "goals" / "instructions" / "tools" / "model"
    value = Column(Text)
读法:Agent 的目标、指令、约束、工具、模型全用"键值对"存——一个 Agent 有多行 AgentConfiguration,每行一个配置项。比如 key="goals", value="调研竞品定价"
📝 一个 Agent 在 agent_configurations 表里长这样(多行 key-value) 同一个 agent_id=7 对应下面这几行:
key=goalsvalue=["调研 3 家竞品定价"]
key=instructionvalue=["汇总成 csv 表格"]
key=toolsvalue=[13, 21](工具 id 列表)
key=modelvalue=gpt-4
key=max_iterationsvalue=25
想给 Agent 加一个新配置项?再插一行就行,完全不用改表结构——这就是 EAV 的灵活之处。
EAV(实体-属性-值)模式的取舍 这叫 EAV 模式——不给每种配置建一个列,而是用"key 列 + value 列"存任意配置。好处:加新配置项(比如 resource_summarylast_resource_time)无需改表结构,加一行即可。坏处:查询不如固定列直接、value 都是文本要自己转类型。对"配置项种类多、常变"的场景,EAV 灵活性优先——SuperAGI 选了它。
接着"员工档案"的类比:固定列建表 = 印死的工牌(想加一栏得重做整批工牌);EAV = 员工的档案袋(要加一项资质,塞张纸进去就行,档案袋结构不用动)。
L03

Execution:一次运行

Agent 是"定义",一次实际运行叫 AgentExecutionmodels/agent_execution.py:11)——一个 Agent 可以被跑很多次:

class AgentExecution(DBBaseModel):
    status = Column(String)                # CREATED/RUNNING/PAUSED/COMPLETED/TERMINATED
    agent_id = Column(Integer)
    num_of_calls = Column(Integer, default=0)     # 调了几次 LLM
    num_of_tokens = Column(Integer, default=0)    # 消耗了多少 token
    current_agent_step_id = Column(Integer)       # ★ 当前走到工作流哪一步
读法:Execution 记录"这次运行的状态机 + 进度 + 用量"。关键是 current_agent_step_id——它指向"这次运行现在走到工作流的哪一步",把"运行"和"流程定义"关联起来。status 是运行状态机(L05)。
Agent vs Execution 的区别(像"类"和"对象") Agent = 定义("一个调研竞品的智能体")。Execution = 一次具体运行("周一那次调研"、"周二那次调研")。一个 Agent 定义可以产生多个 Execution,各自独立跑、各有状态和进度。这样能重复运行同一个 Agent、能定时跑、能同时跑多次——都靠 Execution 承载每次的独立状态。
L04

Feed:短期记忆

AgentExecutionFeedmodels/agent_execution_feed.py:8)——运行过程中每一条 LLM 对话/工具响应存一行:

class AgentExecutionFeed(DBBaseModel):
    agent_execution_id = Column(Integer)
    feed = Column(Text)
    role = Column(String)          # system / user / assistant
    feed_group_id = Column(String)
Feed = 智能体的"对话历史/短期记忆" 智能体每一步的思考、每次工具调用的结果,都作为一条 Feed 存下来(role 区分是谁说的)。下一轮循环时,框架把这些 Feed 读回来、拼成 LLM 的对话上下文——这就是智能体"记得自己之前干了什么"的机制。同时它也是 GUI 实时展示的数据源(你在界面上看到的"智能体思考流"就是 Feed)。Feed 一举三得:短期记忆、UI 展示、执行审计。(长期记忆则在向量库,Day 13。)
L05

循环在 DB 和队列里(最重要的"啊哈")

SuperAGI 的自主循环不是一个 while 循环!它是"数据库状态机 + Celery 任务链"。看 jobs/agent_executor.py:94

# 执行完一步后,若没完成,就再排一个任务给自己(2秒后)
if agent_execution.status in ("COMPLETED", "WAITING_FOR_PERMISSION"):
    return
superagi.worker.execute_agent.apply_async((agent_execution_id, datetime.now()), countdown=2)
❌ 普通智能体:内存里一个大 while 一步 下一步 …直到完成 进程一崩 → 全部丢失 ✅ SuperAGI:跑一步就退,靠队列续跑 worker只跑一步 Redis 队列下一步任务 Postgres进度=current_step_id apply_async 2秒后领走 存进度 进程崩了 → 队列+DB 还在 → 重启从断点续跑
左边"内存大 while"崩了就全丢;右边 SuperAGI 每步退出、把"下一步"重新入队,进度存 DB、对话存 Feed——所以能断点续跑、能多 worker 并发。
👶 小白 vs 👨‍🏫 老师:为什么不直接写个 while 循环? 👶 小白:智能体不就是"想一步→干一步→再想"吗?一个 while True 循环到底不就完了,为什么搞得这么绕?
👨‍🏫 老师:因为 while 循环活在一个进程的内存里。这个循环要跑几分钟到几小时,中间进程一崩(重启、OOM、部署),整局全丢,得从头再来
👶 小白:那把进度存下来不就行?
👨‍🏫 老师:对!SuperAGI 就是把"下一步该干啥"存进 Redis 队列、把"走到第几步"存进 DB。于是循环不再依赖某个进程活着——任何一个 worker 都能接着跑下一步,还能同时开好几个 worker 分担。代价是"一步就退出、靠重排续跑"这套看起来绕的机制。
时刻此刻发生什么statuscurrent_step_id / num_of_calls
worker 第1次领取跑迭代步:调 LLM 选工具、执行、写 FeedRUNNINGstep=12, calls=1
这步末尾没完成 → apply_async(countdown=2) 排下一步RUNNINGstep=13(已推进)
2秒后 worker 第2次领取跑 step=13,又一轮 LLM+工具RUNNINGstep=13, calls=2
某次 LLM 调 finish宣布完成,不再重排COMPLETEDcalls=8,循环结束
读法(单步走查表):盯着最后一列——进度全程写在 DB(step / calls)里,不在内存。所以"第1次""第2次"完全可以是不同的 worker 进程,甚至中间重启过,照样接着跑。
🤯 这是理解 SuperAGI 的关键 普通自主智能体是"进程里一个大 while 循环转到底"。SuperAGI 不是——它每执行一步(一次 LLM+工具)就退出,然后通过 Celery apply_async 把"执行下一步"重新排进队列,2 秒后另一个(或同一个)worker 领走跑下一步。进度存在 DB 的 current_agent_step_id,对话存在 Feed。所以"循环"是"Celery 任务反复自我重新调度",状态全在数据库和 Redis 里,不在内存。好处:进程可以随时断、随时恢复(状态都持久化了)、能水平扩展多个 worker、崩溃不丢进度。理解了这点,两级 step、崩溃恢复、人工审批挂起就都顺理成章。

👶 小白:循环靠队列反复重排、每次还 countdown=2 等 2 秒,那智能体岂不是很慢?

👨‍🏫 老师:几乎不影响。一步里"调 LLM + 执行工具"本身就要好几秒、甚至更久,2 秒的排队间隔相比之下微不足道。而这 2 秒换来的是可断点续跑、可多 worker 并发、崩溃不丢进度——用一点点延迟换一整套可运维性,非常划算。真嫌慢,这个 countdown 也能自己调小。

L06

max_iterations 熔断

自主循环怕失控,所以有 max_iterations 熔断(agent_executor.py:143_check_for_max_iterations)——num_of_calls 超过上限就停。

又见"能循环处必配上限" 和 eino 的 MaxRunSteps、OpenHands/AutoGPT 的 max_iterations、CrewAI 的 max_iter 一模一样——凡是能自主循环的地方,必须配次数上限防失控烧钱。SuperAGI 用 num_of_calls(调 LLM 次数)计数,超 max_iterations 强制停。结束的其它出口:LLM 调用 finish 工具(自己宣布完成)、任务队列空、走到工作流的 COMPLETE 边。五个框架同一个铁律——这就是读多个源码的价值:看穿共性。
💰 数字感受一下:GPT-4 级别一次调用大约几分到几毛钱。若没有上限、循环卡死打转,一个失控智能体一晚上跑几千次调用,就是几百上千块凭空烧掉——max_iterations(默认几十次量级)就是那道保险丝。
L07

三层租户

SuperAGI 是多租户平台,三层组织架构:

层级模型含义
顶层Organisation(organisation.py:7)租户(一个公司/团队)
中层Project(project.py:5,含 organisation_id)项目
底层Agent(含 project_id)智能体
为什么要三层? 平台服务多个组织,每个组织有多个项目,每个项目有多个智能体。层级隔离保证"A 公司看不到 B 公司的智能体"——多租户 SaaS 的基本盘。所有模型都继承 DBBaseModelbase_model.py:10),统一提供 created_at/updated_at 和序列化方法(DRY)。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • Agent 表为什么这么精简?配置为什么用 EAV key-value?
  • Agent 和 Execution 的区别?(类 vs 对象)
  • Feed 是什么?一举哪三得?
  • SuperAGI 的循环为什么"在 DB 和队列里"?好处是什么?
  • max_iterations 和其它框架有什么共性?
🗣️ 一句话复述今天 SuperAGI 的 Agent 就是"员工工牌 + 可加纸的档案袋",它的自主循环不在内存的 while 里,而是"进度记 DB、下一步排 Redis 队列、worker 一步步接力"——所以能断点续跑、能多开 worker、失控有 max_iterations 兜底。

✋ 动手

P=superagi
sed -n '20,40p' $P/models/agent.py
sed -n '11,40p' $P/models/agent_execution.py
sed -n '94,100p' $P/jobs/agent_executor.py       # 循环 = 自我重排
grep -n '_check_for_max_iterations' $P/jobs/agent_executor.py
明天预告 · Day 03:第二个核心概念——工具 Tools:一个工具 = 名字 + 描述 + pydantic 参数 + _execute,看智能体的"手"怎么定义、怎么被调用。
← Day 01 全景 Day 03 · 工具 →