一张图先把几个名词的空间关系摆清楚,后面读代码就不会把 Agent 和 Message 搞混。我们用建筑来类比:Agent 是房间里的角色,Conversation 是房间里的对话记录,Message 是对话里的每一句话,Task 是这场对话要交的差。

Agent 不是模型本身,而是"模型 + 系统提示 + 配置 + 记忆"的封装。一个 Agent 可以接入某个大模型,但从概念上它独立于模型——你随时换模型,Agent 作为角色不变。我们常跟团队说:先想清楚要几个角色,再想每个角色配什么模型。
# Agent 是封装,不是模型 from autogen import ConversableAgent cfg = {"model": "gpt-4o-mini", "api_key": "YOUR_KEY"} agent = ConversableAgent( name="planner", llm_config=cfg, system_message="你是项目规划者,只输出步骤不写代码。", ) print(agent.name) # planner print(agent.system_message) # 你是项目规划者... # 换模型时只改 cfg,角色职责不变
Conversation 是 Agent 之间消息的累积序列。一次 initiate_chat 开启一段对话,里面每一轮都是一条消息追加进历史。GroupChat 则是多个 Agent 共享同一段历史——这是协作的关键,见第四章。
每条 Message 至少带发送者、接收者和内容。内容可以是自然语言,也可以是函数调用请求或函数返回结果。理解消息结构,是看懂函数调用回环的前提。
# 打印一次对话里每条消息的发送者和内容摘要 chat = planner.initiate_chat(executor, message="第一步:读取数据文件。", max_turns=3) for msg in chat.messages: role = msg.get("name") or msg.get("role") content = str(msg.get("content"))[:40] print(f"[{role}] {content}") # [planner] 路径是 /data/input.csv。
Task 是个更上层的概念,通常指"这段对话最终要完成的事",比如"生成可运行的爬虫"。AutoGen 本身不强制 Task 对象,任务靠你发起的对话和终止条件来界定。我们把 Task 单列出来,是为了和 Conversation 区分:一个 Task 可能由多段 Conversation 组成。
单独看每个词都不难,难的是理解它们怎么串成一次完整运行。一个 Task 到达后,你把它拆成若干段 Conversation;每段 Conversation 由多条 Message 推进,而每条 Message 都由一个 Agent 产出。可以用建筑来类比:Task 是"要盖的楼",Conversation 是"每一层的施工记录",Message 是"工人之间的每一次交底",Agent 是"持有不同工种证书的工人"。楼能不能盖好,不取决于某个工人多聪明,而取决于交底是否清晰、记录是否连续。
这里有个常被人忽略的细节:Agent 的"记忆"其实就是它所在 Conversation 的历史。所以当你把一个 Agent 挪到另一段 Conversation,它就"失忆"了——它带不走之前的消息。这个特性决定了多智能体系统的状态是跟着对话走、而不是跟着角色走。理解了这点,你就不会困惑"为什么换了个群聊我的 Agent 不记得前文了"。同样,因为 GroupChat 让多个 Agent 共享同一段历史,所以群聊里每个成员都看得到别人的发言,这正是协作能成立的前提(详见第四章 4.2)。
| 概念 | 类比角色 | 状态附着于 | 常见误用 |
|---|---|---|---|
| Agent | 持证工人 | 自身配置与系统提示 | 把模型和 Agent 画等号 |
| Conversation | 施工记录 | 对话历史序列 | 以为换群聊记忆还在 |
| Message | 一次交底 | 发送者/接收者/内容 | 忽略函数调用的消息形态 |
| Task | 要盖的楼 | 由对话与终止条件界定 | 期待框架自带 Task 对象 |
把这几个概念搞混,不是"考试丢分",而是会在真实调试里绕大弯。最常见的是把 Agent 和模型画等号:于是换模型时去改 Agent 逻辑,而不是只动 llm_config,结果配置越改越乱。其次是以为 GroupChat 里每个 Agent 有"私有记忆"——其实它们共享同一段历史,想让某 Agent 独享信息,只能靠它在消息里明说,否则别的角色看不到。还有人期待框架自动管理 Task 生命周期,结果没设终止条件,对话一直开着一个永远完不成的"任务",烧钱无休。
这几个误区都指向同一件事:概念层次清楚,你才能在出错时精准定位"问题在 Agent 配置、在消息结构、还是在中止逻辑"。第一章把地基打牢,后面每一章的 bug 几乎都能映射回这四个概念之一。所以这一节看似是基础名词,实则是你全册调试能力的底层坐标系。
⚠️ 别把 Agent 和模型画等号。一个模型可以服务多个 Agent,一个 Agent 也可以换模型——混为一谈会导致配置混乱。
💡 概念层次清楚了,"对话即编排"就具体了:Task 拆成 Conversation,Conversation 由 Message 推进,Message 由 Agent 产出。