王者荣耀世界如何规划体力
2026-07-07 3386157
2026-07-07 0
如果你已经写过或读过「单 Agent + 工具循环」,多半遇到过这种尴尬:

Agent Teams 的思路很直白:Lead 负责统筹;Teammate 在独立线程里跑自己的 loop;彼此用 MessageBus 传话;Lead 通过 inbox 注入把结果接回主上下文。
一句话:
很多教学实现里,subagent 是这样工作的:
Lead 调用 task 工具→ 等 subagent 跑完(阻塞)→ 整段历史作为 tool_result 塞回 Lead
适合短任务;不适合「Lead 继续想、队友并行查」。
Agent Teams 改成:
Lead 调用 spawn_teammate→ 后台线程启动 teammate_loop(不阻塞)Lead 继续对话 / 做别的事→ teammate 完成后 BUS.send → lead 的 inbox→ queue_processor 发现 inbox → 自动唤醒 Lead 的 agent_loop
Teammate 不是 tool 的返回值,而是一个在跑的工人。
① 用户打字→ history → agent_loop② Cron 到点 → _queue → inject → agent_loop③ Teammate 回信 → inbox→ inject → agent_loop
Cron 和 Teammate 都不单独调模型「乱入」,而是变成 外部事件,由后台 queue_processor 抢锁后统一交给 Lead 的 agent_loop 消费——这是很多 Agent Runtime 的共同形状。
Lead agent loopMessageBus Teammate loop+----------------+ +-----------++-------------+| prompt + tools | --spawn----->| .jsonl| <---send---- | own history || inject inbox | <---send------ | 邮箱| ---inbox---> | own tools |+----------------+ +-----------++-------------+
bash / 读写文件(教学版未做权限隔离);messages 列表。队友读了哪些文件、执行了哪些命令,留在队友自己的上下文里;Lead 最终只看到 inbox 里那条 result。
生产里常见 Redis、Kafka、数据库队列表。教学代码用 每个 Agent 一个 JSONL 文件,足够把机制讲清楚。
目录示意:
.mailboxes/lead.jsonlreviewer.jsonl
send():向目标文件 append 一行 JSON:
{"from": "reviewer","to": "lead","content": "Parser looks good","type": "result","ts": 1779780000.0}
read_inbox():读光并删除文件(消费式),避免同一条消息反复注入。
| 工具 | 作用 |
|---|---|
spawn_teammate | 按 name / role / prompt 启动后台队友 |
send_message | 给某个 agent 发消息(含队友之间) |
check_inbox | 主动读 Lead 邮箱(自动注入时也可不用) |
spawn_teammate 本质是启动守护线程:
threading.Thread(target=teammate_loop,args=(client, model_name, name, role, prompt),daemon=True,).start()
Lead 立刻拿到「已启动」,不会卡在队友的十轮工具循环里。
Teammate 有自己的 system prompt 和 messages,入口任务来自 Lead 的 prompt。
工具白名单(教学版):
bash、read_file、write_file、edit_file、send_messagespawn_teammate、schedule_cron …(避免队友再 spawn 队友,复杂度爆炸)轮数上限:最多 10 轮 tool loop,防止后台线程无限烧 token。
结束时无论成败,都会:
BUS.send(队友名, "lead", 最后一段文本, msg_type="result")
并从 active_teammates 里注销。
Lead 每轮调模型前会执行:
inject_inbox_messages(messages)# 读 lead.jsonl → 删文件 → 追加一条 user 消息
注入内容类似:
为什么是 role: user?
对 Agent Loop 来说,inbox、cron 触发、用户打字都是 「外部世界发来的新事件」。模型下一轮统一按「用户侧输入」处理,无需为每种事件单独设计 role。
Cron 触发则用 包一层,逻辑相同。
第 8 篇里,后台线程只盯 cron 队列。第 9 篇条件变成:
if not SCHEDULER.has_queue() and not BUS.has_inbox("lead"):continue
有定时任务 或 有队友回信 → 尝试非阻塞获取 agent_lock → 跑一轮 agent_loop(history)。
agent_lock 解决的是:用户正在终端输入时,后台不能同时改同一份 history。拿不到锁就 0.2 秒后再试。
没有替换 cron,而是并入同一套「外部事件」模型:
cron 到点→ tick 入队 → inject_cron_jobs →
持久化方面:durable=True 的 cron 会写入 .scheduled_tasks.json,重启后 load() 恢复;已到点但未消费的队列仍在内存里,进程挂了就没了(教学边界)。
环境变量(.env):
OPENAI_BASE_URLOPENAI_API_KEYMODEL_NAME
仓库根目录:
python3 harness_agent/09_agent_teams.py
推荐试一句(复制到终端即可):
启动一个 teammate,名字叫 reviewer,角色是 code reviewer。让它阅读 harness_agent/09_agent_teams.py,用几句话说明 MessageBus 怎么工作。
预期现象:
spawn_teammate,终端打印 [teammate] reviewer spawned;[bus] reviewer -> lead,[queue processor] delivering external work;| 简化点 | 真实系统常见补法 |
|---|---|
| 文件 JSONL 邮箱 | MQ / DB / gRPC |
| 单进程锁 | 分布式锁、ack、重试 |
| Teammate 最多 10 轮 | 长期 worker、idle 唤醒 |
| 共享工作目录 | 沙箱、per-agent 权限 |
| 无取消/超时/成本上限 | lifecycle、budget、审计 |
知道边界,才知道下一版该往哪长。
从「一个人干活」到「一个小队分工」,这是 Coding Agent 走向工程化协作的第一步;后面还可以叠权限、结构化结果 schema、队友生命周期管理——但 邮箱 + 注入 + 后台唤醒 这条骨架已经够用。