Microsoft AutoGen 源码深度剖析与生产应用教程

1 阅读25分钟

基于仓库 microsoft/autogen 主干代码(v0.4+ 架构分支,已进入维护模式但仍是最完整的多 Agent 框架参考实现之一)。

本文从最底层的 autogen-core 运行时 一路向上拆到 autogen-agentchat 团队编排autogen-ext 扩展生态.NET / 跨语言分布式运行时AutoGen Studio,并附带生产落地教程。


目录

  1. 项目全景与分层架构
  2. autogen-core:事件驱动 Agent 运行时
  3. autogen-agentchat:高层 Agent / Team 编排
  4. autogen-ext:模型、工具、执行器、内存生态
  5. 分布式运行时:gRPC + .NET / Python 跨语言
  6. AutoGen Studio:低代码可视化平台
  7. 生产应用教程(11 个端到端场景)
  8. 生产落地清单(性能、安全、可观测、成本)
  9. 关键源码文件速查表

一、项目全景与分层架构

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 的关键架构决策是分层 + 可扩展,每层职责清晰且建立在下层之上:

层级包名关注点适用人群
Coreautogen-coreActor 模型、消息路由、Pub/Sub、跨语言协议框架开发者、需要细粒度控制的高级用户
AgentChatautogen-agentchat对话式 Agent、团队编排、终止条件应用开发者(90% 用户在此层)
Extensionsautogen-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 注入 idruntime,让 __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() 静态提取,没有运行时类型字符串
  • @eventis_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_messagepublish_message
目标指定 AgentId匹配 TopicId 的所有订阅者
是否等待响应是(返回 awaitable
ctx.is_rpcTrueFalse
拦截器on_sendon_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_publishasyncio.gather 并发投递。

2.4 消息原语

类型文件字段
MessageContext_message_context.py:8-14sender, topic_id, is_rpc, cancellation_token, message_id
FunctionCall_types.py:6-12id, name, arguments(JSON str)
SystemMessage / UserMessage / AssistantMessage / FunctionExecutionResultMessagemodels/_types.py:10-81LLM 消息四件套
CreateResultmodels/_types.py:107-128finish_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 → JSON
  • PydanticJsonMessageSerializer:支持嵌套/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

Memorymemory/_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

ChatCompletionContextmodel_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.systemgen_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 当作输入。
分类主要类用途
ChatTextMessage纯文本
ChatMultiModalMessage文本 + Image 列表
ChatHandoffMessageAgent 之间交接(带可选上下文)
ChatToolCallSummaryMessage工具结果聚合摘要
ChatStopMessage终止信号
ChatStructuredMessage[T]Pydantic 类型化输出
EventToolCallRequestEventLLM 发起工具调用
EventToolCallExecutionEvent工具执行结果
EventCodeGenerationEvent / CodeExecutionEvent代码生成与执行
EventModelClientStreamingChunkEvent流式 token
EventThoughtEvent推理(如 o1 reasoning)
EventMemoryQueryEvent内存检索
EventSelectSpeakerEvent / SelectorEvent选择下一发言者
EventUserInputRequestedEvent请求人类输入

3.2 核心协议

ChatAgentbase/_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

AssistantAgentAgentChat 的灵魂,几乎所有用户的第一个 Agent 就是它。on_messages_stream(行 901-1011)的核心 6 步:

  1. 写历史:把传入消息追加到 model_context,遇到 HandoffMessage 解包出携带的上下文。
  2. 检索内存:调用 memory.update_context(model_context),发出 MemoryQueryEvent
  3. 生成流 ID:UUID 用于关联流式 chunk。
  4. 调用 LLM_call_llm()model_client.create_stream()
    • 边收 chunk 边 yield ModelClientStreamingChunkEvent
    • 若有 reasoning,发 ThoughtEvent
  5. 处理结果_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 则强制开启
  6. 返回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.pyHuman-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.pysource/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
  • 激活组allany 依赖
  • 支持环(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 累计 RequestUsage
  • UserInputManager 处理 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=Trueresponse_format={"type":"json_object"}
    • json_output=PydanticModel → 走 beta parse API(要求 model_info["structured_output"]=True

ChatCompletionCachemodels/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_toolmcp/_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

其他工具

工具文件用途
HttpToolhttp/_http_tool.py:64把 HTTP API 包装成工具,支持 path 参数模板
PythonCodeExecutionToolcode_execution/_code_execution.py:28让 LLM 直接调用代码执行器
LangChainToolAdapterlangchain/复用 LangChain 工具生态
KernelFunctionFromToolsemantic_kernel/SK 函数互转
GraphragLocalSearchToolgraphrag/GraphRAG 检索

4.3 代码执行器(code_executors/

执行器隔离级别适用场景
LocalCommandLineCodeExecutor无(直接 subprocess)开发/可信脚本
DockerCommandLineCodeExecutor容器隔离生产首选
DockerJupyterCodeExecutor容器 + Jupyter kernel长会话、保留变量
JupyterCodeExecutor本地 kernel数据分析
ACADynamicSessionsCodeExecutorAzure Container Apps云原生隔离

DockerCommandLineCodeExecutordocker/_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用途
FileSurferagents/file_surfer/本地文件浏览,markdown 预览,工具:open / page_up/down / find
MultimodalWebSurferagents/web_surfer/Playwright 浏览器,Set-of-Mark 截图标记后让多模态模型点击
VideoSurfer视频抽帧 + 字幕检索
OpenAIAgentagents/openai/直接对接 OpenAI Assistants API

4.5 内存(memory/

实现文件
ChromaDBVectorMemorychromadb/_chromadb.py:35(支持 Persistent / Http)
Mem0Memorymem0/_mem0.py:47(Mem0.ai 云 + 自建)
RedisMemoryredis/
TextCanvasMemorycanvas/_text_canvas.py(多 Agent 共享黑板)

ChromaDB 嵌入函数可选:Default / OpenAIEmbedding / SentenceTransformer

4.6 缓存存储(cache_store/

  • RedisStoreredis.py:25):value 自动 Pydantic JSON 序列化
  • DiskCacheStorediskcache.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.ContractsIAgentRuntimeIAgentAgentIdMessageContext共享接口
Microsoft.AutoGen.CoreInProcessRuntimeBaseAgentHandlerInvoker进程内运行时 + 反射式 IHandle<TMessage> 路由
Microsoft.AutoGen.Core.GrpcGrpcAgentRuntimeGrpcMessageRouterAutoRestartChannelWorker 端
Microsoft.AutoGen.RuntimeGateway.GrpcGrpcGatewayServiceGrpcWorkerConnectionGrpcGatewayHost/Gateway
Microsoft.AutoGen.AgentHostHost.StartAsync()启动入口(WebApplication + 服务默认配置)

GrpcMessageRouterCore.Grpc/GrpcMessageRouter.cs:101-299)双 pump 设计:

  • RunReadPump 把入站消息派发给 _incomingMessageSink.OnMessageAsync()
  • RunWritePump 排空出站 channel,写到 gRPC stream
  • AutoRestartChannel(行 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 总体架构

  • 后端 FastAPIautogenstudio/web/app.py:60-190
    • 异步 HTTP + WebSocket
    • 路由:/sessions/runs/teams/ws/validate/gallery/settings/auth/mcp
  • 数据层datamodel/ + database/
    • SQLAlchemy + Alembic 迁移
    • 持久化 Run / Team / Session / Config
  • TeamManagerteammanager/teammanager.py:40-77
    • 从 JSON/YAML 配置加载团队(直接复用 Component 系统反序列化)
    • RunEventLogger(行 28-37)把流式事件转给 WebSocket
  • GalleryBuildergallery/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 失败兜底

  • 终止条件必须MaxMessageTerminationTokenUsageTermination 兜底
  • 工具内部 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
流式 SaaSFastAPI + WebSocket + Redis pub/sub + 状态持久化到 Postgres

九、关键源码文件速查表

autogen-core

模块关键文件行号
Agent 协议_agent.py12-64
AgentId_agent_id.py12-69
BaseAgent_base_agent.py60-255
RoutedAgent 路由_routed_agent.py474-491
装饰器 @message_handler/@event/@rpc_routed_agent.py85-412
ClosureAgent_closure_agent.py76-242
单机运行时主循环_single_threaded_agent_runtime.py671-753
三种 Envelope_single_threaded_agent_runtime.py57-93
懒加载实例化_single_threaded_agent_runtime.py466-512
TopicId_topic.py11-48
Subscription 协议_subscription.py10-65
TypeSubscription_type_subscription.py10-67
TypePrefixSubscription_type_prefix_subscription.py10-70
MessageContext_message_context.py8-14
Serialization_serialization.py14-150
Component 系统_component_config.py18-156
Tool 协议tools/_base.py56-81
FunctionTooltools/_function_tool.py30-100
ChatCompletionClient / ModelFamilymodels/_model_client.py16-153
LLMMessage 四件套models/_types.py10-81
CreateResultmodels/_types.py107-128
Memory 协议memory/_base_memory.py60-133
ChatCompletionContextmodel_context/_chat_completion_context.py10-75
CodeExecutor 协议code_executor/_base.py34-103

autogen-agentchat

模块关键文件行号
Messages 全集messages.py1-694
AssistantAgent.on_messages_streamagents/_assistant_agent.py901-1011
AssistantAgent._process_model_resultagents/_assistant_agent.py1118-1350+
BaseGroupChatteams/_group_chat/_base_group_chat.py66-176
BaseGroupChatManagerteams/_group_chat/_base_group_chat_manager.py25-201
RoundRobinteams/_group_chat/_round_robin_group_chat.py16-83
Selectorteams/_group_chat/_selector_group_chat.py50-250+
Swarmteams/_group_chat/_swarm_group_chat.py15-98
Termination 基类base/_termination.py15-86
ChatAgent 协议base/_chat_agent.py24-95
TaskRunner 协议base/_task.py19-65
Console UIui/_console.py82-150+

autogen-ext

模块关键文件行号
OpenAI clientmodels/openai/_openai_client.py1179
OpenAI streaming同上816
OpenAI tool 转换同上735-773
count_tokens同上308
ChatCompletionCachemodels/cache/_chat_completion_cache.py29
AzureAI clientmodels/azure/_azure_ai_client.py181
McpWorkbenchtools/mcp/_workbench.py47, 314-353
MCP Server paramstools/mcp/_config.py9-28
HttpTooltools/http/_http_tool.py64
PythonCodeExecutionTooltools/code_execution/_code_execution.py28
Local executorcode_executors/local/__init__.py45
Docker executorcode_executors/docker/_docker_code_executor.py85, 405-419
FileSurferagents/file_surfer/_file_surfer.py44
WebSurferagents/web_surfer/_multimodal_web_surfer.py72
MagenticOne teamteams/magentic_one.py22
ChromaDB memorymemory/chromadb/_chromadb.py35
Mem0 memorymemory/mem0/_mem0.py47
RedisStorecache_store/redis.py25
DiskCacheStorecache_store/diskcache.py18
Azure authauth/azure/__init__.py16

分布式

模块关键文件行号
AgentRpc 服务定义protos/agent_worker.proto127-134
Message envelopeprotos/agent_worker.proto82-88
Payloadprotos/agent_worker.proto16-20
AgentIdprotos/agent_worker.proto11-14
CloudEventprotos/cloudevent.proto21-58
GrpcWorkerAgentRuntimeautogen_ext/runtimes/grpc/_worker_runtime.py215
主消息循环同上279-306
send_message同上366-411
publish_message同上413-490
Host_worker_runtime_host.py19
Host servicer 路由_worker_runtime_host_servicer.py185-286
.NET IAgentRuntimedotnet/.../Contracts/IAgentRuntime.cs11-125
.NET BaseAgentdotnet/.../Core/BaseAgent.cs15-100
.NET GrpcAgentRuntimedotnet/.../Core.Grpc/GrpcAgentRuntime.cs88-289
.NET GrpcMessageRouterdotnet/.../Core.Grpc/GrpcMessageRouter.cs101-299
.NET Gatewaydotnet/.../RuntimeGateway.Grpc/Services/Grpc/GrpcGatewayService.cs11-109
.NET AgentHostdotnet/.../AgentHost/Host.cs9-23

autogen-studio

模块关键文件行号
FastAPI appautogenstudio/web/app.py60-190
TeamManagerautogenstudio/teammanager/teammanager.py40-77
GalleryBuilderautogenstudio/gallery/builder.py33-60
WebSocket 路由autogenstudio/web/routes/ws.py20-60

十、结语

AutoGen 把"多 Agent 系统"抽象成 Actor + Pub/Sub + Component DSL 三件套:

  1. Actor:每个 Agent 是带状态的协程,懒加载实例化,按 AgentId 寻址。
  2. Pub/Sub:基于 TopicId 解耦,订阅可按类型 / 类型前缀 / 默认匹配。
  3. 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 模型 + 消息总线"的标准实现来精读。