第 3 章 · 04 swarms.Agent 与 Conversation 抽象 本节摘要:本节退一步,看 AutoHedge 五个 Agent 与消息历史的「容器」——swarms 框架的 类与 类。AutoHedge 本身不实现这两者,而是从 库直接 import 来用。本节从 workers.py 与 main.py 的实际调用归纳出 构造参数的全貌(agentname/systemprompt/modelname/maxloops/handoffs/tools/outputtype/contextlength/verbose),再讲清 main.
本节摘要:本节退一步,看 AutoHedge 五个 Agent 与消息历史的「容器」——swarms 框架的
Agent类与Conversation类。AutoHedge 本身不实现这两者,而是从swarms库直接 import 来用。本节从 workers.py 与 main.py 的实际调用归纳出Agent构造参数的全貌(agent_name/system_prompt/model_name/max_loops/handoffs/tools/output_type/context_length/verbose),再讲清 main.py 里Conversation(time_enabled=True)这个消息历史抽象——它如何add消息、如何用三种方法(return_messages_as_list/dict、return_history_as_string)取出历史。读完本节,你理解 AutoHedge 与 swarms 框架的边界——前者是「配置层」,后者是「运行时」。
内容来源:原项目源码
autohedge/workers.py、autohedge/main.py(from swarms import Agent, Conversation),精读并套用体系化模板。
⚠️ 现实澄清:
Agent与Conversation的内部实现在 swarms 包里(本仓库不含),本节讲的是 AutoHedge 可观测到的用法与参数语义,不深究 swarms 源码。
阅读完本节,你应当能够:
Conversation(time_enabled=True) 给消息加了什么。return_messages_as_list / return_messages_as_dictionary / return_history_as_string 三者的差异。workers.py 顶部 import:
from swarms import Agent
五个 Agent 全是 Agent(...) 的实例。把 workers.py 里用到的所有构造参数汇总,得到 AutoHedge 实际使用的参数表:
| 参数 | 类型 | 含义 | 在哪用 |
|---|---|---|---|
agent_name |
str | Agent 名字,日志与 handoffs 识别用 | 全部五个 |
system_prompt |
str | 角色 + 目标 + 输入输出约定(决定 Agent 行为) | 全部五个 |
model_name |
str | LLM 模型 ID,如 gpt-4.1 / gpt-4o-mini |
全部五个 |
max_loops |
int | 推理轮数(1=单轮) | 全部五个 |
handoffs |
list[Agent] | 可交接的目标 Agent 列表 | 仅 Director |
tools |
list[callable] | 可调用的工具函数列表 | 仅情绪 Agent([exa_search]) |
output_type |
str | 输出格式约束,如 "str" |
风控/执行/量化 |
context_length |
int | 上下文窗口(token 数) | 风控/执行/量化(16000) |
verbose |
bool | 是否打印详细日志 | 四个专家(都 True);Director 未设 |
几个要点:
verbose(用默认)、情绪没设 output_type/context_length。这些不一致不影响运行(走默认值),但能看出代码不够规整。model_name 是字符串:"gpt-4.1" 这种。swarms 内部会把它映射到对应的 LLM 客户端(走 OpenAI API)。这就是为什么必须配 OPENAI_API_KEY。tools 是函数列表:Python 可调用对象直接传进去。swarms 会读它们的 docstring 与类型注解,自动转成 OpenAI function calling 的 schema。所以 exa_search 那段详尽 docstring 不只是给人看,也是给 LLM 看。💡 核心心法:Agent 的「智能」来自三处:system_prompt(说什么算对)、model_name(脑子有多强)、tools/handoffs(手脚和同事)。把这三组参数调对,Agent 行为就基本定了。AutoHedge 的全部工程,几乎就是在这三组参数上做配置。
Agent 是一个有状态的推理引擎:
.run(task=...) 方法:接收一段任务文本,内部驱动「LLM 推理 → 可能调工具 → 可能 handoff → 综合」,返回最终文本(行为)。调用方(如 main.py)只需要:
output = director_agent.run(task=task)
不必关心 swarms 内部怎么调 OpenAI、怎么解析 function call、怎么驱动 handoff——这些都是 Agent.run 封装的。这是框架的价值:把多 Agent 编排的复杂度藏进 .run。
main.py 顶部 import:
from swarms import Conversation
AutoHedge.__init__ 里创建它:
self.conversation = Conversation(time_enabled=True)
Conversation 是一个消息历史的容器,职责单一:记录「谁(role)说了什么(content),什么时候(timestamp)」。它不做推理,只「记账」。
time_enabled=True 的作用:给每条消息自动加时间戳。这样历史里每条消息除了 role/content,还有一个时间字段,便于追溯。这与 workers.py 顶部注入 system_prompt 的 _SYSTEM_SUFFIX(当前时间)是互补的——前者给 LLM 看时间,后者给人/日志看时间。
main.py 的 run 方法对 Conversation 做了三个动作,覆盖它全部用法:
self.conversation.add(role="user", content=f"Task: {task}") ... self.conversation.add(role="director", content=output)
add(role=..., content=...) 是 Conversation 的核心写入方法。AutoHedge 只用了两种 role:"user"(用户任务)和 "director"(Director 的产出)。注意:四个专家的中间产出没有被 add 进这个 Conversation——它们存在 swarms 内部的另一套历史里。AutoHedge 这个 Conversation 只记「用户↔Director」两层。
run 末尾按 output_type 选择取出方式:
if self.output_type == "list": return self.conversation.return_messages_as_list() if self.output_type == "dict": return self.conversation.return_messages_as_dictionary() if self.output_type == "str": return self.conversation.return_history_as_string() return self.conversation.return_messages_as_list() # 默认 list
三者差异(基于方法名的语义):
| 方法 | 返回类型 | 形态 |
|---|---|---|
return_messages_as_list() |
list[dict] |
每条消息一个 dict,装在 list 里;最结构化 |
return_messages_as_dictionary() |
dict |
整个历史聚合成一个 dict(如按 role 分组) |
return_history_as_string() |
str |
把所有消息拼成一长串文本;最易读 |
举例(默认 list,跑完 example.py):
[ {"role": "user", "content": "Task: Analyze the sentiment of oil market...", "timestamp": "2026-08-05T14:30:12"}, {"role": "director", "content": "...(Director 的最终回答)...", "timestamp": "2026-08-05T14:31:45"}, ]
💡 核心心法:
output_type控制的是「怎么把历史取出来」,不是「Agent 怎么推理」。三种格式服务于不同下游:list 适合程序再处理、dict 适合按角色聚合、str 适合直接 print 给人看。默认 list 是最通用的选择。
把 AutoHedge 与 swarms 的边界画清:
┌─────────────────────────────────────────┐ │ 你的代码(example.py / autohdge 命令) │ ├─────────────────────────────────────────┤ │ AutoHedge(配置层) │ │ - prompts.py:五个 system_prompt │ │ - workers.py:五个 Agent 的实例化配置 │ │ - main.py:AutoHedge 主类 + Conversation │ │ - tools/:exa_search 等工具函数 │ ├─────────────────────────────────────────┤ │ swarms(运行时层,外部库) │ │ - Agent 类:推理引擎 + handoffs │ │ - Conversation 类:消息历史 │ │ - LLM 客户端、function calling 调度 │ ├─────────────────────────────────────────┤ │ OpenAI API / Exa API / Jupiter API │ └─────────────────────────────────────────┘
AutoHedge 没有自己实现 Agent 调度、handoffs 驱动、消息历史——这些全用 swarms。AutoHedge 做的是:
⚠️ 现实澄清:这种「薄配置层 + 重框架」的结构意味着:学 AutoHedge 一半在学 swarms。如果想真正理解 handoffs 怎么驱动、function call 怎么解析,得去看 swarms 的源码(它也是开源的)。AutoHedge 本身的代码量(~1400 行)里,真正「自己」的逻辑不多。
swarms.Agent(本章) ──配置──► 五个 Agent(本章 02 节) │ │ handoffs(本章 03 节) swarms.Conversation ──被──► AutoHedge 主类(第 5 章第 3 节)
理解了 swarms 的两个抽象,下一章我们钻进 prompts.py——这些 Agent 的「性格」是怎么用文字塑造出来的。
.run(task) 驱动「LLM→工具→handoff→综合」(行为);框架封装了复杂度。time_enabled=True 给每条消息加时间戳;只记账不推理。return_messages_as_list(list[dict],最结构化,默认)、return_messages_as_dictionary(聚合 dict)、return_history_as_string(长字符串,最易读)。下一章,我们钻进
prompts.py——看这五个 Agent 的 system_prompt 是怎么用文字塑造出「总监/情绪/量化/风控/执行」五种性格的。