一次 agent 运行的完整旅程
把前四天串成故事线:你在 GUI 创建并运行一个智能体,到它自主完成,数据在整个平台里怎么流动。这是理解 SuperAGI 全局的关键一天。
旅程全景
贯穿今天的类比是"一张外卖订单的旅程":一次运行 = 一张外卖单;API 入队 = 前台把小票贴到后厨挂单栏;worker = 厨师做一道工序就先歇;自我重排 = 做完一道把"下一道"重新挂回单栏;Feed 轮询 = 你在外卖 App 里不停刷新看"商家已接单 / 制作中 / 已出餐"。
execute_agent.delay() 入 Redis 队列,API 立即返回① 创建智能体
GUI 调 POST /agents/create(controllers/agent.py:60):校验 project 和 tools → Agent.create_agent_with_config 落库 → 立刻建一条 AgentExecution(status='CREATED')→ 把 goal/tools/model 写进 AgentExecutionConfiguration。
② 入队 Celery
POST /agentexecutions/add(controllers/agent_execution.py:65)发起运行:把 status 从 CREATED 改成 RUNNING,然后关键一步(:148):
execute_agent.delay(db_agent_execution.id, datetime.now()) # 丢进 Celery 队列
# API 到此立即返回,不阻塞
.delay() 把"运行这个智能体"作为 Celery 任务推给 Redis 队列,API 立刻返回。真正的执行由后台 worker 领走(Day 04 的 celery 容器)。这就是"接单/干活分离"的落地——回忆 AutoGPT 的 MQ 入队、OpenHands 的双进程,同一模式。/agents/create 里把我建出来,status=CREATED,此刻我还只是数据库里一条静静躺着的记录。我被叫醒:有人点了"运行",
/agentexecutions/add 把我的 status 改成 RUNNING,然后 execute_agent.delay(我的id) 把我这张"单子"贴上了 Redis 挂单栏——API 转身就去接待别的客人了,不管我了。我被领走:一个 celery 厨师取下我,看我
current_agent_step_id 走到哪一步,做完这一道工序、把结果写进我的 Feed。我没做完:厨师把"我的下一道工序"重新挂回单栏(apply_async),自己下班——2 秒后另一个厨师接着做我。
我完成了:某一步 LLM 喊了 finish,我的 status 变 COMPLETED,不再被挂回栏——我这趟旅程结束。全程我的状态都写在 DB,所以换谁来做、中间停几次,都能接着做我。
③ worker 跑一步
Celery worker 领取 execute_agent 任务(worker.py:66)→ AgentExecutor.execute_next_step(jobs/agent_executor.py:39):
# 按当前 workflow step 的 action_type 分派 handler(agent_executor.py:105)
if action_type == "TOOL": AgentToolStepHandler(...).execute_step()
elif action_type == "ITERATION_WORKFLOW": AgentIterationStepHandler(...).execute_step() # think→选工具→执行→观察
elif action_type == "WAIT_STEP": AgentWaitStepHandler(...).execute_step()
current_agent_step_id 取当前工作流步,根据类型交给对应 handler。迭代步(ITERATION_WORKFLOW)里才是经典的"think→选工具→执行→观察"循环(Day 06 精读)。注意:跑完这一步就退出,不是一路跑到底。第1次 execute_agent:think「先搜第一家」→ 调 WebSearch("竞品A pricing") → 观察写 Feed → status 仍 RUNNING → 自我重排第2次 execute_agent:think「再搜第二家」→ 调 WebSearch("竞品B pricing") → 写 Feed → 重排第3次:think「资料够了,写文件」→ 调 WriteFile("竞品定价.csv") → 写 Feed → 重排第4次:LLM 调 finish 工具宣布完成 → status = COMPLETED → 不再重排,循环结束4 次 Celery 任务 = 4 步,而不是 1 个进程从头跑到尾。
④ 自我重排续跑(Day 02 的"啊哈"兑现)
跑完一步后,若没完成,再排一个任务给自己(agent_executor.py:94):
if agent_execution.status in ("COMPLETED", "WAITING_FOR_PERMISSION"):
return
superagi.worker.execute_agent.apply_async((agent_execution_id, datetime.now()), countdown=2)
current_agent_step_id)、对话存在 Feed——这就是 Day 02 说的"循环在 DB 和队列里"。出错时 countdown=15 延迟重试(不丢任务)。⑤ Feed 流回 GUI
每一步的思考、工具结果都写入 AgentExecutionFeed(agent/output_handler.py:48,Day 02)。GUI 轮询 GET /agentexecutionfeeds(controllers/agent_execution_feed.py)拿到每一步 feed,实时展示智能体在干嘛。
WAITING_FOR_PERMISSION,GUI 显示批准/拒绝按钮。👶 小白:.delay() 让 API 秒回了,那我怎么知道智能体到底跑完没、结果去哪看?
👨🏫 老师:靠这一步的 Feed 流回 + GUI 轮询。worker 在后台每跑一步就把思考和工具结果写进 AgentExecutionFeed,GUI 每隔几秒轮询 /agentexecutionfeeds 把新内容刷出来;当 status 变成 COMPLETED 就是跑完了。状态和产出全在数据库里,你随时刷新、随时查,不用盯着那个请求干等。这正是"接单/干活分离"要配一条"进度回传"通道的原因。
为什么这样最好
- 不阻塞:API 秒回,智能体在后台慢慢跑,用户不用干等。
- 可扩展:多个 Celery worker 能同时跑多个智能体(并发)。
- 可恢复:每步状态持久化,进程崩了重启能从断点续跑(不丢进度)。
- 可暂停/审批:状态机支持 PAUSED/WAITING_FOR_PERMISSION,随时挂起恢复。
🎓 第 1 周收官 + 动手
第 1 周(Day 01-05)你已建立完整心智
- Day 01 全景:平台架构、六服务、数据流
- Day 02 Agent:极简身份 + EAV 配置 + 循环在 DB/队列
- Day 03 工具:name+描述+pydantic参数+_execute
- Day 04 运行平台:docker 六服务、启动步骤、seeding
- Day 05 完整旅程:创建→入队→逐步循环→Feed 流回
你现在理解了"一个智能体如何被自主运行"的全局。下周(Day 06-10)深入 Agent 执行:执行循环、工作流、提示词、输出解析、LLM。
💰 数字感受:API 那一下
.delay() 是毫秒级返回,用户零等待;而后台一整趟运行可能几分钟到几十分钟、几步到几十步——正因为两者差了几个数量级,才必须"接单/干活分离"。一句话复述:一次运行就像一张外卖单——前台秒接单入队、后厨一道道工序接力做、每道工序上报进度让你实时看到,做完自动收尾。
✋ 动手:验证旅程
P=superagi
grep -n 'def create_agent_with_config\|execute_agent.delay' $P/controllers/agent.py $P/controllers/agent_execution.py | head
grep -n 'def execute_next_step\|apply_async' $P/jobs/agent_executor.py | head
sed -n '66,72p' $P/worker.py # execute_agent 任务