Day 05 / 共 20 天 · 第 1 周收官

一次 agent 运行的完整旅程

把前四天串成故事线:你在 GUI 创建并运行一个智能体,到它自主完成,数据在整个平台里怎么流动。这是理解 SuperAGI 全局的关键一天。

📍 你在整门课的位置 · 第 1 周核心概念收官(D1-5)· 今天把前四天串成一条完整故事线
D01 全景架构 D02 Agent D03 工具 D04 运行平台 D05 完整旅程· 第2周 Agent执行· 第3周 工具/记忆/资源· 第4周 平台/异步/生态
L01

旅程全景

🤔 前四天学了架构、Agent、工具、docker 服务……但它们到底怎么"串"成一次运行? 单个概念好像懂了,可"点一下运行按钮,到智能体自己干完活"这中间,数据在六个服务之间到底怎么跑的?这一环最容易糊。
💡 一句话本质:一条数据流把前四天全部串起来 整个平台就干一件事:GUI 定义 → API 建 Execution 并入队 → Celery worker 一步步跑、每步自我重排、每步写 Feed → GUI 轮询展示。今天就沿着这一条线,把 Day01 的服务、Day02 的 Execution/Feed、Day03 的工具、Day04 的 celery 容器全部对号入座。
贯穿今天的类比是"一张外卖订单的旅程"一次运行 = 一张外卖单;API 入队 = 前台把小票贴到后厨挂单栏;worker = 厨师做一道工序就先歇;自我重排 = 做完一道把"下一道"重新挂回单栏;Feed 轮询 = 你在外卖 App 里不停刷新看"商家已接单 / 制作中 / 已出餐"。
① GUI创建+运行 ② FastAPI建 Execution Redis 队列delay() 入队 ③ Celery worker跑一步 LLM+工具 Postgres进度 + Feed ⑤ GUI 轮询 /agentexecutionfeeds实时展示思考流 领取 ④ 自我重排 ↺ 下一步 读写进度/Feed
一次运行的完整数据流:① GUI 创建 → ② API 建 Execution 并 delay 入队 → ③ worker 领取跑一步 → ④ 每步自我重排续跑 ↺ → ⑤ Feed 写库、GUI 轮询展示。下面 L02-L06 逐环拆解。
GUI → API:创建智能体(目标+工具+LLM),建 AgentExecution
API → Celeryexecute_agent.delay() 入 Redis 队列,API 立即返回
worker 跑一步:按 current_step 分派 handler,调 LLM 选工具、执行、观察
自我重排:这一步完成后,再排一个任务给自己(2秒后)跑下一步 ↺
Feed 流回:每步产出写 Feed,GUI 轮询实时展示,直到完成
L02

① 创建智能体

GUI 调 POST /agents/createcontrollers/agent.py:60):校验 project 和 tools → Agent.create_agent_with_config 落库 → 立刻建一条 AgentExecution(status='CREATED')→ 把 goal/tools/model 写进 AgentExecutionConfiguration

读法:"在 GUI 点 Create Agent"背后就是这个接口。它同时创建"定义"(Agent + 配置)和"第一次运行"(AgentExecution)。此刻智能体还没跑,只是记录已建好。
L03

② 入队 Celery

POST /agentexecutions/addcontrollers/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 的双进程,同一模式。
🎭 第一人称请求之旅:现在你就是"一次 AgentExecution" 我诞生了——API 在 /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,所以换谁来做、中间停几次,都能接着做我。
L04

③ worker 跑一步

Celery worker 领取 execute_agent 任务(worker.py:66)→ AgentExecutor.execute_next_stepjobs/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()
读法:worker 只跑一步——按 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 个进程从头跑到尾。
L05

④ 自我重排续跑(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)
"循环"就是这么转起来的 worker 跑完第 1 步 → 排一个"跑下一步"的任务(2 秒后)→ 另一个 worker(或同一个)领走跑第 2 步 → 又排"跑第 3 步"…… "一步→入队→下一步→入队……"形成后台自主循环,直到 status 变 COMPLETED 或达到迭代上限。进度存在 DB(current_agent_step_id)、对话存在 Feed——这就是 Day 02 说的"循环在 DB 和队列里"。出错时 countdown=15 延迟重试(不丢任务)。
L06

⑤ Feed 流回 GUI

每一步的思考、工具结果都写入 AgentExecutionFeedagent/output_handler.py:48,Day 02)。GUI 轮询 GET /agentexecutionfeedscontrollers/agent_execution_feed.py)拿到每一步 feed,实时展示智能体在干嘛。

你在界面上看到的"智能体思考流" worker 在后台一步步跑,每步把"我想了啥、调了什么工具、得到什么结果"写进 Feed 表。GUI 每隔几秒轮询一次 feed 接口,把新的 feed 渲染到界面——于是你看到智能体的思考和行动"实时"滚动出来。(注意 SuperAGI 用轮询而非 WebSocket——GUI 定期问"有新进度吗"。)需要人工确认时,某步停在 WAITING_FOR_PERMISSION,GUI 显示批准/拒绝按钮。

👶 小白:.delay() 让 API 秒回了,那我怎么知道智能体到底跑完没、结果去哪看?

👨‍🏫 老师:靠这一步的 Feed 流回 + GUI 轮询。worker 在后台每跑一步就把思考和工具结果写进 AgentExecutionFeed,GUI 每隔几秒轮询 /agentexecutionfeeds 把新内容刷出来;当 status 变成 COMPLETED 就是跑完了。状态和产出全在数据库里,你随时刷新、随时查,不用盯着那个请求干等。这正是"接单/干活分离"要配一条"进度回传"通道的原因。

L07

为什么这样最好

  • 不阻塞:API 秒回,智能体在后台慢慢跑,用户不用干等。
  • 可扩展:多个 Celery worker 能同时跑多个智能体(并发)。
  • 可恢复:每步状态持久化,进程崩了重启能从断点续跑(不丢进度)。
  • 可暂停/审批:状态机支持 PAUSED/WAITING_FOR_PERMISSION,随时挂起恢复。
核心心智模型(一句话):GUI 定义智能体 → API 建 Execution 入 Redis 队列 → Celery worker 逐步跑自主循环、每步自我重排、每步写 Feed → GUI 轮询展示。API 全程不阻塞,状态全持久化,worker 可水平扩展。这就是"把自主智能体做成可运维生产系统"的架构。
L08

🎓 第 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 挂单、worker 做一道、做完再挂单、Feed 上桌看得见」
💰 数字感受: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 任务
下周预告 · Day 06:深入 Agent 执行循环——迭代步 vs 工具步、经典的 think→choose tool→execute→observe 到底在哪一步发生。
← Day 04 运行 Day 06 · 执行循环 →