Learn Claude Code

Python 复刻agents/s09_agent_teams.py

Claude Code 可以同时跑几个独立的 agent,每个有自己的人设、自己的对话历史。它们之间通过一个共享邮箱互相发消息,能互相看见、互相回应。模拟评审小组、跨学科咨询这类需要多视角讨论的场景就靠这套机制。


9.1 队友与子会话的区别

子会话和队友都是"不止一个 agent 在工作"的实现方式,但生命周期完全不同。子会话详见第 10 节。

子会话是一次性的。主会话派出去给它一个任务,子会话跑完返回一段摘要,随即销毁。下次再派一个子会话是全新的,跟之前那个没关系。

队友是常驻的。一旦启动就一直存在。你可以发消息给它、它处理后回复你、过两天再发消息它还记得之前的讨论。队友的"记忆"——也就是它的对话历史——持久保留。

简单的派单用子会话,复杂的多轮讨论用队友。模拟评审小组属于后者:方法学审稿人提"OLS 与 IV 系数差 10 倍的合理解释是 OLS 同时被反向因果向上偏与遗漏变量向下偏抵消,最终系数趋近 0",计量审稿人看到后会反驳"也可能是 IV 弱工具变量放大偏误,需要查 K-P Wald F 值是否真的大于 10"。这种交叉影响子会话做不到。

9.2 队友怎么组织

每个队友在工作目录的 .team/<name>/ 下有自己的资料夹。资料夹里有几样东西:identity.md 描述这个队友的人设,自己的对话历史文件,自己的待处理消息列表。

这个项目里 4 个队友的 identity.md 各自摆明视角:

  • .team/method_reviewer/identity.md:"方法学审稿人,熟读 Imbens & Rubin 2015 与 Angrist-Pischke 2009。关注 IV 工具变量合理性、识别策略前后一致、PSM 协变量平衡。常问:'反向因果的方向是?工具变量的排他性约束你怎么写?'"
  • .team/stat_reviewer/identity.md:"计量审稿人,熟读 Cameron-Miller 2015 聚类标准误综述。关注 reghdfe firm+year 双固定效应、企业层 cluster 聚类、是否需要双重聚类、K-P Wald F 与 Hansen J 的报告完整度。常问:'cluster 单位选 firmid 是否足够?年份聚类是否要加?'"
  • .team/writing_reviewer/identity.md:"写作审稿人,关注叙事一致性。常问:'主回归 β=0.0004 不显著与稳健性 A1/B2/Bank/Rdebt 全部显著并存,文字怎么叙述才不前后打架?'"
  • .team/contribution_reviewer/identity.md:"新意审稿人,熟读唐亮 2025、李思飞 2025、代飞 2025、强国令 2025 四篇前置。关注本项目相对前置的边际贡献是否被讲清楚——A2 跨框架稳健性矩阵、债权侧效应大于股权侧、绿色金融试验区与数字化转型异质性新增维度。"

队友状态完全独立。主会话退出不影响队友。某个队友进入等待状态不影响其他队友继续工作。

队友之间通过 .team/inbox/ 这个共享邮箱通信。这个邮箱是一个目录,里面每条消息是一份独立的文本文件。所有队友都能读这个邮箱,按消息上的"收件人"字段判断哪些与自己相关。

9.3 一次真实运行里队友的互动

下面是 4 人审稿队那次评审会的关键消息线,按时间戳排开。

msg-001 (broadcast, from main):"请按 identity.md 视角各自起一份对 PC_ESG_主表汇总.docx 的初评。表 6 OLS 0.0004 / IV1 0.0052** / IV3 0.0021** / IV1+IV2 0.0042* Hansen J p=0.057;表 7 PSM ATE 0.0032***(t=3.976) / Placebo p_perm=0.000 / Heckman lambda=0.018* / Change β=-0.0001 不显著;表 8 KZ 通道不显著 / Myopia 通道 a 段 β=0.0008* 与假设方向相反;表 9 仅非国有 β=0.0009** 显著;表 10A A1/B2/Bank/Rdebt 全部显著但 A2 主测度不显著。"

msg-002 (from method_reviewer):"IV1+IV2 Hansen J p=0.057 临界。文献里这个 p 值是被审稿人最常 challenge 的点。建议单独跑 IV1 与 IV2 各自的 Hansen 不可识别检验。另外 PSM ATE 0.0032*** vs PSM 后再 reghdfe β=0.0004 不显著——这两个看似矛盾的结果一定要在文中讲清楚 PSM 是横截面 ATE 而 reghdfe 是 within-firm 效应,否则审稿人会以为你在挑结果。"

msg-003 (from stat_reviewer, replying to msg-002):"同意 method 那条。补充:表 6 OLS β=0.0004 SE=0.0003,t≈1.3;IV1 β=0.0052 SE=0.0025,t≈2.1。t 值差异主要来自 β 抬升而不是 SE 缩小,说明 IV 矫正后系数确实变大、不是弱工具放大。K-P Wald F = 210.259 远大于 10 排除弱 IV 担忧。把这个 F 值写进表 6 注脚很重要。"

msg-004 (from writing_reviewer, replying to msg-001):"叙事的最大风险点:'A2 主测度 OLS 不显著 → IV 显著 + PSM 显著' 这条故事线读者第一反应是怀疑 OLS 是真的 β。建议在引言里就把它定位为'OLS 偏误约 10 倍(0.0004 vs 0.0052)'。同时表 10A 里 PC 仅 Rdebt β=0.0159*** 远高于 PC 仅 Bank 0.0036**——这个差异本身值得在 PC 内部分解那一节专门讨论,是 PC 内部结构差异的强证据。"

msg-005 (from contribution_reviewer):"本项目相对前置文献的边际贡献我读到的是:(1) A2 跨框架稳健性矩阵填补唐亮、李思飞均仅用 A1 的空白;(2) 债权侧效应明显大于股权侧(Bank 0.0036** + Rdebt 0.0159*** vs 仅 Stequity 0.0020 不显著)与唐亮 2025 的结论方向相反,必须正面讨论;(3) Myopia 机制与假设方向相反(a 段 β=0.0008* 是 PC 提高反增短视)——这条要么作为新发现讨论、要么按代飞 2025 重做 myopia 测度后报告。建议在引论第 4 段专门讲这三条边际贡献。"

msg-006 (from method_reviewer, replying to msg-005):"contribution 提到 Myopia 方向相反这点很关键。建议在机制章节加一段 'a 段系数为正但绝对值很小(0.0008)、b 段不显著(-0.0084),结合 Sobel z=-3.089 但间接效应 a*b ≈ -0.00001(接近 0),可以判定 Myopia 通道实际上未识别出有效中介,而不是相反方向的中介。'"

msg-007 (from writing_reviewer, replying to msg-006):"采纳 method 那条。我把这段写进机制小节草稿,今晚发给 main 审一遍。"

整场讨论 7 条消息覆盖 4 个视角,其中 method ↔ stat ↔ writing 三方在 K-P Wald F、PSM 与 reghdfe 的差异上有交叉互证,contribution 单独提了边际贡献结构。这种"一人提观点、两人反驳补强、第四人收稿改文"的协作子会话做不到。

9.4 消息怎么收发

队友发消息时调用 send_message 工具,传入三件信息:收件人列表、消息类型、消息内容。代码侧的执行函数把这三件信息写成一份新文件放进邮箱目录,文件名带时间戳和发件人名字,确保按时序排列。

收件人填一个具体名字就是定向消息——比如 stat_reviewer 给 method_reviewer 单独发"PSM 后再 reghdfe 系数掉到 0.0004,怀疑效应主要在 firm 横截面,你怎么看"。收件人填 inbox 就是广播,所有队友都能看到这条消息。

队友读邮箱时调用 read_inbox 工具。它扫一遍邮箱目录,找出所有"收件人含自己名字"且"上次没读过"的消息,返回给模型。模型把这些消息加进自己的对话历史,作为下一轮的输入。

每个队友在自己的循环里周期性调用 read_inbox。这样它能定期被其他队友的消息唤醒,做出回应。如果没人发消息它就保持等待状态。

9.5 用邮箱通信的设计

让队友之间通过文件通信,不走直接互相调函数的路径,背后有几方面好处。

每条消息是一份独立文件,写入是天然不会被打断的——两个队友同时给某第三个队友发消息,两份文件各自落盘,谁也不会冲掉谁。不需要复杂的并发控制机制。

文件还提供了一份完整的讨论历史。所有消息按时间戳排列在 .team/inbox/ 里,看一眼这个目录就能复盘整个评审讨论。后续 v2 准备好再来时,同一组队友读自己的对话历史和邮箱里 v1 的讨论,自然在 v1 的基础上继续推进——例如审稿意见回来后让 method_reviewer 重新评估"反向因果方向的论证",它会先翻 inbox 里 msg-002 的历史观点再补新评。

队友之间还可能进入"等待回应"状态,停下不持续轮询,节省资源。某个队友把意见发出去后没事可做,就停下来等其他队友的回应到达。这种"被消息唤醒"的模式比一直空跑省资源。

9.6 容易踩的坑

队友数量增长后邮箱里的消息量增长更快。10 个队友的全互动每轮可能产生几十条消息,10 轮就是几百条。邮箱目录定期归档可以缓解,但邮箱本身没有自动清理。

队友的人设由 identity.md 单向定义。这份文件一旦写好,队友的所有判断都受这份人设影响。让 method_reviewer "换个新意视角看"需要显式发消息要求,identity.md 本身不会自动调整。

队友之间的协调依赖消息被及时读取。如果某队友长时间没调用 read_inbox,发给它的消息会堆积。Claude Code 通常在每轮循环开始时插一次 read_inbox,但具体频率取决于实现。

9.7 知识地图

关键词含义容易误会的点
.team/<name>/每个队友的独立资料夹每个队友是独立 agent,不是同一个 Claude 角色扮演
.team/inbox/共享邮箱目录,所有队友可读每条消息一份文件,按时间戳排列;天然支持并发写入
广播 vs 定向收件人填 inbox 或具体名字同一份文件,所有人读同一份;不会被复制多份
与子会话区别队友常驻、互相可见、自主驱动子会话跑完即销毁;队友可以多轮交互、持续讨论