基于仓库
microsoft/autogen主干代码(v0.4+ 架构分支,已进入维护模式但仍是最完整的多 Agent 框架参考实现之一)。本文从最底层的 autogen-core 运行时 一路向上拆到 autogen-agentchat 团队编排、autogen-ext 扩展生态、.NET / 跨语言分布式运行时、AutoGen Studio,并附带生产落地教程。
目录
- 项目全景与分层架构
- autogen-core:事件驱动 Agent 运行时
- autogen-agentchat:高层 Agent / Team 编排
- autogen-ext:模型、工具、执行器、内存生态
- 分布式运行时:gRPC + .NET / Python 跨语言
- AutoGen Studio:低代码可视化平台
- 生产应用教程(11 个端到端场景)
- 生产落地清单(性能、安全、可观测、成本)
- 关键源码文件速查表
一、项目全景与分层架构
1.1 仓库结构(关键目录)
autogen/
├── protos/ # 跨语言 protobuf 契约(agent_worker.proto, cloudevent.proto)
├── dotnet/ # .NET 实现:Contracts / Core / Core.Grpc / RuntimeGateway.Grpc / AgentHost
└── python/packages/
├── autogen-core/ # 第 1 层:消息总线、Agent 协议、运行时、Pub/Sub、组件系统
├── autogen-agentchat/ # 第 2 层:AssistantAgent / Teams / Termination / Handoff
├── autogen-ext/ # 第 3 层:OpenAI/Anthropic/Azure 模型、MCP、Docker 执行器、ChromaDB 等
├── autogen-studio/ # 低代码 GUI(FastAPI + React)
├── autogen-magentic-one/ # Magentic-One 编排示例
├── magentic-one-cli/ # Magentic-One CLI 入口
└── agbench/ # Benchmarking 套件
1.2 三层 API 设计哲学
AutoGen 的关键架构决策是分层 + 可扩展,每层职责清晰且建立在下层之上:
| 层级 | 包名 | 关注点 | 适用人群 |
|---|---|---|---|
| Core | autogen-core | Actor 模型、消息路由、Pub/Sub、跨语言协议 | 框架开发者、需要细粒度控制的高级用户 |
| AgentChat | autogen-agentchat | 对话式 Agent、团队编排、终止条件 | 应用开发者(90% 用户在此层) |
| Extensions | autogen-ext | 具体的 LLM 客户端、工具实现、代码执行器 | 需要接入第三方能力的所有用户 |
核心抽象关系图:
AgentRuntime (调度+消息总线)
│
├── 注册并实例化 ──► BaseAgent ──► RoutedAgent ──► AssistantAgent
│ │
├── 投递消息(send/publish) ──► MessageContext ├── ChatCompletionClient
│ ├── Tool / Workbench
├── 维护订阅 ──► SubscriptionManager ──► TopicId ├── Memory
│ └── ChatCompletionContext
└── 拦截器 ──► InterventionHandler
二、autogen-core:事件驱动 Agent 运行时
路径:
python/packages/autogen-core/src/autogen_core/
这是整个 AutoGen 架构的地基。一切 Agent、Team、Tool 最终都在这一层被一个 AgentRuntime 托管。
2.1 Agent 抽象层
2.1.1 协议层:Agent Protocol(_agent.py:12-64)
AutoGen 的 Agent 是协议优先设计——任何符合协议的对象都可作为 Agent,无需继承基类。协议规定了 5 个必备成员:
class Agent(Protocol):
@property
def metadata(self) -> AgentMetadata: ... # type/key/description
@property
def id(self) -> AgentId: ... # 全局唯一地址
def bind_id_and_runtime(self, id, runtime): ... # 实例化时由 runtime 注入
async def on_message(self, message, ctx): ... # 主消息入口
async def save_state(self) -> Mapping[str, Any]: ...
async def load_state(self, state): ...
async def close(self): ...
2.1.2 唯一地址:AgentId(_agent_id.py:12-69)
@dataclass(frozen=True)
class AgentId:
type: str # 类型,例如 "math_expert",匹配 ^[\w\-\.]+$
key: str # 实例 key,例如 "session_42",可任意字符串
# __str__() => "math_expert/session_42"
重要语义:相同 type 的不同 key 是不同 Agent 实例(多租户多会话天然支持)。
2.1.3 实现基类:BaseAgent(_base_agent.py:60-255)
提供:
- 懒加载注册机制:
BaseAgent.register(runtime, type, factory)注册工厂函数,不立即创建实例。 - 直接寻址订阅:每个 Agent 自动获得
TypePrefixSubscription("type:")订阅(行 195-206),允许其他 Agent 用TopicId("type:xxx", "key")直接寻址。 - AgentInstantiationContext:实例化时通过 ContextVar 注入
id与runtime,让__init__不需手动传参(行 86-91)。
2.1.4 路由式基类:RoutedAgent(_routed_agent.py:40-519)
把消息按 Python 类型 自动路由到 @message_handler / @event / @rpc 装饰的方法:
class MathAgent(RoutedAgent):
@message_handler
async def on_question(self, msg: MathQuestion, ctx: MessageContext) -> MathAnswer:
...
@event # 仅响应 publish,不响应 send
async def on_room_event(self, msg: RoomEvent, ctx: MessageContext) -> None:
...
@rpc(match=lambda msg, ctx: msg.priority == "high") # 仅响应高优先级
async def on_urgent(self, msg: Task, ctx: MessageContext) -> Result:
...
装饰器实现关键(行 474-491):
async def on_message_impl(self, message, ctx):
handlers = self._handlers.get(type(message)) # Dict[Type, List[MessageHandler]]
if handlers:
for h in handlers: # 按字典序排序
if h.router(message, ctx): # 自定义 match 谓词
return await h(self, message, ctx)
return await self.on_unhandled_message(message, ctx)
target_types/produces_types在装饰时通过get_type_hints()静态提取,没有运行时类型字符串。@event把is_rpc=False加入 router;@rpc强制is_rpc=True。
2.1.5 闭包 Agent:ClosureAgent(_closure_agent.py:76-242)
把单个异步函数包装成 Agent,签名即类型——非常适合"日志 Agent"、"数据收集 Agent"等无状态场景:
async def collector(ctx: ClosureContext, msg: Result, mctx: MessageContext) -> None:
print(f"got {msg} from {mctx.sender}")
await ClosureAgent.register_closure(runtime, "collector", collector)
2.2 单机运行时 SingleThreadedAgentRuntime
文件:
_single_threaded_agent_runtime.py:149-753
2.2.1 三种消息信封
# _single_threaded_agent_runtime.py:57-93
SendMessageEnvelope # 一对一 RPC,包含 Future[Any]
PublishMessageEnvelope # 一对多广播,无返回
ResponseMessageEnvelope # RPC 响应,唤醒原 Future
2.2.2 主循环 _process_next()(行 671-753)
async def _process_next(self):
envelope = await self._message_queue.get()
match envelope:
case SendMessageEnvelope(...):
for h in self._intervention_handlers: # ① 拦截器链
temp = await h.on_send(msg, ctx, recipient)
if temp is DropMessage:
future.set_exception(MessageDroppedException()); return
asyncio.create_task(self._process_send(envelope)) # ② 投递
case PublishMessageEnvelope(...):
... # 同样链路
asyncio.create_task(self._process_publish(envelope))
case ResponseMessageEnvelope(...):
future.set_result(message) # ③ 唤醒
整个运行时是单线程 asyncio 队列处理器,所有并发通过 asyncio.gather 实现,避免锁。
2.2.3 send_message vs publish_message
send_message | publish_message | |
|---|---|---|
| 目标 | 指定 AgentId | 匹配 TopicId 的所有订阅者 |
| 是否等待响应 | 是(返回 awaitable) | 否 |
ctx.is_rpc | True | False |
| 拦截器 | on_send | on_publish |
2.2.4 懒加载实例化(行 466-512)
async def _get_agent(self, agent_id: AgentId) -> Agent:
if agent_id not in self._instantiated_agents:
factory = self._agent_factories[agent_id.type]
with AgentInstantiationContext.populate_context(agent_id, self):
agent = factory() if not async else await factory()
agent.bind_id_and_runtime(agent_id, self)
self._instantiated_agents[agent_id] = agent
return self._instantiated_agents[agent_id]
意义:注册成千上万种 Agent 类型 + 任意多 key 实例都几乎零开销,只有真正收到消息的 (type, key) 才会被构造。
2.2.5 拦截器:InterventionHandler
class InterventionHandler(Protocol):
async def on_send(msg, ctx, recipient) -> msg | DropMessage
async def on_publish(msg, ctx) -> msg | DropMessage
async def on_response(msg, sender, recipient) -> msg | DropMessage
正交的扩展点——审计日志、PII 脱敏、配额限流、A/B 流量染色都在这一层做。
2.3 Pub/Sub 系统
2.3.1 TopicId(_topic.py:11-48)
CloudEvents 兼容:
@dataclass(frozen=True)
class TopicId:
type: str # 例如 "chat.message"
source: str # 例如 "room_42" 或 URL
2.3.2 三种内置订阅
| 类 | 匹配规则 | 映射 |
|---|---|---|
TypeSubscription(topic_type, agent_type) | 类型完全相等 | AgentId(agent_type, source) |
TypePrefixSubscription(topic_type_prefix, agent_type) | topic.type.startswith(prefix) | AgentId(agent_type, source) |
DefaultSubscription(topic_type="default") | 类型相等且自动检测 agent_type | 同上 |
装饰器糖:
@default_subscription
class MyAgent(RoutedAgent): ...
# 等价于注册时附带 DefaultSubscription("default")
匹配算法(_runtime_impl_helpers.py):
recipients = []
for sub in all_subscriptions:
if sub.is_match(topic_id):
recipients.append(sub.map_to_agent(topic_id))
发布时 _process_publish 用 asyncio.gather 并发投递。
2.4 消息原语
| 类型 | 文件 | 字段 |
|---|---|---|
MessageContext | _message_context.py:8-14 | sender, topic_id, is_rpc, cancellation_token, message_id |
FunctionCall | _types.py:6-12 | id, name, arguments(JSON str) |
SystemMessage / UserMessage / AssistantMessage / FunctionExecutionResultMessage | models/_types.py:10-81 | LLM 消息四件套 |
CreateResult | models/_types.py:107-128 | finish_reason, content, usage, cached, logprobs, thought |
CancellationToken | _cancellation_token.py:6-47 | 线程安全,link_future 自动取消 |
2.5 序列化与跨语言
_serialization.py:14-150 定义协议:
class MessageSerializer(Protocol[T]):
@property
def data_content_type(self) -> str # "application/json" / "application/x-protobuf"
@property
def type_name(self) -> str
def serialize(message: T) -> bytes
def deserialize(payload: bytes) -> T
内置实现:
DataclassJsonMessageSerializer:纯 dataclass → JSONPydanticJsonMessageSerializer:支持嵌套/Union/校验 ⭐ 推荐ProtobufMessageSerializer:跨语言场景必备
SerializationRegistry 维护"类型名 ↔ 序列化器"映射,分布式运行时按 payload 头部的 data_type 反查。
2.6 Component 系统:声明式装配
_component_config.py:18-156
任何核心组件(Agent、Tool、Model、Termination、Memory)都实现:
class MyComp(ComponentFromConfig, ComponentToConfig):
component_type: ClassVar[str] = "tool"
component_version: ClassVar[int] = 1
@classmethod
def _from_config(cls, config: ConfigModel) -> Self: ...
def _to_config(self) -> ConfigModel: ...
→ 任何组件都能 dump_component() 成 ComponentModel(YAML/JSON 友好):
ComponentModel(
provider="autogen_ext.models.openai.OpenAIChatCompletionClient",
component_type="model", version=1, component_version=1,
config={"model": "gpt-4o", "api_key": "..."},
description="...", label="GPT-4o"
)
安全护栏(行 55-82):默认只允许 autogen_core.*、autogen_agentchat.*、autogen_ext.*、autogen_studio.* 命名空间,需要扩展须设 AUTOGEN_ALLOWED_PROVIDER_NAMESPACES。这堵住了"恶意 YAML 加载任意类执行代码"的洞。
2.7 Tool 与 Workbench
协议(tools/_base.py:56-81):
class Tool(Protocol):
name: str
description: str
schema: ToolSchema
def args_type(self) -> Type[BaseModel]
def return_type(self) -> Type[Any]
async def run_json(args: Dict, cancellation_token, call_id) -> Any
BaseTool[ArgsT, ReturnT]:泛型基类,强类型FunctionTool:从普通 Python 函数自动推断 schema(用Annotated[..., "doc"]提供描述)Workbench:动态工具集合,可热加 / 热卸StaticWorkbench:不可变工具集合
2.8 Memory 与 ModelContext
Memory(memory/_base_memory.py:60-133):
class Memory(ABC, ComponentBase):
async def update_context(model_context) -> UpdateContextResult
async def query(query, **kw) -> MemoryQueryResult
async def add(content) -> None
async def clear() -> None
ChatCompletionContext(model_context/):管理 LLM 历史窗口,4 种实现:
UnboundedChatCompletionContext—— 全量BufferedChatCompletionContext—— 滑动窗口(条数)TokenLimitedChatCompletionContext—— 滑动窗口(Token 数)HeadAndTailChatCompletionContext—— 保留首 N + 末 M 条
2.9 CodeExecutor 协议
class CodeExecutor(ABC, ComponentBase):
async def execute_code_blocks(blocks: List[CodeBlock], cancellation_token) -> CodeResult
async def start() / stop() / restart()
具体实现见 autogen-ext:local / docker / docker_jupyter / jupyter / azure。
2.10 OpenTelemetry 遥测
_telemetry/:
_tracing.py——TraceHelper在每次 send/publish/instantiate/tool 调用包一层 span_propagation.py——EnvelopeMetadata携带 trace context,跨 asyncio 边界自动传播_genai.py—— GenAI 标准属性(gen_ai.system、gen_ai.request.model等)- 关闭:
AUTOGEN_DISABLE_RUNTIME_TRACING=true
三、autogen-agentchat:高层 Agent / Team 编排
路径:
python/packages/autogen-agentchat/src/autogen_agentchat/
这一层把 Core 的"原始消息总线"包装成对话式多 Agent 编程模型,是绝大多数业务代码直接使用的层。
3.1 消息体系:Chat vs Event(messages.py)
AutoGen 显式区分两种消息:
BaseChatMessage(行 68-140):Agent 之间真正的对话消息,会进入团队历史、被其他 Agent 看到、参与 LLM 调用。BaseAgentEvent(行 142-172):仅给应用层观测用——工具调用、代码执行、流式 chunk、思维链等,不会被其他 Agent 当作输入。
| 分类 | 主要类 | 用途 |
|---|---|---|
| Chat | TextMessage | 纯文本 |
| Chat | MultiModalMessage | 文本 + Image 列表 |
| Chat | HandoffMessage | Agent 之间交接(带可选上下文) |
| Chat | ToolCallSummaryMessage | 工具结果聚合摘要 |
| Chat | StopMessage | 终止信号 |
| Chat | StructuredMessage[T] | Pydantic 类型化输出 |
| Event | ToolCallRequestEvent | LLM 发起工具调用 |
| Event | ToolCallExecutionEvent | 工具执行结果 |
| Event | CodeGenerationEvent / CodeExecutionEvent | 代码生成与执行 |
| Event | ModelClientStreamingChunkEvent | 流式 token |
| Event | ThoughtEvent | 推理(如 o1 reasoning) |
| Event | MemoryQueryEvent | 内存检索 |
| Event | SelectSpeakerEvent / SelectorEvent | 选择下一发言者 |
| Event | UserInputRequestedEvent | 请求人类输入 |
3.2 核心协议
ChatAgent(base/_chat_agent.py)
class ChatAgent(Protocol):
name: str
description: str
produced_message_types: Sequence[type[BaseChatMessage]]
async def on_messages(messages, token) -> Response
def on_messages_stream(messages, token) -> AsyncGenerator[Event | Message | Response]
async def on_reset / on_pause / on_resume
async def save_state / load_state
Response = chat_message + inner_messages(公开消息 + 内部事件)。
TaskRunner / Team / TerminationCondition
TaskRunner.run(task)/run_stream(task)返回TaskResult(messages, stop_reason)。Team:多 Agent 编排器。TerminationCondition:可组合,a | b(任一满足)、a & b(全部满足)、状态机式调用。
cond = MaxMessageTermination(20) | TextMentionTermination("DONE")
cond = cond & TokenUsageTermination(max_total_token=100_000)
3.3 AssistantAgent 全流程剖析
agents/_assistant_agent.py
AssistantAgent 是 AgentChat 的灵魂,几乎所有用户的第一个 Agent 就是它。on_messages_stream(行 901-1011)的核心 6 步:
- 写历史:把传入消息追加到
model_context,遇到HandoffMessage解包出携带的上下文。 - 检索内存:调用
memory.update_context(model_context),发出MemoryQueryEvent。 - 生成流 ID:UUID 用于关联流式 chunk。
- 调用 LLM:
_call_llm()→model_client.create_stream():- 边收 chunk 边 yield
ModelClientStreamingChunkEvent - 若有 reasoning,发
ThoughtEvent
- 边收 chunk 边 yield
- 处理结果(
_process_model_result,行 1118 起):- 工具循环:最多
max_tool_iterations轮(>1 时支持链式工具调用),用asyncio.gather并发执行 - 每轮发
ToolCallRequestEvent+ToolCallExecutionEvent - Handoff:检测到
Handoff.handoff_tool调用 → 切换 Agent - 反思(reflect_on_tool_use):默认在工具调用后再走一次 LLM 输出最终答案;若设了
output_content_type则强制开启
- 工具循环:最多
- 返回:
TextMessage/StructuredMessage/ToolCallSummaryMessage/HandoffMessage之一
关键参数(直接决定行为差异):
AssistantAgent(
name="assistant",
model_client=client,
tools=[func1, FunctionTool(...)], # 自动包装
handoffs=["specialist_agent"], # 自动生成 transfer_to_xxx 工具
workbench=mcp_workbench, # 与 tools 互斥;优先 workbench
model_context=BufferedChatCompletionContext(buffer_size=20),
memory=[chromadb_memory, mem0_memory],
system_message="...",
reflect_on_tool_use=True, # 工具结果再过一次 LLM
max_tool_iterations=10, # 多步工具
output_content_type=MyPydanticModel, # 结构化输出
tool_call_summary_format="{tool_name}({arguments}) -> {result}",
model_client_stream=True,
)
3.4 其他内置 Agent
| Agent | 文件 | 用途 |
|---|---|---|
UserProxyAgent | _user_proxy_agent.py | Human-in-the-loop,发 UserInputRequestedEvent,调用 input_func(同步/异步) |
CodeExecutorAgent | _code_executor_agent.py | 抽取消息中的代码块执行,支持 approval_func 把关、CodeGenerationEvent 发布 |
SocietyOfMindAgent | _society_of_mind_agent.py | 把一个 Team 包装成单 Agent——支持任意层级嵌套(团队套团队) |
MessageFilterAgent | _message_filter_agent.py | 按 source/position/count 过滤上游消息再传给被包装的 Agent,配合图编排用 |
3.5 Group Chat 内部实现
teams/_group_chat/
3.5.1 BaseGroupChat(_base_group_chat.py:66-176)
无论哪种 Team,都在内部建一个 SingleThreadedAgentRuntime + 4 类 Topic:
| Topic 类型 | 用途 |
|---|---|
group_topic_{team_id} | 广播频道:所有参与者 + Manager 都订阅 |
{participant_name}_{team_id} | 单播参与者 |
{manager_name}_{team_id} | 单播 Manager |
output_topic_{team_id} | 流式输出给上层调用方 |
每个参与 Agent 被 ChatAgentContainer 包一层,Manager 是 BaseGroupChatManager 的子类。
3.5.2 BaseGroupChatManager 状态机(_base_group_chat_manager.py:25-201)
async def handle_start(message: GroupChatStart):
# 1. 校验起始消息(如 Swarm 校验 HandoffMessage 目标)
# 2. 把消息广播到 group_topic
# 3. 检查终止条件
# 4. 选下一发言者并请求其发言
async def handle_agent_response(message: GroupChatAgentResponse | GroupChatTeamResponse):
# 1. 把响应消息追加到 thread
# 2. _active_speakers 计数 -1
# 3. 终止条件检查
# 4. 全部讲完 -> 选下一组发言者
async def select_speaker(thread) -> List[str] | str: # 抽象方法
...
# 唤起下一组 speaker
async def _transition_to_next_speakers(token):
names = await self.select_speaker(self._message_thread)
for name in names:
await self.publish_message(
GroupChatRequestPublish(),
topic_id=DefaultTopicId(type=speaker_topic_type),
)
self._active_speakers.append(name)
3.5.3 四种内置 Manager
① RoundRobinGroupChatManager(_round_robin_group_chat.py:16-83)—— 循环
async def select_speaker(self, thread) -> str:
cur = self._next_speaker_index
self._next_speaker_index = (cur + 1) % len(self._participant_names)
return self._participant_names[cur]
② SelectorGroupChatManager(_selector_group_chat.py:50-250+)—— LLM 选人
async def select_speaker(self, thread) -> str:
if self._selector_func: # 用户钩子优先
speaker = await self._selector_func(thread)
if speaker: return speaker
candidates = [...] # candidate_func 可过滤
prompt = build_selector_prompt(candidates, descriptions)
answer = await self._model_client.create([SystemMessage(prompt)])
emit SelectorEvent
return parse(answer)
支持:
selector_func:完全旁路 LLM 的同步/异步钩子candidate_func:候选过滤allow_repeated_speaker:是否允许同一个连讲
③ SwarmGroupChatManager(_swarm_group_chat.py:15-98)—— Handoff 驱动
async def select_speaker(self, thread) -> str:
for msg in reversed(thread):
if isinstance(msg, HandoffMessage):
self._current_speaker = msg.target
return msg.target
return self._current_speaker # 没有 handoff 则继续当前发言人
④ MagenticOneOrchestrator(_magentic_one_orchestrator.py)—— 任务/进度账本
维护 task / facts / plan / n_rounds / n_stalls 状态,Ledger 模式:
- Task Ledger:开局制定计划、收集事实
- Progress Ledger:每轮自评进度
- 卡住 N 轮则重新规划
3.5.4 GraphFlow / DiGraph(实验)
DAG / 图状编排:
DiGraph(
nodes={
"A": DiGraphNode(name="A", edges=[DiGraphEdge(target="B", condition="exit")]),
"B": DiGraphNode(name="B", edges=[DiGraphEdge(target="C")]),
},
default_start_node="A"
)
- 条件边:字符串子串匹配 / Callable / None
- 激活组:
all或any依赖 - 支持环(feedback loop)
3.6 终止条件全集
| 条件 | 语义 |
|---|---|
StopMessageTermination | 出现 StopMessage 类型消息 |
MaxMessageTermination(n) | 消息数 ≥ n |
TextMentionTermination("DONE") | 子串出现在 to_text() |
TokenUsageTermination(max_total_token=...) | 累计 token 超限 |
HandoffTermination(target=...) | 末条是指向目标的 HandoffMessage |
SourceMatchTermination(sources=[...]) | 末条来自指定 Agent |
FunctionalTermination(fn) | 自定义谓词 |
3.7 状态持久化(state/_states.py)
每类 Agent / Manager / Container 都有自己的 *State(Pydantic Model):
state = await team.save_state() # 包含全部参与者 + Manager 状态
# ...持久化到 DB...
await team.load_state(state) # 恢复对话现场
3.8 Tool 化复用:AgentTool / TeamTool
math_tool = AgentTool(math_agent, return_value_as_last_message=True)
team_tool = TeamTool(research_team)
dispatcher = AssistantAgent(
"dispatcher",
model_client=client,
tools=[math_tool, team_tool], # 把整个 Agent / Team 当工具
)
⚠️ 注意:父 Agent 的 model_client 应禁用 parallel tool calls,防止状态冲突。
3.9 Console UI(ui/_console.py)
唯一开箱即用的展示器——把 agent.run_stream() / team.run_stream() 的事件流渲染到终端,支持:
- 实时 token 流
- iTerm2 内联图片
output_stats=True累计RequestUsageUserInputManager处理UserInputRequestedEvent
四、autogen-ext:模型、工具、执行器、内存生态
路径:
python/packages/autogen-ext/src/autogen_ext/
4.1 模型客户端(models/)
| 子目录 | 关键类 |
|---|---|
openai/ | OpenAIChatCompletionClient / AzureOpenAIChatCompletionClient |
anthropic/ | AnthropicChatCompletionClient |
azure/ | AzureAIChatCompletionClient(Azure AI Foundry / GitHub Models) |
ollama/ | OllamaChatCompletionClient |
llama_cpp/ | LlamaCppChatCompletionClient |
replay/ | ReplayChatCompletionClient(测试用,回放固定响应) |
semantic_kernel/ | SK Connector |
cache/ | ChatCompletionCache 装饰器 |
OpenAIChatCompletionClient 关键点(openai/_openai_client.py)
create_stream(行 816):根据json_output是否为 Pydantic 类决定走 beta 客户端- 工具映射(行 735-773):
if choice.message.tool_calls:
content = []
for tc in choice.message.tool_calls:
content.append(FunctionCall(
id=tc.id,
name=normalize_name(tc.function.name),
arguments=tc.function.arguments,
))
finish_reason = "tool_calls"
- Token 计数(
count_tokens_openai,行 308):用模型对应 tokenizer,叠加工具 schema 开销 - 结构化输出:
json_output=True→response_format={"type":"json_object"}json_output=PydanticModel→ 走 betaparseAPI(要求model_info["structured_output"]=True)
ChatCompletionCache(models/cache/_chat_completion_cache.py:29)
装饰器模式包任意 client:
client = OpenAIChatCompletionClient(model="gpt-4o")
cache = RedisStore(...) # 或 DiskCacheStore
cached_client = ChatCompletionCache(client, cache)
- 缓存 key = hash(messages + tools + params)
- 命中时
usage = 0(不计费) - 流式调用同样支持
4.2 工具(tools/)
MCP(Model Context Protocol)—— 一等公民
StdioServerParams(command="npx", args=["@playwright/mcp@latest", "--headless"])
SseServerParams(url="https://...", headers={...})
StreamableHttpServerParams(url="...", sse_read_timeout=...)
async with McpWorkbench(server_params) as wb:
agent = AssistantAgent("a", model_client=client, workbench=wb)
McpWorkbench.call_tool(mcp/_workbench.py:314-353)的转换:
result = await self._actor.call("call_tool", {"name": original_name, "kargs": arguments})
for content in result.content:
if isinstance(content, TextContent):
result_parts.append(TextResultContent(content=content.text))
elif isinstance(content, ImageContent):
result_parts.append(ImageResultContent(content=Image.from_base64(content.data)))
把 MCP 的 TextContent / ImageContent / EmbeddedResource 反向映射为 AutoGen ToolResult。
其他工具
| 工具 | 文件 | 用途 |
|---|---|---|
HttpTool | http/_http_tool.py:64 | 把 HTTP API 包装成工具,支持 path 参数模板 |
PythonCodeExecutionTool | code_execution/_code_execution.py:28 | 让 LLM 直接调用代码执行器 |
LangChainToolAdapter | langchain/ | 复用 LangChain 工具生态 |
KernelFunctionFromTool | semantic_kernel/ | SK 函数互转 |
GraphragLocalSearchTool | graphrag/ | GraphRAG 检索 |
4.3 代码执行器(code_executors/)
| 执行器 | 隔离级别 | 适用场景 |
|---|---|---|
LocalCommandLineCodeExecutor | 无(直接 subprocess) | 开发/可信脚本 |
DockerCommandLineCodeExecutor | 容器隔离 | 生产首选 |
DockerJupyterCodeExecutor | 容器 + Jupyter kernel | 长会话、保留变量 |
JupyterCodeExecutor | 本地 kernel | 数据分析 |
ACADynamicSessionsCodeExecutor | Azure Container Apps | 云原生隔离 |
DockerCommandLineCodeExecutor(docker/_docker_code_executor.py:85):
executor = DockerCommandLineCodeExecutor(
image="python:3-slim",
work_dir="/workspace",
timeout=120,
auto_remove=True,
extra_volumes={"/host/data": {"bind": "/data", "mode": "ro"}},
extra_hosts={"api.internal": "10.0.0.1"},
device_requests=[...], # GPU
)
每次 execute_code_blocks:写文件 → docker exec → 收集 stdout/stderr → 返回 CommandLineCodeResult(exit_code, output)。
4.4 内置 Agent 扩展
| Agent | 用途 |
|---|---|
FileSurfer(agents/file_surfer/) | 本地文件浏览,markdown 预览,工具:open / page_up/down / find |
MultimodalWebSurfer(agents/web_surfer/) | Playwright 浏览器,Set-of-Mark 截图标记后让多模态模型点击 |
VideoSurfer | 视频抽帧 + 字幕检索 |
OpenAIAgent(agents/openai/) | 直接对接 OpenAI Assistants API |
4.5 内存(memory/)
| 实现 | 文件 |
|---|---|
ChromaDBVectorMemory | chromadb/_chromadb.py:35(支持 Persistent / Http) |
Mem0Memory | mem0/_mem0.py:47(Mem0.ai 云 + 自建) |
RedisMemory | redis/ |
TextCanvasMemory | canvas/_text_canvas.py(多 Agent 共享黑板) |
ChromaDB 嵌入函数可选:Default / OpenAIEmbedding / SentenceTransformer。
4.6 缓存存储(cache_store/)
RedisStore(redis.py:25):value 自动 Pydantic JSON 序列化DiskCacheStore(diskcache.py:18):本地文件缓存
4.7 Auth
auth/azure/:AzureTokenProvider 包装 DefaultAzureCredential 输出 Bearer Token,供 Azure 类客户端使用。
五、分布式运行时:gRPC + .NET / Python 跨语言
5.1 Protobuf 契约
路径:
autogen/protos/
agent_worker.proto 关键服务
service AgentRpc {
rpc OpenChannel(stream Message) returns (stream Message); // 双向流,业务消息
rpc OpenControlChannel(stream ControlMessage) returns (stream ControlMessage);
rpc RegisterAgent(RegisterAgentTypeRequest) returns (RegisterAgentTypeResponse);
rpc AddSubscription(AddSubscriptionRequest) returns (AddSubscriptionResponse);
rpc RemoveSubscription(...) returns (...);
rpc GetSubscriptions(...) returns (...);
}
message Message {
oneof message {
RpcRequest request = 1;
RpcResponse response = 2;
io.cloudevents.v1.CloudEvent cloudEvent = 3; // 用于 publish
}
}
message Payload {
string data_type = 1; // "MyMessage",类型字符串
string data_content_type = 2; // "application/json" / protobuf
bytes data = 3;
}
message AgentId {
string type = 1;
string key = 2;
}
CloudEvent (cloudevent.proto) 用于 pub/sub 事件:必备 id / source / spec_version / type,扩展属性塞 sender 信息和 data schema。
5.2 Python 端:GrpcWorkerAgentRuntime
autogen-ext/src/autogen_ext/runtimes/grpc/_worker_runtime.py
runtime = GrpcWorkerAgentRuntime(host_address="localhost:50051")
await runtime.start()
await MyAgent.register(runtime, "my_agent", lambda: MyAgent())
启动后 _run_read_loop(行 279-306)核心:
async def _run_read_loop(self):
while self._running:
msg = await self._host_connection.recv()
match msg.WhichOneof("message"):
case "request":
asyncio.create_task(self._process_request(msg.request))
case "response":
asyncio.create_task(self._process_response(msg.response))
case "cloudEvent":
asyncio.create_task(self._process_event(msg.cloudEvent))
发送(行 366-411):构造 RpcRequest(request_id, target, source, payload) → 发到 host → _pending_requests[request_id] Future 等响应。
发布(行 413-490):包成 CloudEvent,sender / schema 塞 attributes。
5.3 Python 端:Host
_worker_runtime_host.py+_worker_runtime_host_servicer.py
host = GrpcWorkerAgentRuntimeHost(address="0.0.0.0:50051")
await host.start()
核心路由(_worker_runtime_host_servicer.py:185-286):
async def _process_request(self, request, src_client):
target_client = self._agent_type_to_client_id[request.target.type]
await self._data_connections[target_client].send(Message(request=request))
fut = create_future()
self._pending_responses[target_client][request.request_id] = fut
asyncio.create_task(self._wait_and_send_response(fut, src_client))
async def _process_event(self, cloud_event):
topic = TopicId(type=cloud_event.type, source=cloud_event.source)
recipients = await self._subscription_manager.get_subscribed_recipients(topic)
for client in client_ids_for(recipients):
await self._data_connections[client].send(Message(cloudEvent=cloud_event))
Host 是纯路由器,自身不持有 Agent 状态。
5.4 .NET 端
| 项目 | 关键类型 | 角色 |
|---|---|---|
Microsoft.AutoGen.Contracts | IAgentRuntime、IAgent、AgentId、MessageContext | 共享接口 |
Microsoft.AutoGen.Core | InProcessRuntime、BaseAgent、HandlerInvoker | 进程内运行时 + 反射式 IHandle<TMessage> 路由 |
Microsoft.AutoGen.Core.Grpc | GrpcAgentRuntime、GrpcMessageRouter、AutoRestartChannel | Worker 端 |
Microsoft.AutoGen.RuntimeGateway.Grpc | GrpcGatewayService、GrpcWorkerConnection、GrpcGateway | Host/Gateway |
Microsoft.AutoGen.AgentHost | Host.StartAsync() | 启动入口(WebApplication + 服务默认配置) |
GrpcMessageRouter(Core.Grpc/GrpcMessageRouter.cs:101-299)双 pump 设计:
RunReadPump把入站消息派发给_incomingMessageSink.OnMessageAsync()RunWritePump排空出站 channel,写到 gRPC streamAutoRestartChannel(行 17-99)持久化双向流,断线自动重连
5.5 跨语言互操作
- 共享 .proto —— Python / .NET 各自生成 stub
- 类型名作 Schema ——
Payload.data_type字符串映射 - JSON / Protobuf 二选一 —— 推荐 protobuf,强模式
- CloudEvent attributes —— 跨语言 pub/sub 通用元数据
只要双方 SerializationRegistry 注册同名 Pydantic / C# class(或同 .proto 类型),.NET 与 Python Agent 就能互相 send_message、收到对方 publish_message。
六、AutoGen Studio:低代码可视化平台
路径:
python/packages/autogen-studio/
6.1 总体架构
- 后端 FastAPI(
autogenstudio/web/app.py:60-190)- 异步 HTTP + WebSocket
- 路由:
/sessions、/runs、/teams、/ws、/validate、/gallery、/settings、/auth、/mcp
- 数据层(
datamodel/+database/)- SQLAlchemy + Alembic 迁移
- 持久化 Run / Team / Session / Config
- TeamManager(
teammanager/teammanager.py:40-77)- 从 JSON/YAML 配置加载团队(直接复用 Component 系统反序列化)
RunEventLogger(行 28-37)把流式事件转给 WebSocket
- GalleryBuilder(
gallery/builder.py:33-60)- 内置一份"组件画廊"——AssistantAgent、UserProxyAgent、OpenAI/Anthropic 客户端、各类执行器、终止条件等
- 前端读它来生成可视化拖拽面板
- WebSocket 路由(
web/routes/ws.py:20-60)/api/ws/runs/{run_id}流式推送 Run 事件
- React 前端(
frontend/src/)- REST 做 CRUD,WebSocket 做实时
6.2 启动
pip install -U autogenstudio
autogenstudio ui --port 8080 --appdir ./my-app
⚠️ Studio 官方明确不是生产应用——缺少认证授权细节、限流、审计。生产请参考它的代码自建。
七、生产应用教程(11 个端到端场景)
所有示例需要:
pip install -U "autogen-agentchat" "autogen-ext[openai,docker,mcp,redis,chromadb]"
教程 1:最小骨架(Hello World)
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
async def main():
client = OpenAIChatCompletionClient(model="gpt-4o")
agent = AssistantAgent("assistant", model_client=client)
print(await agent.run(task="解释什么是 actor 模型,3 句话"))
await client.close()
asyncio.run(main())
教程 2:带工具 + 多步工具循环
from typing import Annotated
from autogen_core.tools import FunctionTool
async def get_weather(
city: Annotated[str, "城市英文名"],
unit: Annotated[str, "celsius 或 fahrenheit"] = "celsius",
) -> str:
return f"{city} sunny 25°{unit[0].upper()}"
agent = AssistantAgent(
"assistant",
model_client=client,
tools=[get_weather], # 自动包成 FunctionTool
max_tool_iterations=10, # 允许 LLM 链式工具调用
reflect_on_tool_use=True, # 工具结果再过一次 LLM 总结
)
教程 3:MCP 服务接入(Playwright 浏览器示例)
from autogen_ext.tools.mcp import McpWorkbench, StdioServerParams
server = StdioServerParams(command="npx", args=["@playwright/mcp@latest", "--headless"])
async with McpWorkbench(server) as wb:
agent = AssistantAgent(
"browser",
model_client=client,
workbench=wb,
max_tool_iterations=15,
model_client_stream=True,
)
await Console(agent.run_stream(task="去 GitHub 查一下 microsoft/autogen 的 star 数"))
⚠️ 安全:仅连接可信 MCP 服务,Playwright/Filesystem 类 MCP 几乎拥有完全的本地能力。
教程 4:结构化输出(Pydantic)
from pydantic import BaseModel
class Diagnosis(BaseModel):
severity: str
root_cause: str
actions: list[str]
agent = AssistantAgent(
"doctor",
model_client=client,
system_message="你是 SRE 专家,诊断报警。",
output_content_type=Diagnosis, # 强制 StructuredMessage[Diagnosis]
)
resp = await agent.run(task="磁盘 IO 持续 95%,DB 写入延迟从 5ms 涨到 800ms")
print(resp.messages[-1].content) # Diagnosis 实例
教程 5:RoundRobin 团队 + 终止条件组合
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
writer = AssistantAgent("writer", model_client=client, system_message="写作者")
critic = AssistantAgent("critic", model_client=client,
system_message="评审者;满意时只回复 APPROVE")
team = RoundRobinGroupChat(
participants=[writer, critic],
termination_condition=MaxMessageTermination(10) | TextMentionTermination("APPROVE"),
)
await Console(team.run_stream(task="写一段关于多 Agent 系统的 200 字介绍"))
教程 6:SelectorGroupChat(动态选择发言者)
from autogen_agentchat.teams import SelectorGroupChat
planner = AssistantAgent("planner", model_client=client, description="任务拆解")
coder = AssistantAgent("coder", model_client=client, description="写 Python")
reviewer = AssistantAgent("reviewer", model_client=client, description="审代码")
def my_selector(thread):
# 第一轮强制 planner,否则交给 LLM
if not thread:
return "planner"
return None
team = SelectorGroupChat(
[planner, coder, reviewer],
model_client=client,
selector_func=my_selector,
allow_repeated_speaker=False,
)
教程 7:Swarm(Handoff 驱动)
from autogen_agentchat.teams import Swarm
from autogen_agentchat.base import Handoff
triage = AssistantAgent(
"triage",
model_client=client,
system_message="判断问题类别,转给 billing 或 tech",
handoffs=["billing", "tech"],
)
billing = AssistantAgent("billing", model_client=client,
system_message="处理账单",
handoffs=[Handoff(target="triage", message="转回三角")])
tech = AssistantAgent("tech", model_client=client, system_message="处理技术问题")
team = Swarm([triage, billing, tech], termination_condition=...)
教程 8:人机协同(HITL)
from autogen_agentchat.agents import UserProxyAgent
async def ask_user(prompt: str, ct) -> str:
return input(f"{prompt}\n> ")
user = UserProxyAgent("user", input_func=ask_user)
team = RoundRobinGroupChat([assistant, user], termination_condition=...)
UI 层若需异步输入(Web/移动端),把 input_func 实现成 await queue.get(),前端通过 WebSocket 把用户回答 push 进 queue。
教程 9:Docker 隔离的代码执行 Agent
from autogen_agentchat.agents import CodeExecutorAgent
from autogen_ext.code_executors.docker import DockerCommandLineCodeExecutor
async with DockerCommandLineCodeExecutor(
image="python:3.11-slim",
timeout=60,
work_dir="/workspace",
auto_remove=True,
) as executor:
coder = CodeExecutorAgent("coder", code_executor=executor, model_client=client)
await Console(coder.run_stream(task="算一下 2024 年的复利,10000 元年利率 5% 30 年"))
教程 10:内存 + 缓存 + 流式
from autogen_ext.memory.chromadb import ChromaDBVectorMemory, PersistentChromaDBVectorMemoryConfig
from autogen_ext.models.cache import ChatCompletionCache
from autogen_ext.cache_store.redis import RedisStore
import redis
memory = ChromaDBVectorMemory(config=PersistentChromaDBVectorMemoryConfig(
collection_name="kb", persistence_path="./chroma"
))
await memory.add(MemoryContent(content="公司报销限额:差旅 ≤ 5000 元/月", mime_type="text/plain"))
raw_client = OpenAIChatCompletionClient(model="gpt-4o")
cache_store = RedisStore(redis.Redis(host="localhost", port=6379))
client = ChatCompletionCache(raw_client, cache_store)
agent = AssistantAgent(
"hr",
model_client=client,
memory=[memory],
model_client_stream=True,
model_context=BufferedChatCompletionContext(buffer_size=20),
)
教程 11:状态保存 / 恢复(多会话续聊)
# 第一次会话
team = RoundRobinGroupChat([...], termination_condition=...)
await team.run(task="...")
state = await team.save_state()
json.dump(state, open("session.json", "w"))
# 第二次进程:完全重建相同的 team 配置
team2 = RoundRobinGroupChat([...], termination_condition=...)
await team2.load_state(json.load(open("session.json")))
await team2.run(task="继续上次") # 历史完整恢复
教程 12(额外):分布式 Agent
启动 host:
# host.py
import asyncio
from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntimeHost
async def main():
host = GrpcWorkerAgentRuntimeHost(address="0.0.0.0:50051")
await host.start()
await host.stop_when_signal()
asyncio.run(main())
启动 worker:
# worker.py
import asyncio
from autogen_core import AgentId, RoutedAgent, message_handler, MessageContext
from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntime
from dataclasses import dataclass
@dataclass
class Ping: text: str
@dataclass
class Pong: text: str
class Server(RoutedAgent):
@message_handler
async def on_ping(self, msg: Ping, ctx: MessageContext) -> Pong:
return Pong(text=f"echo:{msg.text}")
async def main():
rt = GrpcWorkerAgentRuntime(host_address="localhost:50051")
rt.add_message_serializer([PydanticJsonMessageSerializer(Ping),
PydanticJsonMessageSerializer(Pong)])
await rt.start()
await Server.register(rt, "server", lambda: Server("server"))
# 在另一个 worker 进程:
# pong = await rt.send_message(Ping("hi"), AgentId("server", "default"))
await rt.stop_when_signal()
asyncio.run(main())
八、生产落地清单
8.1 性能
| 项 | 建议 |
|---|---|
| 模型上下文 | 用 BufferedChatCompletionContext / TokenLimitedChatCompletionContext 限窗,绝不默认 unbounded |
| 流式响应 | 设 model_client_stream=True 并通过 WebSocket 推前端,避免长时间空白 |
| 并发工具 | max_tool_iterations>1 时框架已 asyncio.gather,但每个工具内部需是协程 |
| 缓存 | LLM 调用必加 ChatCompletionCache,至少省 30% 成本 |
| 分布式 | 单 host 是路由瓶颈,按业务域拆多 host;同语言内首选 InProcess + asyncio |
8.2 安全
- 严禁用
LocalCommandLineCodeExecutor跑用户代码,至少用 Docker 执行器 - MCP / HTTP 工具按白名单接入;HttpTool 一定加 timeout 与限速
- 自定义
InterventionHandler做 PII 脱敏、prompt injection 检查 AUTOGEN_ALLOWED_PROVIDER_NAMESPACES显式限定可加载组件- AutoGen Studio 仅用于内部原型,不要直接对外网开放
8.3 可观测
- 启用 OpenTelemetry:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import BatchSpanProcessor
provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel:4317")))
trace.set_tracer_provider(provider)
每条消息、每次工具调用、每次 LLM 调用都会自动出现在 Jaeger / Tempo / Honeycomb。
ToolCallExecutionEvent/ToolCallRequestEvent推 ELK,做工具调用审计RequestUsage累计写时序库(Prometheus / VictoriaMetrics)做成本看板
8.4 成本
- 路由层:先用便宜模型(haiku / mini)做意图判断,再交给贵模型
SelectorGroupChat.selector_func写规则路由优先于 LLM 选人- 复用
AgentTool/TeamTool,避免重复维护多份 Prompt - 结构化输出 + Pydantic 验证可减少多轮"格式纠错"开销
8.5 失败兜底
- 终止条件必须带
MaxMessageTermination与TokenUsageTermination兜底 - 工具内部
try/except后返回明确错误字符串(让 LLM 看得懂) CancellationToken配合超时 task:asyncio.wait_for(team.run(task), timeout=300)- 用
save_state周期性 checkpoint,崩溃后能恢复
8.6 部署形态推荐
| 规模 | 形态 |
|---|---|
| 单进程小项目 | SingleThreadedAgentRuntime(Core)或直接用 AgentChat 高阶 API |
| 多业务线 | 每业务一个 FastAPI/容器,AgentChat in-process |
| 大规模、跨语言、多团队 | gRPC 分布式:1 个 host + N 个 Python/.NET worker |
| 流式 SaaS | FastAPI + WebSocket + Redis pub/sub + 状态持久化到 Postgres |
九、关键源码文件速查表
autogen-core
| 模块 | 关键文件 | 行号 |
|---|---|---|
| Agent 协议 | _agent.py | 12-64 |
| AgentId | _agent_id.py | 12-69 |
| BaseAgent | _base_agent.py | 60-255 |
| RoutedAgent 路由 | _routed_agent.py | 474-491 |
| 装饰器 @message_handler/@event/@rpc | _routed_agent.py | 85-412 |
| ClosureAgent | _closure_agent.py | 76-242 |
| 单机运行时主循环 | _single_threaded_agent_runtime.py | 671-753 |
| 三种 Envelope | _single_threaded_agent_runtime.py | 57-93 |
| 懒加载实例化 | _single_threaded_agent_runtime.py | 466-512 |
| TopicId | _topic.py | 11-48 |
| Subscription 协议 | _subscription.py | 10-65 |
| TypeSubscription | _type_subscription.py | 10-67 |
| TypePrefixSubscription | _type_prefix_subscription.py | 10-70 |
| MessageContext | _message_context.py | 8-14 |
| Serialization | _serialization.py | 14-150 |
| Component 系统 | _component_config.py | 18-156 |
| Tool 协议 | tools/_base.py | 56-81 |
| FunctionTool | tools/_function_tool.py | 30-100 |
| ChatCompletionClient / ModelFamily | models/_model_client.py | 16-153 |
| LLMMessage 四件套 | models/_types.py | 10-81 |
| CreateResult | models/_types.py | 107-128 |
| Memory 协议 | memory/_base_memory.py | 60-133 |
| ChatCompletionContext | model_context/_chat_completion_context.py | 10-75 |
| CodeExecutor 协议 | code_executor/_base.py | 34-103 |
autogen-agentchat
| 模块 | 关键文件 | 行号 |
|---|---|---|
| Messages 全集 | messages.py | 1-694 |
| AssistantAgent.on_messages_stream | agents/_assistant_agent.py | 901-1011 |
| AssistantAgent._process_model_result | agents/_assistant_agent.py | 1118-1350+ |
| BaseGroupChat | teams/_group_chat/_base_group_chat.py | 66-176 |
| BaseGroupChatManager | teams/_group_chat/_base_group_chat_manager.py | 25-201 |
| RoundRobin | teams/_group_chat/_round_robin_group_chat.py | 16-83 |
| Selector | teams/_group_chat/_selector_group_chat.py | 50-250+ |
| Swarm | teams/_group_chat/_swarm_group_chat.py | 15-98 |
| Termination 基类 | base/_termination.py | 15-86 |
| ChatAgent 协议 | base/_chat_agent.py | 24-95 |
| TaskRunner 协议 | base/_task.py | 19-65 |
| Console UI | ui/_console.py | 82-150+ |
autogen-ext
| 模块 | 关键文件 | 行号 |
|---|---|---|
| OpenAI client | models/openai/_openai_client.py | 1179 |
| OpenAI streaming | 同上 | 816 |
| OpenAI tool 转换 | 同上 | 735-773 |
| count_tokens | 同上 | 308 |
| ChatCompletionCache | models/cache/_chat_completion_cache.py | 29 |
| AzureAI client | models/azure/_azure_ai_client.py | 181 |
| McpWorkbench | tools/mcp/_workbench.py | 47, 314-353 |
| MCP Server params | tools/mcp/_config.py | 9-28 |
| HttpTool | tools/http/_http_tool.py | 64 |
| PythonCodeExecutionTool | tools/code_execution/_code_execution.py | 28 |
| Local executor | code_executors/local/__init__.py | 45 |
| Docker executor | code_executors/docker/_docker_code_executor.py | 85, 405-419 |
| FileSurfer | agents/file_surfer/_file_surfer.py | 44 |
| WebSurfer | agents/web_surfer/_multimodal_web_surfer.py | 72 |
| MagenticOne team | teams/magentic_one.py | 22 |
| ChromaDB memory | memory/chromadb/_chromadb.py | 35 |
| Mem0 memory | memory/mem0/_mem0.py | 47 |
| RedisStore | cache_store/redis.py | 25 |
| DiskCacheStore | cache_store/diskcache.py | 18 |
| Azure auth | auth/azure/__init__.py | 16 |
分布式
| 模块 | 关键文件 | 行号 |
|---|---|---|
| AgentRpc 服务定义 | protos/agent_worker.proto | 127-134 |
| Message envelope | protos/agent_worker.proto | 82-88 |
| Payload | protos/agent_worker.proto | 16-20 |
| AgentId | protos/agent_worker.proto | 11-14 |
| CloudEvent | protos/cloudevent.proto | 21-58 |
| GrpcWorkerAgentRuntime | autogen_ext/runtimes/grpc/_worker_runtime.py | 215 |
| 主消息循环 | 同上 | 279-306 |
| send_message | 同上 | 366-411 |
| publish_message | 同上 | 413-490 |
| Host | _worker_runtime_host.py | 19 |
| Host servicer 路由 | _worker_runtime_host_servicer.py | 185-286 |
| .NET IAgentRuntime | dotnet/.../Contracts/IAgentRuntime.cs | 11-125 |
| .NET BaseAgent | dotnet/.../Core/BaseAgent.cs | 15-100 |
| .NET GrpcAgentRuntime | dotnet/.../Core.Grpc/GrpcAgentRuntime.cs | 88-289 |
| .NET GrpcMessageRouter | dotnet/.../Core.Grpc/GrpcMessageRouter.cs | 101-299 |
| .NET Gateway | dotnet/.../RuntimeGateway.Grpc/Services/Grpc/GrpcGatewayService.cs | 11-109 |
| .NET AgentHost | dotnet/.../AgentHost/Host.cs | 9-23 |
autogen-studio
| 模块 | 关键文件 | 行号 |
|---|---|---|
| FastAPI app | autogenstudio/web/app.py | 60-190 |
| TeamManager | autogenstudio/teammanager/teammanager.py | 40-77 |
| GalleryBuilder | autogenstudio/gallery/builder.py | 33-60 |
| WebSocket 路由 | autogenstudio/web/routes/ws.py | 20-60 |
十、结语
AutoGen 把"多 Agent 系统"抽象成 Actor + Pub/Sub + Component DSL 三件套:
- Actor:每个 Agent 是带状态的协程,懒加载实例化,按
AgentId寻址。 - Pub/Sub:基于
TopicId解耦,订阅可按类型 / 类型前缀 / 默认匹配。 - Component DSL:所有可装配项都能 dump 成 JSON/YAML,Studio 与代码可互相导出。
在此之上:
- AgentChat 提供"开箱即用"的 4 种团队模式(Round-robin / Selector / Swarm / Magentic-One)+ 可组合的终止条件;
- Extensions 让 OpenAI / Anthropic / Azure / MCP / Docker / ChromaDB 即插即用;
- gRPC + .NET 把同样的协议带到了多语言、跨进程、跨主机;
- Studio 提供低代码原型;
虽然项目已转入维护模式(继任者是 Microsoft Agent Framework),但其架构与代码组织仍是迄今为止理解多 Agent 系统设计的最佳教材之一——强烈建议把 autogen-core 当成"Actor 模型 + 消息总线"的标准实现来精读。