核心思想
AutoGen 的核心思想是通过对话实现协作。它将多智能体系统抽象为一个由多个“可对话”智能体组成的群聊。开发者可以定义不同角色(如 Coder、ProductManager、Tester 等),并设定它们之间的交互规则(例如:Coder 写完代码后由 Tester 自动接管)。
任务的解决过程,就是这些智能体在群聊中通过自动化消息传递,不断对话、协作、迭代,直至最终达成目标的过程。
模型客户端配置
首先,我们先来了解一下模型客户端的配置。
1 | |
以上代码是实例化一个模型客户端的 Demo,指定了各种参数:使用的 LLM、最大 Token 数、模型信息等。
核心参数解析:Temperature
其中,temperature 是一个极其关键的参数,它控制着模型输出概率分布的“尖锐程度”。
简单来讲,在模型预测下一个词时,会把每个候选词的原始分数(Logits,
假设现在有三个候选词及其原始分数:
- 词 “好”:
3分 - 词 “棒”:
2分 - 词 “烂”:
1分
根据不同的
- 假设一:
(原始状态)
运算后的分数不变,原始分数直接参与后续概率计算。 - 假设二:
(趋于保守)
分数会变得苛刻,放大差距。运算后:
词 “好”(3/0.5=6分)> 词 “棒”(2/0.5=4分)> 词 “烂”(1/0.5=2分),“好”的优势被进一步拉大。 - 假设三:
(趋于随机)
分数变得宽容,缩小差距。运算后:
词 “好”(3/2=1.5分)> 词 “棒”(2/2=1分)> 词 “烂”(1/2=0.5分),各个词被选中的概率变得更加相近。
总结来说,temperature 值越大,各个词之间的原始差距被缩得越小,模型选词越偏向随机发散;值越小,差距被放大,模型越偏向确定保守。
注: 实际模型中,运算后的分数最终还会通过 Softmax 函数(指数归一化)转换为
的概率!上面的 3/2/1分只是为了方便理解是如何放大/缩小差距的。真实模型中,转换后的概率大致呈现下方表格所示的动态变化趋势:
| Temperature |
效果 | 概率分布示例长什么样 |
|---|---|---|
| 极度确定,永远选最高概率词 | 好: 99%,棒: 1%,烂: 0% | |
| 保守,高概率词碾压其他 | 好: 80%,棒: 18%,烂: 2% | |
| 平衡 | 好: 55%,棒: 35%,烂: 10% | |
| 使用模型原始分布,不做任何压缩 | 好: 45%,棒: 30%,烂: 25% | |
| 分布趋于均匀,各词概率接近,输出混乱 | 好: 36%,棒: 34%,烂: 30% |
核心参数解析:top_p
top_p(Nucleus Sampling,核采样)的作用简单来说就是**“砍尾巴”**。它通常和 temperature 配合使用:先由 temperature 处理数据得出概率分布,再根据 top_p 的阈值比例来砍掉尾巴,最后才进行选词。
假设经过 temperature 处理后,候选词的概率如下:
- “好”:45%
- “棒”:25%
- “绝”:15%
- “行”:8%
- “烂”:5%
- …(其他低概率词):合计 2%
如果我们设置 top_p = 0.9(即 90%),模型会按概率从高到低累加,只截取累积概率刚达到 90% 时的单词集合:
- 第一名 “好” (45%) —— 累计:45%(没到 90%,继续)
- 第二名 “棒” (25%) —— 累计:70%(没到 90%,继续)
- 第三名 “绝” (15%) —— 累计:85%(没到 90%,继续)
- 第四名 “行” (8%) —— 累计:93% (超过了 90%!停!)
结果:只有 【好、棒、绝、行】 这 4 个词留下来进入最终的抽签池(并且这四个词的概率会按比例重新放大归一化到 100%)。而排在后面的“烂”以及更糟的词,将被直接拦腰斩断、彻底除名。哪怕它原本还有 5% 的机会,现在的入选概率也是 0%。
temperature 和 top_p 的协同工作
在底层运行中,这两个参数可以说是“黄金搭档”。它们的协同工作流程如下:
- 算概率:先使用
temperature来决定候选词分差是被放大还是缩小,计算出一个带有特定“感情色彩”的概率分布。 - 砍尾巴:再用
top_p执行“截断”——看着调完之后的概率单,从上往下加,一旦累计达到阈值(如0.9)就划线,把排在后面的“弱势词”全扔掉。 - 终极抽签:从活下来的“精英”圈子里,按它们的相对概率随机抽取一个词输出。
核心区别总结:
| 比较维度 | Temperature (温度) | top_p (核采样 / 截断采样) |
|---|---|---|
| 手段 | 像**“滤镜”**:改变所有人分数的差距。 | 像**“剪刀”**:直接把排在后面的选项咔嚓剪掉。 |
| 态度 | 温柔:即使把 0.0001% 的机会,理论上没绝杀。 |
冷酷:只要你没挤进去前 |
| 解决的问题 | 防止输出过于死板(提高 |
剪除“长尾噪音”。语言模型词汇表有几万个词,往往有几千个极低概率的词(比如乱码或离谱生僻字)。top_p 的任务就是把这几千个垃圾选项永远关在门外,防止哪怕万分之一的“爆冷抽中”。 |
核心参数解析:json_output 与 structured_output
这两个参数通常一起出现,它们主要用于指导或强制大模型以结构化的 JSON 格式返回输出。
当
json_output=True时:
它就像是在提示里告诉模型:“请自觉一点,把结果按照 JSON 的格式发给我。”- 模型表现:它会尽力返回 JSON。
- 潜在问题:因为它只是“尽力”,有时候它可能会漏写一个逗号、多加一个引号、把字段名拼错(比如把
name写成了first_name),甚至在 JSON 外面还啰里啰嗦加一句“这是您要求的 JSON 代码”。 - 可能后果:当你的程序尝试去解析(Parse)这段文本时,极易因为格式或类型的细微错误而自动报错挂掉。
当
structured_output=True时:
这相当于直接给大模型发了一张“固定格式的机读答题卡”。此时,这不再仅仅是一个提示语的作用,而是从大模型底层的推理生成机制层面,严格限制了模型的输出概率分布。它能确保输出百分之百符合你预先定义的 JSON Schema(数据结构)约束,连多余的一个废话字符都不会出现。
**避坑指南:**虽然当前绝大多数模型都能听懂“输出 JSON”的指令(即支持
json_output),但底层引擎直接支持严格structured_output模式的模型并不算多。该特性目前更广泛且成熟地应用于 OpenAI 的官方原生模型(如GPT-4o等)。在上文的示例代码中,我们对接的是第三方 DeepSeek 服务,受限于 API 的原生支持情况,所以这里我们暂时将
structured_output设置成了False。
AutoGen 的 Agent (智能体)
1 | |
AssistantAgent
AssistantAgent 是 AutoGen 中最基础、最常用,也是最成熟的对话智能体类。它是任务的主要解决者,其核心是封装了一个大型语言模型(LLM)。
如果把 AutoGen 比作一个“虚拟外包项目组”,那么 AssistantAgent 就是这个项目组的核心脑力员工。它本身“没有手”(不具备直接在本地电脑上执行代码或操作的能力),但它拥有最强的思考与规划能力。你通过 system_message 给它分配什么角色(如:前端专家、文案策划、数据分析师),它就能胜任对应的工作。
除此之外,它还内置了以下强大的核心能力:
- 记忆功能(维护上下文):大模型本身是无状态、没有记忆的,需要每次对话时都把之前的对话历史统一发送给大模型。
AssistantAgent内部自动实现了历史消息的管理与拼接功能。 - 代码提取与格式化(Code Block Parsing):大模型在回答时,往往会将代码、代码注释、说明文字甚至一些废话混合在一起返回。
AssistantAgent内置了提取能力,它会自动扫描大模型回答的 Markdown 内容中的独立代码块,方便后续交给其他 Agent(如UserProxyAgent)去执行。 - 工具调用(Function Calling / Tool Use):可以给大模型注册一些 Python 函数(例如:
get_weather(city: str)、search_web(query: str))。当你问到某些模型不知道的实时/专有信息,且工具恰好可以获取时,模型会按照约定格式输出调用指令。底层机制捕获该指令后会执行对应函数,再把调用结果返回给大模型。 - 自动化的重试与纠错(Auto-Reply & Fallback):面对复杂的任务,代码往往一次性跑不通。这时别的 Agent(通常是
UserProxyAgent充当的执行者和测试者)在运行时如果抛出异常,会把异常信息反馈给它(例如:“你刚才写的代码抛出了 IndentationError,在第4行。”)。AssistantAgent底层自带auto-reply(自动回复)机制,不需要开发者写额外的while循环。它收到报错后会自动将报错信息塞进上下文,再次请求大模型:“根据报错,给我一个新的修复方案。” 只有当问题解决,或者达到最大重试次数(max_consecutive_auto_reply)时,交互才会停止。 - 终止条件判断(Termination Detection):AI 群聊很容易陷入无限死循环(例如两个 AI 互相发送“谢谢你”、“不客气”)。因此,
AssistantAgent经常被配置一种“终止词”识别能力。比如,你可以约定当任务彻底完成时,在回复末尾加上TERMINATE。框架一旦检测到该触发词,就会自动结束这轮多智能体对话任务。