惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
C
Check Point Blog
IT之家
IT之家
MyScale Blog
MyScale Blog
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
Last Week in AI
Last Week in AI
GbyAI
GbyAI
P
Proofpoint News Feed
量子位
Stack Overflow Blog
Stack Overflow Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
人人都是产品经理
人人都是产品经理
B
Blog
T
The Blog of Author Tim Ferriss
H
Help Net Security
云风的 BLOG
云风的 BLOG

博客园 - Artech

[MAF预定义的AIContextProvider-05]CompactionProvider——采用多种策略压缩对话历史 [MAF预定义的AIContextProvider-04]Mem0Provider——长期记忆基于的云端解决方案 [MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力 [MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF [MAF预定义的AIContextProvider-01]TextSearchProvider——RAG在MAF中的实现 [MAF预定义ChatClient中间件-09]MessageInjectingChatClient-赋予工具消息注入的能力 [MAF预定义ChatClient中间件-08]OpenTelemetryChatClient-实现链路跟踪和性能监控 [MAF预定义ChatClient中间件-07]PerServiceCallChatHistoryPersistingChatClient——基于ReAct循环的一步一存档 [MAF预定义ChatClient中间件-06]利用ImageGeneratingChatClient开发专业图片生成Agent [MAF预定义ChatClient中间件-05]动态修改ChatOptions和请求消息 [MAF预定义ChatClient中间件-04]ReducingChatClient——精减对话历史又不丢失基本语义 [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间 [MAF预定义ChatClient中间件-02]FunctionInvokingChatClient——实现ReAct循环和人机交互的大功臣 [MAF预定义ChatClient中间件-01]LoggingChatClient——在调用LLM前后输出日志 [MAF的Agent管道详解-06]ChatClientAgent对IChatClient和输入输出增强管道的整合 [MAF的Agent管道详解-06]ChatClientAgent对IChatClient和输入输出增强管道的整合 - Artech [MAF的Agent管道详解-05]对话历史的持久化和输入输出的增强 [MAF的Agent管道详解-04]如何让LLM按照要求的结构输出数据? [MAF的Agent管道详解-03]连接LLM的IChatClient对象 [MAF的Agent管道详解-02]IChatClient管道如何完美连接大模型? [MAF的Agent管道详解-01]塑智能体边界,从AIAgent抽象类开始 [对比学习LangChain和MAF-04]针对消息的设计 [对比学习LangChain和MAF-03]完全不同的Agent设计哲学 [对比学习LangChain和MAF-02]基本编程模式的差异(下篇) [对比学习LangChain和MAF-01]基本编程模式的差异(上篇) 这是一篇测试文章 我所理解的Python元模型 除了按值和引用,方法参数的第三种传递方式 方法的三种调用形式 可以调用Null的实例方法吗?
[MAF的Agent管道详解-07]利用AIAgent中间件构建Agent管道
Artech · 2026-06-02 · via 博客园 - Artech

与采用DelegatingChatClient中间件装饰IChatClient对象并构成IChatClient管道的方式类似,我们可以使用DelegatingAIAgent代表的AIAgent中间件来装饰一个AIAgent对象,并构成一个AIAgent管道。通过在不同的阶段插入不同的AIAgent中间件,我们就可以实现对Agent调用的全方位控制和增强。DelegatingAIAgent中间件链条位于整个AIAgent管道的最前端。

Alternative Text

1. DelegatingAIAgent

作为AIAgent中间件的一个DelegatingAIAgent类型定义如下。这是一个派生于AIAgent的抽象类,它的核心成员是一个InnerAgent属性,表示被委托的AIAgent对象。我们可以定义DelegatingAIAgent的派生类,通过重写其属性成员和方法来实现对InnerAgent的功能扩展和增强。通过不断地嵌套多个DelegatingAIAgent,我们就可以构建出一个类似于中间件的管道来对AIAgent进行扩展和增强。

public abstract class DelegatingAIAgent : AIAgent
{
    protected AIAgent InnerAgent { get; }
    protected override string? IdCore => InnerAgent.Id;
    public override string? Name => InnerAgent.Name;
    public override string? Description => InnerAgent.Description;
    protected DelegatingAIAgent(AIAgent innerAgent) =>InnerAgent = innerAgent;

    public override object? GetService(Type serviceType, object? serviceKey = null)
    {
        if (serviceKey != null || !serviceType.IsInstanceOfType(this))
        {
            return InnerAgent.GetService(serviceType, serviceKey);
        }
        return this;
    }

    protected override ValueTask<AgentSession> CreateSessionCoreAsync(
        CancellationToken cancellationToken = default)
    =>InnerAgent.CreateSessionAsync(cancellationToken);

    protected override ValueTask<JsonElement> SerializeSessionCoreAsync(
        AgentSession session, 
        JsonSerializerOptions? jsonSerializerOptions = null, 
        CancellationToken cancellationToken = default)
    =>InnerAgent.SerializeSessionAsync(session, jsonSerializerOptions, cancellationToken);

    protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(
        JsonElement serializedState, 
        JsonSerializerOptions? jsonSerializerOptions = null, 
        CancellationToken cancellationToken = default)
    =>InnerAgent.DeserializeSessionAsync(serializedState, jsonSerializerOptions, cancellationToken);

    protected override Task<AgentResponse> RunCoreAsync(
        IEnumerable<ChatMessage> messages, 
        AgentSession? session = null, 
        AgentRunOptions? options = null, 
        CancellationToken cancellationToken = default)
    => InnerAgent.RunAsync(messages, session, options, cancellationToken);

    protected override IAsyncEnumerable<AgentResponseUpdate> RunCoreStreamingAsync(
        IEnumerable<ChatMessage> messages, 
        AgentSession? session = null, 
        AgentRunOptions? options = null, 
        CancellationToken cancellationToken = default)
    => InnerAgent.RunStreamingAsync(messages, session, options, cancellationToken);
}

多个DelegatingAIAgent和最终的被委托的AIAgent按照顺序组成了一个AIAgent管道,这个管道的结构如下所示。

Alternative Text

从定义可以看出,以DelegatingAIAgent形式定义的AIAgent中间件并非专属于ChatClientAgent,理论上它可以用于任何类型的AIAgent对象。所以系统按照ChatClientBuilder一样的模式定义了AIAgentBuilder。我们可以针对一个具体的AIAgent或者创建AIAgent的工厂来构建一个AIAgentBuilder对象,然后通过调用AIAgentBuilder的一系列重载的Use方法来注册不同的AIAgent中间件,最后调用Build方法来构建出一个代表整个管道的AIAgent对象。

2. AIAgentBuilder

public sealed class AIAgentBuilder
{	
    public AIAgentBuilder(AIAgent innerAgent);
    public AIAgentBuilder(Func<IServiceProvider, AIAgent> innerAgentFactory);

    public AIAgent Build(IServiceProvider? services = null);

    public AIAgentBuilder Use(Func<AIAgent, AIAgent> agentFactory);
    public AIAgentBuilder Use(Func<AIAgent, IServiceProvider, AIAgent> agentFactory);
    public AIAgentBuilder Use(
        Func<IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, Func<IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, CancellationToken, Task>, CancellationToken, Task> sharedFunc);

    public AIAgentBuilder Use(
        Func<IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, AIAgent, CancellationToken, Task<AgentResponse>>? runFunc, 
        Func<IEnumerable<ChatMessage>, AgentSession?, AgentRunOptions?, AIAgent, CancellationToken, IAsyncEnumerable<AgentResponseUpdate>>? runStreamingFunc);
}

3. 系统预定义的AIAgent中间件

  • MessageAIContextProviderAgent:MessageAIContextProviderAgent是对一组MessageAIContextProvider的包装,它利用重写的RunCoreAsync和RunCoreStreamingAsync方法来调用MessageAIContextProvider针对请求消息的增强以及针对响应消息的增强和处理异常;
  • FunctionInvocationDelegatingAgent:利用提供的委托可以在某个工具的执行前后注入自定义的逻辑,也可以接管某个工具的调用;
  • AIHostAgent:通过为为AIAgent绑定了一个AgentSessionStore用来持久化会话状态,使之成为一个具有会话持久化与线程恢复能力的AIAgent;
  • LoggingAgent:负责拦截内部Agent的各种生命周期操作(如发送请求、模型响应、工具调用),并将这些细节高效、结构化地输出到.NET标准的ILogger日志管道中;
  • OpenTelemetryAgent:它实现了OpenTelemetry,能够将Agent在推理、工具调用及多轮协作中的各种行为,转化为标准化的Trace链路追踪)、Metrics(指标度量)和 Logs(日志),输出给云端或本地的现代观测后端;
  • FundtryAgent:是微软Agent框架中连接本地代码与Azure AI Foundry云端托管服务的平台级桥梁组件 。它采用定义在云、消费在本地的架构,Agent的提示词、模型参数和工具资产(如代码解释器、文件检索)全部在云端进行可视化管理与安全执行。本地代码只需通过 Agent ID即可直接对其进行实例化;
  • EntityAgentWrapper:基于 Azure Durable Functions或Durable Task Scheduler 的底层技术,为Agent披上了一层“防弹衣”。它把一个普通的 AIAgent(例如 ChatClientAgent)封装为一个受持久化框架管理的有状态实体(Durable Entity)。 包装器形式出现)是 Durable Task 扩展包(Durable Task Extension)中的核心组件。它的核心职责是将普通的无状态Agent包装为“长生不老”的有状态持久化实体,使其能够跨越服务器崩溃、重启或数周的人工审批流,自动实现状态恢复与断点续传。