Conversation
This was referenced Apr 6, 2026
louis4li
added a commit
that referenced
this pull request
Apr 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MAF-Inspired Framework Improvements
基于 Microsoft Agent Framework (MAF) 调研,对 Aevatar 框架进行 6 项改进,涵盖中间件管线、可观测性、人机交互、工具审批、编排模式和表达式语言。
变更概览
1. Agent Middleware Pipeline
问题
原有 Hook 系统 (
IAIGAgentExecutionHook) 是 best-effort 执行,无法修改或拦截 Agent 输入输出。MAF 提供三层中间件(Agent Run / Function Calling / IChatClient),支持安全过滤、限流、内容审查等横切关注点。方案
新增三层 Middleware 接口,与 Hook 系统共存(Hook 做观测,Middleware 做拦截):
IAgentRunMiddleware— 包裹整个 Agent Chat 执行,可修改用户输入、短路返回IToolCallMiddleware— 包裹每次 Tool 执行,可验证参数、覆盖结果、阻止调用ILLMCallMiddleware— 包裹每次 LLM 调用,可修改 messages、注入 system prompt、变换响应中间件通过 DI 注册,遵循 ASP.NET Core 中间件模式(
next()递归链)。补充约定:
ChatAsync与ChatStreamAsync均会进入IAgentRunMiddleware链。provider.ChatStreamAsync(...)会在ILLMCallMiddleware链的next()内执行,确保观测/限流/缓存等横切逻辑对流式调用同样生效。新增文件
src/Aevatar.AI.Abstractions/Middleware/IAgentRunMiddleware.cssrc/Aevatar.AI.Abstractions/Middleware/IToolCallMiddleware.cssrc/Aevatar.AI.Abstractions/Middleware/ILLMCallMiddleware.cssrc/Aevatar.AI.Core/Middleware/MiddlewarePipeline.cs修改文件
src/Aevatar.AI.Core/Tools/ToolCallLoop.cs— 集成 Tool + LLM 中间件src/Aevatar.AI.Core/Chat/ChatRuntime.cs— 集成 Agent Run + LLM 中间件src/Aevatar.AI.Core/AIGAgentBase.cs— 从 DI 收集中间件并注入 Runtime使用示例
2. OpenTelemetry GenAI Semantic Conventions
问题
原有 ActivitySource 仅在 LocalActor 层记录事件处理 span,缺少 LLM 调用和 Tool 执行的标准化 span 和 metrics。MAF 遵循 OpenTelemetry GenAI Semantic Conventions 发射
invoke_agent/chat/execute_tool标准 span。方案
以内置 Middleware 形式实现可观测性(
GenAIObservabilityMiddleware),同时实现三个 Middleware 接口:Span 类型(GenAI 语义规范):
invoke_agent <name>— 每次 Agent Run,包含gen_ai.agent.id/gen_ai.agent.name/gen_ai.provider.namechat <model>— 每次 LLM 调用,包含gen_ai.request.model/gen_ai.provider.name/gen_ai.usage.*_tokensexecute_tool <name>— 每次 Tool 调用,包含gen_ai.tool.name/gen_ai.tool.call_id(span kind 为INTERNAL)Metrics(直方图):
gen_ai.client.token.usage— Token 消耗gen_ai.client.operation.duration— LLM 调用耗时aevatar.tool.invocation.duration— Tool 调用耗时敏感数据控制:通过
GenAIActivitySource.EnableSensitiveData控制是否在 span 中包含 prompt/response 内容。新增文件
src/Aevatar.AI.Core/Observability/GenAIActivitySource.cssrc/Aevatar.AI.Core/Observability/GenAIObservabilityMiddleware.cssrc/Aevatar.Foundation.Runtime/Observability/AevatarObservabilityOptions.cssrc/Aevatar.Foundation.Runtime/Observability/GenAIMetrics.cs修改文件
src/Aevatar.Foundation.Runtime/Observability/AevatarActivitySource.cs— 增加 GenAI span 工厂方法使用示例
3. Human-in-the-Loop Workflow Steps
问题
MAF 提供
Question/Confirmation/WaitForInput/RequestExternalInput四种 Human-in-the-Loop 操作。Aevatar 工作流引擎没有暂停执行等待人工输入的机制。方案
新增两个工作流步骤模块和暂停/恢复事件:
HumanApprovalModule— 处理type: human_approval,暂停工作流等待 yes/no 审批HumanInputModule— 处理type: human_input,暂停工作流等待自由文本输入通过
WorkflowSuspendedEvent/WorkflowResumedEvent实现暂停恢复,AGUI 层映射为HUMAN_INPUT_REQUEST事件供前端渲染。YAML DSL 扩展
参数约定(最小集):
human_approval:prompt/timeout(秒)/on_reject(默认fail)human_input:prompt/variable/timeout(秒)/on_timeout(默认fail)新增文件
src/workflow/Aevatar.Workflow.Core/Modules/HumanApprovalModule.cssrc/workflow/Aevatar.Workflow.Core/Modules/HumanInputModule.cssrc/workflow/Aevatar.Workflow.Projection/Reducers/WorkflowSuspendedEventReducer.cs修改文件
src/workflow/Aevatar.Workflow.Core/cognitive_messages.proto— 新增WorkflowSuspendedEvent/WorkflowResumedEventsrc/Aevatar.Presentation.AGUI/AGUIEvents.cs— 新增HumanInputRequestEvent/HumanInputResponseEventsrc/workflow/Aevatar.Workflow.Presentation.AGUIAdapter/EventEnvelopeToAGUIEventMapper.cs— 新增映射 Handlersrc/workflow/Aevatar.Workflow.Presentation.AGUIAdapter/DependencyInjection/ServiceCollectionExtensions.cs— 注册src/workflow/Aevatar.Workflow.Core/ServiceCollectionExtensions.cs— 默认注册human_input/human_approval步骤模块4. Tool Approval Mechanism
问题
MAF 的
@tool(approval_mode="always_require")可阻止 Agent 自主执行敏感工具。Aevatar 的工具系统无审批机制。方案
在
IAgentTool接口增加ApprovalMode属性(默认NeverRequire,向后兼容):与 Middleware Pipeline 自然组合:
IToolCallMiddleware可检查context.Tool.ApprovalMode实现审批逻辑。新增文件
src/Aevatar.AI.Abstractions/ToolProviders/ToolApprovalMode.cs修改文件
src/Aevatar.AI.Abstractions/ToolProviders/IAgentTool.cs— 增加ApprovalMode默认接口属性5. Reusable Multi-Agent Orchestration Patterns
问题
MAF 将 5 种编排模式打包为可复用组件。Aevatar 通过 Workflow 模块实现类似能力,但与 YAML 引擎紧耦合,无法在无 YAML 场景下程序化使用。
方案
抽取 4 种编排模式为
Aevatar.Foundation.Core.Orchestration命名空间下的一等公民:SequentialOrchestrationConcurrentOrchestrationVoteOrchestrationHandoffOrchestration所有模式基于
IOrchestration<TInput, TOutput>接口,接受Func<string, string, CancellationToken, Task<string>>作为 Agent 执行委托,与具体 Agent 实现解耦。新增文件
src/Aevatar.Foundation.Core/Orchestration/IOrchestration.cssrc/Aevatar.Foundation.Core/Orchestration/SequentialOrchestration.cssrc/Aevatar.Foundation.Core/Orchestration/ConcurrentOrchestration.cssrc/Aevatar.Foundation.Core/Orchestration/VoteOrchestration.cssrc/Aevatar.Foundation.Core/Orchestration/HandoffOrchestration.cs6. Declarative Workflow Expression Language
问题
MAF 的声明式工作流使用 PowerFx 表达式语言。Aevatar YAML DSL 有变量替换但缺少运行时表达式求值。
方案
新增轻量级
${...}表达式求值器,支持:${name}${variables.user}${if(...)}${if(variables.age, 'adult', 'minor')}${concat(...)}${concat('Hello, ', variables.name)}${isBlank(...)}${isBlank(variables.input)}${length(...)}${length(variables.text)}${and/or/not(...)}${and(variables.a, variables.b)}${upper/lower/trim(...)}${upper(variables.name)}支持嵌套函数调用和引号字面量,参数分隔正确处理括号嵌套。
新增文件
src/workflow/Aevatar.Workflow.Core/Expressions/WorkflowExpressionEvaluator.cs修改文件
src/workflow/Aevatar.Workflow.Core/Modules/WorkflowLoopModule.cs— 在派发StepRequestEvent前对步骤参数执行${...}求值运行时变量与求值时机
WorkflowLoopModule.DispatchStep(...)发布StepRequestEvent前,对step.parameters的 value 做一次模板替换(${...})。run_id维护独立变量字典,默认包含:input:当前步骤的输入(上一步输出)<stepId>:已完成步骤的输出(同名 key),可用${first_step}或${variables.first_step}引用验证