Skip to content

[Aevatar Harness] 梳理 Harness 核心能力现状与演进边界 #567

Closed

Description

@eanzhao

背景

这个 issue 用来讨论 Aevatar Harness 的整体能力边界。

目前 Aevatar 已经具备一些 Harness 关键能力:Agent Loop、Tools / Skills / Plugins、Memory / Session、Governance、Multi-Agent 的雏形都存在。但这些能力还比较分散,有些已经在 Aevatar 内实现,有些应该优先复用外部平台能力。

当前需要先明确一条原则:

  • Aevatar 不应该把自己做成一个大而全的 tools/plugins 平台。
  • Tools / Plugins 优先结合 NyxID:通过 NyxID services / proxy / MCP / approval / agent binding 来配置和调用其他 services。
  • Skills 优先结合 Ornn:通过 Ornn 做 skill 的创建、发布、搜索、拉取、执行。
  • Aevatar 只做接入、编排、运行时上下文传递与必要的原生工具。 只有 NyxID / Ornn 现有 surface 覆盖不了,且确实属于 Aevatar 运行时内部能力时,才在 Aevatar 内新增 tools / plugins。

这个 issue 不要求 NyxID、chrono-ornn、chrono-storage 等外部仓库新增能力。方案应优先使用这些仓库当前已经公开的能力。

当前能力总览

1. Agent Loop

相关路径:

  • src/Aevatar.AI.Core/AIGAgentBase.cs
  • src/Aevatar.AI.Core/Chat/ChatRuntime.cs
  • src/Aevatar.AI.Core/Tools/ToolCallLoop.cs
  • src/Aevatar.AI.Core/Tools/StreamingToolExecutor.cs
  • src/Aevatar.AI.Core/RoleGAgent.cs
  • src/Aevatar.Foundation.Core/GAgentBase.cs
  • src/Aevatar.Foundation.Core/GAgentBase.TState.cs
  • src/workflow/Aevatar.Workflow.Core/WorkflowRunGAgent.cs
  • src/workflow/Aevatar.Workflow.Core/Execution/WorkflowExecutionKernel.cs

已经具备:

  • ChatRuntime 已经实现 LLM -> tool call -> tool result -> next round 的多轮循环。
  • 支持 ChatStreamAsync 流式主链路,文本、reasoning、tool call、tool result 可以沿同一条流式链路输出。
  • 支持 structured tool call 和文本/XML fallback tool call。
  • 支持 hook / middleware,例如 execution trace、tool truncation、budget monitor、approval middleware。
  • RoleGAgent 已经把 AI loop 接入 actor/GAgent 模型,通过 ChatRequestEvent 触发,通过 TextMessage*、ToolCallEvent、ToolResultEvent 对外发布观察事件。
  • GAgentBase<TState> 已经有 actor-owned state、event sourcing、committed state event 发布到 observation/projection 主链。
  • WorkflowRunGAgent + WorkflowExecutionKernel 已经实现更接近 actor 化的 workflow loop:step 推进、timeout、retry、backoff、completion 都通过事件推进。

主要欠缺:

  • Agent Loop、Workflow Loop、StreamingProxy group chat loop 仍是几条相对独立的链路,还没有统一成 Harness run/session 语义。
  • ChatRuntime 内部仍有 Task.Run、tool executor lock/queue/background task,一次 actor turn 内可能承载较长 LLM/tool 执行过程。作为本地执行器可用,但若作为 Harness 主干,长期需要更 actor-native 的 continuation 模型。
  • Tool round、approval、timeout、LLM sampling、tool invocation 并没有全部成为 actor-owned continuation state。
  • Agent Loop 的中间态 readmodel 还不完整,例如 round trace、tool invocation ledger、approval decision、budget usage、run failure reason 等。

建议方向:

  • 定义统一 AgentRun / AgentSession / AgentTurn / AgentLoopStep / AgentObservation 语义。
  • 将 loop 标准阶段收敛为 Normalize -> Resolve Target/Session -> Build Context -> Sample -> Tool Invocation -> Observe -> Continue/Complete。
  • 长耗时阶段逐步事件化:LLM sampling started/completed/failed、tool invocation requested/completed/failed、approval requested/decided/timed out、run completed/failed/cancelled。

2. Tools / Skills / Plugins

这是当前需要重点收敛的部分。

预期边界

Aevatar 的工具体系不应该长期演进成“所有外部服务都在 Aevatar 里写一套 provider”。更合理的边界是:

  • NyxID 负责 Tools / Plugins 的服务配置与调用面。
    • 用户配置 external services。
    • NyxID 管 credential、proxy、approval、agent isolation、service catalog、MCP dynamic tools。
    • Aevatar 通过 NyxID token / API key 调用这些 services。
  • Ornn 负责 Skills 的创建、发布、发现、拉取与执行面。
    • skill package、metadata、版本、搜索、playground/sandbox 都优先走 Ornn。
    • Aevatar 不重复实现 skill registry / sandbox 平台。
  • Aevatar 只保留必要的原生工具。
    • 例如 ask_user、workflow/binding 内部操作、少量 actor/runtime 内部能力。
    • Lark / Telegram / Web / ChronoStorage / 第三方 API 这类应优先作为 NyxID services/plugins,而不是 Aevatar 长期维护 typed tools。

外部能力现状

NyxID 已经具备:

  • user_endpoints / user_api_keys / user_services 三类用户服务配置模型。
  • /api/v1/keys 用于统一创建服务配置。
  • /api/v1/catalog 和 /api/v1/catalog/{slug}/endpoints 用于服务目录和 endpoint discovery。
  • /api/v1/proxy/services 用于 proxyable services discovery。
  • /api/v1/proxy/s/{slug}/{path} 用于 slug-based proxy。
  • /api/v1/approvals 用于 approval request / grant / service config。
  • API key scope、agent binding、per-agent credential override、rate limit 和 audit attribution。
  • NyxID MCP 已经支持 nyx__search_tools、nyx__discover_services、nyx__connect_service,并能按已连接服务动态生成 MCP tools。

Ornn 已经具备:

  • skill create / read / update / delete。
  • /skill-search keyword / semantic search。
  • /skills/{idOrName}/json 拉取 skill package JSON。
  • skill generation。
  • playground chat。
  • runtime-based skill 通过 chrono-sandbox 执行。

Aevatar 当前已经实现

相关路径:

  • src/Aevatar.AI.Abstractions/ToolProviders/IAgentTool.cs
  • src/Aevatar.AI.Abstractions/ToolProviders/IAgentToolSource.cs
  • src/Aevatar.AI.Abstractions/Middleware/IToolCallMiddleware.cs
  • src/Aevatar.AI.Core/Tools/ToolManager.cs
  • src/Aevatar.AI.Core/Tools/ToolCallLoop.cs
  • src/Aevatar.AI.Core/Tools/StreamingToolExecutor.cs
  • src/Aevatar.AI.ToolProviders.NyxId/*
  • src/Aevatar.AI.ToolProviders.Ornn/*
  • src/Aevatar.AI.ToolProviders.Skills/*

已经具备:

  • 有统一 IAgentTool / IAgentToolSource 抽象。
  • Tool 可声明 ApprovalMode、IsReadOnly、IsDestructive、RequiresApproval(argumentsJson)。
  • 有 tool call middleware,可做参数校验、结果覆盖、阻断、approval gate。
  • 有 ToolApprovalMiddleware,支持本地 approval/yield 到 actor continuation。
  • 有 NyxIdAgentToolSource,暴露 NyxID account/status/catalog/services/proxy/approvals/nodes/api keys/capability search 等工具。
  • 有 nyxid_proxy,通过 NyxID proxy 调下游服务,并明确把外部服务审批交给 NyxID server-side。
  • 有 nyxid_search_capabilities + nyxid_proxy_execute,可以基于 NyxID OpenAPI spec 做较泛化的 NyxID API 调用。
  • 有 Ornn ornn_search_skills,可搜索 Ornn skill。
  • 有 use_skill,可从本地 registry 或 Ornn remote fetcher 拉取 skill instructions 和 associated files。

当前欠缺

  1. Tools / Plugins 边界还没有收敛到 NyxID

Aevatar 现在还有不少直接 tool providers:

  • Aevatar.AI.ToolProviders.Lark
  • Aevatar.AI.ToolProviders.Telegram
  • Aevatar.AI.ToolProviders.ChronoStorage
  • Aevatar.AI.ToolProviders.Web
  • Aevatar.AI.ToolProviders.Workflow
  • Aevatar.AI.ToolProviders.Scripting
  • Aevatar.AI.ToolProviders.Binding
  • Aevatar.AI.ToolProviders.ServiceInvoke
  • Aevatar.AI.ToolProviders.MCP

其中一部分可能是 Aevatar-native runtime 能力,但 Lark / Telegram / Web / external service / generic API 这类更适合通过 NyxID services/plugins 暴露。

问题不是这些 provider 当前不能用,而是长期边界容易变成:每接一个服务,Aevatar 就新增一套 typed tool provider。这会绕开 NyxID 在 credential、approval、agent isolation、audit、service catalog 上已经做好的能力。

  1. 缺少 NyxID Plugin / Service ToolSource

Aevatar 目前有 nyxid_proxy,但还没有一个明确的 NyxIDPluginToolSource 或同等抽象:

  • 从 NyxID /proxy/services 或 MCP surface 发现用户已连接 services。
  • 根据 service endpoint schema 动态暴露 service tools。
  • 支持按需激活 / tool list refresh。
  • 把 service capability、approval config、scope、agent binding 作为工具可见语义。

NyxID MCP 已经有类似动态工具模型,Aevatar 应优先复用或适配,而不是重新发明一套 plugin registry。

  1. 缺少动态刷新 / 激活语义

当前 Aevatar tool discovery 多数是启动或 agent activation 时发现并缓存。NyxID services/plugins 是用户可配置的,配置会变化;如果 Aevatar 不能刷新 tool list,就会出现:

  • 用户在 NyxID 连接了新 service,agent 不知道。
  • 用户撤销 service 或 credential,agent 仍以为可用。
  • NyxID MCP 侧已经有 dynamic tools changed 的语义,但 Aevatar 没有对应接入。
  1. 治理边界需要明确

外部 service/plugin 调用应该优先由 NyxID 负责:

  • credential 注入;
  • approval;
  • per-agent API key;
  • scope;
  • rate limit;
  • audit attribution;
  • service binding。

Aevatar 本地 ToolApprovalMiddleware 应主要用于 Aevatar-native tools,而不是重复审批 NyxID 已经治理的外部 services。

当前一些 typed tools 使用 ApprovalMode.Auto,但没有明确设置 IsDestructive,可能导致本地 approval 判断并不可靠。如果这些工具未来统一走 NyxID,那 Aevatar 本地只需要记录 tool call reference 和结果摘要。

  1. Skills 目前偏“加载指令”,不是完整 Ornn skill runtime

当前 use_skill 的主要行为是:

  • 找到 skill;
  • 返回 SKILL.md instructions;
  • 附带 associated files;
  • 由 LLM 继续按说明执行。

这适合 plain skills,但对 runtime-based / tool-based / mixed skills 还不够。Ornn 已经有 playground/sandbox 能力,Aevatar 不应自己再造 sandbox;更好的方向是把 runtime execution 委托给 Ornn / chrono-sandbox。

  1. Ornn 能力接得还比较浅

当前 Aevatar Ornn client 主要覆盖:

  • keyword search;
  • fetch skill JSON。

还缺:

  • semantic search;
  • category browsing;
  • skill version/hash/provenance;
  • skill permissions / required env / runtime-dependency 的显式表达;
  • runtime-based skill execution;
  • artifact retrieval;
  • skill run audit/reference。
  1. 非流式 tool metadata 传递存在风险

流式路径创建 StreamingToolExecutor 时会传 requestMetadata,所以 NyxID/Ornn tools 能通过 AgentToolRequestContext 拿 token。

但非流式 ToolCallLoop.ExecuteToolCallsCoreAsync 中创建 StreamingToolExecutor 时没有传 metadata。虽然外层设置过 AgentToolRequestContext.CurrentMetadata,executor 内部执行时又会设置自己的 _requestMetadata,这里可能导致某些非流式 tool 拿不到 NyxID token。

建议单独修复:让非流式路径也把 metadata 传给 executor,或者统一工具执行上下文传递方式。

建议方案

  1. 定义工具分层

建议明确三类工具:

  • NyxID-backed external tools:外部 services/plugins,默认走 NyxID。
  • Ornn-backed skills:skills 的搜索、加载、运行,默认走 Ornn。
  • Aevatar-native tools:只保留 Aevatar 运行时内部必须拥有的能力。
  1. 新增或收敛 NyxID Plugin ToolSource

基于 NyxID 当前能力实现 Aevatar 侧薄适配:

  • 发现 /proxy/services;
  • 读取 service endpoint schema;
  • 暴露为 agent tools;
  • 调用时通过 NyxID proxy;
  • approval/audit/scope/rate limit 由 NyxID 负责;
  • Aevatar 记录 run 内 tool call observation。

如果直接复用 NyxID MCP 更合适,也可以让 Aevatar 的 MCP tool source 连接 NyxID MCP,而不是自己实现 endpoint -> tool 的映射。

  1. 逐步降级 Aevatar direct external providers

对 Lark / Telegram / Web / ChronoStorage / generic external API:

  • 短期可保留 typed facade,服务现有场景;
  • 中期在文档和配置上标记为 transitional;
  • 长期尽量迁移为 NyxID service/plugin;
  • 只保留真正属于 Aevatar runtime 内部的原生 tools。
  1. 把 Skills 收敛到 Ornn

Aevatar 的 skill 能力建议演进为:

  • search_skill:调用 Ornn search,支持 keyword/semantic/category。
  • load_skill:拉取 Ornn skill package,保留 version/hash/source。
  • run_skill:对 runtime-based skill 委托 Ornn playground/sandbox 或 Ornn 定义的执行 surface。
  • skill_observation:Aevatar 只记录这次 run 使用了哪个 skill、哪个版本、输入摘要和输出摘要。
  1. 明确治理归属
  • NyxID-backed plugin:NyxID 管 credential/scope/approval/audit。
  • Ornn-backed skill:Ornn 管 skill package/provenance/runtime/sandbox,必要时结合 NyxID 权限。
  • Aevatar-native tool:Aevatar 本地 approval/middleware 管。
  1. 补齐测试和守卫

建议优先加:

  • NyxID-backed external tool 不绕过 NyxID proxy 的测试。
  • Aevatar-native tool 才走本地 approval 的测试。
  • Ornn skill load/search 的 token/context 传递测试。
  • 非流式 tool metadata 传递测试。
  • Workflow tool_call 不绕过统一 tool invocation 语义的测试。

3. Memory / Session

基本判断

Aevatar 的 Memory / Session 不应该简单对齐传统 agent harness 的“chat history + vector memory”。Aevatar 已经有一个更有辨识度的底座:

  • actor-owned state:每个 GAgent 自己拥有当前权威状态。
  • committed domain events:状态变化不是临时文本,而是有版本、有时间、有类型、有 actor 归属的事件事实。
  • projection readmodel:查询、搜索、UI、AGUI、审计、ledger 等读侧能力都应该从 committed facts 物化出来。
  • session / chat history / prompt compression:这些是 prompt context 和会话体验层,不应该成为唯一 memory 真相。

换句话说,Aevatar 的核心记忆模型更应该是:

Memory = State + Event Log + Projection ReadModel

这和很多 agent harness 不一样。常见 harness 往往把 memory 做成 transcript、vector DB、cache 或 tool trace sidecar;Aevatar 可以把 memory 做成 actor 状态机的一部分:可版本化、可解释、可审计、可回放修复、可投影成多种查询视图。

当前已有

相关路径:

  • src/Aevatar.Foundation.Core/GAgentBase.TState.cs
  • src/Aevatar.Foundation.Core/EventSourcing/IEventSourcingBehavior.cs
  • src/Aevatar.Foundation.Core/EventSourcing/EventSourcingBehavior.cs
  • src/Aevatar.Foundation.Abstractions/agent_messages.proto
  • src/Aevatar.AI.Core/RoleGAgent.cs
  • src/Aevatar.AI.Abstractions/ai_messages.proto
  • src/workflow/Aevatar.Workflow.Core/WorkflowRunGAgent.cs
  • src/workflow/Aevatar.Workflow.Core/Execution/WorkflowExecutionKernel.cs

已经具备:

  • GAgentBase<TState> 的状态更新是 event-first:先 RaiseEvent / ConfirmEventsAsync,再把 event transition 到 actor state。
  • commit 成功后会发布 CommittedStateEventPublished,其中同时携带 state_event 和 state_root。这非常适合把“发生了什么”和“发生后状态是什么”一起送入 projection/readmodel。
  • StateEvent 本身已经有 event_id / timestamp / version / event_type / event_data / agent_id,天然适合做 memory timeline 和 audit ledger。
  • RoleGAgentState.sessions 已经保存 bounded session state,包括 prompt、完成态、final content、reasoning content、tool calls、input/output parts 等。
  • PendingToolApprovalState 已经把等待 approval 的 tool call 作为 actor state,而不是只放在进程内回调里。
  • Workflow run 已经把当前 step、variables、retry、timeout/backoff、execution id 等运行态放进 actor-owned state,通过事件推进。
  • scripting 文档里已经明确 current-state readmodel 的方向:事件推进 actor state,readmodel 从 post-event state 派生,query 只读 persisted snapshot/document。

这些能力目前更多服务于恢复、投影和架构正确性,还没有被充分包装成 agent 可以主动使用的“自我记忆能力”。这正是 Aevatar 可以拉开差异的地方。

主要欠缺

  1. Memory 模型还没有被产品化表达出来

现在代码里有 state、event sourcing、session、projection,但 Harness 层还没有一个清晰的 AgentMemory / SessionMemory / RunMemory 语义。用户看到的可能仍然只是“有 chat history”,而不是“agent 有一套可信的状态记忆”。

  1. Session memory 和 actor state memory 没有分层

当前 RoleGAgentState.sessions 更像最近 session 的 bounded replay cache。它能支持会话恢复,但还不是完整 memory 分层:

  • 当前 turn 的 prompt context;
  • 当前 session 的对话与工具轨迹;
  • actor 长期状态,比如偏好、配置、绑定、能力、策略;
  • 由 projection 物化出来的 session timeline、tool ledger、approval ledger、decision log;
  • scope/team 级 aggregate memory。

这些现在还没有统一命名和查询契约。

  1. Agent 还不能安全地“看见自己的历史”

event sourcing 的价值之一是:agent 不只知道当前 state,还可以知道自己为什么变成这样。但这里不能简单把“所有 event logs”直接塞给模型。

更合理的是提供受治理的自我记忆查询面:

  • 查询自己的当前 state summary 和 state version。
  • 查询经过 projection/redaction/summarization 的 event timeline。
  • 按事件类型、时间、版本、correlation id、session id 搜索自己的历史。
  • 对比两个 state version 的差异。
  • 解释某个配置、偏好、绑定、approval、tool result 是由哪些事件形成的。

原始 event store 更适合 recovery、debug、migration、admin repair,不应该成为正常 query path 或 prompt path。

  1. “回滚”语义需要收敛成 event sourcing 的正确姿势

让 agent 读取自己的 event logs,并自己决定 raise 一个 event 来回滚 state,是一个有价值的方向,但需要改一下表达:

  • 不应该删除、改写或倒放历史事件。
  • 不应该让 LLM 直接操作 event store。
  • 不应该在 query path 里 replay event 后临时拼 state。
  • 正确模型应该是:agent 可以提出一个 corrective command,由 actor 验证后追加一个新的补偿事件或恢复事件。

例如:

  • PreferenceRemovedEvent
  • ConfigurationRolledBackEvent
  • SessionMemoryForgottenEvent
  • StateRestoredFromVersionEvent
  • ToolBindingRevokedEvent

这些事件被 append 到同一个 event stream,再由 actor transition 出新的 current state,并通过 CommittedStateEventPublished(state_event + state_root) 更新 readmodel。历史仍然完整,当前态可以恢复,审计也能解释“谁在什么时候因为哪个原因做了回滚”。

  1. 缺少 memory readmodel/search/index 的稳定契约

长期记忆不应该只靠 chat compression 或 vector search。vector index 可以是 readmodel 的一种,但不能代替权威状态。

需要定义几类 actor-scoped readmodel:

  • current state summary:当前状态、版本、水位、可展示摘要。
  • event timeline:重要事件、版本、时间、来源、session/run/correlation。
  • decision log:重要决策及其依据事件。
  • tool invocation ledger:工具调用、参数摘要、结果摘要、失败原因、approval 关联。
  • approval ledger:申请、审批、拒绝、超时、delegated to NyxID 等。
  • session index:session 摘要、主题、结果、相关工具、最后活跃时间。
  • memory search index:从 committed facts 和 state summary 派生出的搜索/向量索引。

所有 readmodel 都应该暴露 source version / watermark,诚实表达最终一致性。

  1. 遗忘、隐私、权限和审计还没有统一治理

event log 很强,但也意味着敏感信息不能随意扩散。

需要明确:

  • 哪些事件可以被 agent 自我查询。
  • 哪些字段需要 redaction 后才能进入 memory readmodel。
  • 哪些 memory 操作需要用户 approval。
  • 哪些 memory 可以忘记,哪些只能追加 tombstone/forget event。
  • secret、credential、raw external payload 不应进入普通 memory projection。

建议方向

  1. 把 Memory 分成五层
  • Turn Context:当前轮 prompt、临时 tool result、模型上下文窗口。生命周期最短,不是权威事实。
  • Session Memory:一次 session/run 的对话、工具轨迹、结果、失败、approval。由 actor state + session readmodel 表达。
  • Actor Long-term State:偏好、配置、绑定、策略、长期能力、上次稳定状态等。由 actor-owned state 表达。
  • Projection Memory:timeline、ledger、search、vector index、UI/AGUI view。由 committed facts 和 state_root 派生。
  • Aggregate Memory:team/scope/project 级共享记忆,由专门 aggregate actor 拥有,不在中间层临时拼。
  1. 提供 Harness-native self-memory tools

这些 tools 应该是 Aevatar-native,因为它们读取的是 Aevatar 自己的 actor state/readmodel,不属于外部 service/plugin。

建议先设计这些能力:

  • inspect_self_state:读取自己的 current-state readmodel,返回摘要、版本、水位。
  • search_self_events:读取投影后的 event timeline,支持类型、时间、版本、session、correlation 过滤。
  • explain_self_state:解释某个状态字段由哪些事件形成。
  • diff_self_state_versions:对比当前 state 与某个历史版本或 checkpoint 的差异。
  • propose_memory_correction:让 agent 提出纠偏方案,但不直接写 state。
  • request_state_restore:请求恢复到某个版本或撤销某类变更,由 actor/policy 验证后追加补偿事件。
  • forget_session_memory:对可遗忘的 session memory 追加 forget/tombstone 事件,并更新 readmodel。

注意:这些 tools 查询的是 readmodel 或受控 memory query port,不是直接读 IEventStore 后在请求路径 replay。

  1. 把回滚定义为“追加补偿事件”

推荐原则:

  • rollback 是 domain command,不是 storage operation。
  • rollback 结果是新的 committed event,不是删除旧 event。
  • actor 自己验证目标 version、可恢复字段、权限、当前版本冲突。
  • destructive restore / forget / revoke 默认需要 approval。
  • projection 用新的 state version 覆盖当前 readmodel,旧 timeline 仍可审计。

这样 agent 可以有自我修复能力,但不会破坏 event sourcing 的事实链。

  1. 用 event sourcing 做“可信记忆”,用 projection 做“可用记忆”

可以把 Aevatar 的差异化说清楚:

  • 传统 memory 更像“模型旁边的一本笔记”。
  • Aevatar memory 更像“agent 自己的状态账本”。
  • event log 负责可信、因果、版本和审计。
  • actor state 负责当前权威事实。
  • projection/readmodel 负责查询、搜索、摘要、UI、AGUI、治理报表。

这能支持一些传统 harness 不容易做好的能力:

  • agent 解释自己为什么记住某件事。
  • agent 比较现在和历史版本的差异。
  • agent 主动发现最近一次 tool/config/session 变化导致了坏状态。
  • agent 通过补偿事件修复自己,而不是靠 prompt 提醒“下次别这样”。
  • 用户可以审计 agent 什么时候学到了什么、忘掉了什么、因为什么恢复到了旧状态。
  • 多 agent 的共享记忆可以由 aggregate actor 拥有,而不是散落在各个进程缓存或向量库里。
  1. 优先做一个最小闭环

建议第一阶段不要一上来做通用 memory 平台,而是围绕 RoleGAgent 做一个最小闭环:

  • 为 RoleGAgent 定义 AgentMemoryReadModel 或等价 query surface。
  • 先投影 session summary、tool ledger、approval ledger、important state changes。
  • 给 agent 一个 inspect_self_state 和 search_self_events。
  • 再加一个保守的 propose_memory_correction,只生成建议,不直接执行。
  • 最后再加 request_state_restore / forget_session_memory 这类需要 approval 的写侧能力。

不建议做

  • 不把完整 raw event log 默认塞进 prompt。
  • 不让 LLM 直接访问 IEventStore 做正常业务查询。
  • 不在 query path replay events 来临时拼 state。
  • 不通过删除历史事件实现回滚。
  • 不把 secret、credential、raw external payload 投影进普通 memory readmodel。
  • 不把 vector memory 当成唯一长期记忆源。

4. Governance

基本判断

Governance 不能只理解成“工具调用前问一下用户”。对 Aevatar Harness 来说,Governance 应该是一套贯穿 agent run 全链路的策略系统:

  • 模型输出是否允许继续进入 tool call。
  • 某个 tool / connector / command 是否允许调用。
  • HTTP path、CLI operation、MCP tool、service endpoint 是否命中 allow/deny rule。
  • 高风险操作是否需要 interactive approval。
  • 预算、频率、模型、provider、外部 service 是否受限。
  • 被拒绝、被审批、被放行的动作是否进入 event / readmodel / audit ledger。

Aevatar 现在已经有一些治理点,但还没有形成统一的 Harness governance layer。它更像散落在 tool、connector、workflow、scripting、service governance 里的多套局部规则。

当前已有

相关路径:

  • src/Aevatar.AI.Abstractions/ToolProviders/IAgentTool.cs
  • src/Aevatar.AI.Abstractions/ToolProviders/ToolApprovalMode.cs
  • src/Aevatar.AI.Abstractions/ToolProviders/IToolApprovalHandler.cs
  • src/Aevatar.AI.Core/Middleware/ToolApprovalMiddleware.cs
  • src/Aevatar.AI.Core/Middleware/YieldApprovalHandler.cs
  • src/Aevatar.AI.Core/RoleGAgent.cs
  • src/Aevatar.AI.Core/Hooks/IAIGAgentExecutionHook.cs
  • src/Aevatar.AI.Core/Hooks/AgentHookPipeline.cs
  • src/Aevatar.AI.Core/Hooks/BuiltIn/BudgetMonitorHook.cs
  • src/Aevatar.Configuration/AevatarConnectorConfig.cs
  • src/Aevatar.Bootstrap/Connectors/HttpConnector.cs
  • src/Aevatar.Bootstrap/Connectors/CliConnector.cs
  • src/Aevatar.AI.ToolProviders.MCP/MCPConnector.cs
  • src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs
  • src/platform/Aevatar.GAgentService.Governance.*
  • src/Aevatar.Scripting.Infrastructure/Compilation/ScriptSandboxPolicy.cs

已经具备:

  • IAgentTool 支持 ApprovalMode、IsReadOnly、IsDestructive、RequiresApproval(argumentsJson)。
  • ToolApprovalMode 当前有 NeverRequire / AlwaysRequire / Auto。
  • ToolApprovalMiddleware 可以在 tool call 前请求 approval,也能基于工具声明和运行时参数决定是否审批。
  • YieldApprovalHandler 支持非阻塞 approval:middleware 先 yield,actor 再持久化 pending state。
  • RoleGAgent 已经把 pending approval 放进 PendingToolApprovalState,并发布 ToolApprovalRequestEvent,审批通过后再 self-continuation 执行工具。
  • RoleGAgent 支持 local approval timeout 后升级到 NyxID remote approval handler。
  • AI hooks 覆盖 LLM start/end、tool start/end、session start/end、approval requested/completed、post-sampling、tool failure、stop 等阶段。
  • post_sampling hook 已经处在 LLM 输出和 tool 执行之间,理论上可以做 tool call 参数预审、输出过滤和 tool call blocking。
  • BudgetMonitorHook 已经能观察 token 使用,但目前主要是 warning,不是硬门禁。
  • Connector 已经有局部 allowlist:HTTP allowedMethods / allowedPaths / allowedInputKeys,CLI allowedOperations / allowedInputKeys,MCP allowedTools / allowedInputKeys。
  • HTTP connector 已经校验目标 URL 不能逃逸 configured baseUrl 的 scheme/host/port。
  • Workflow role 可以声明 connector allowlist,ConnectorCallModule 会校验当前 step 的 connector 是否在 role 允许列表内。
  • scripting sandbox 已经有 forbidden API 检查,例如禁止 Task.Run、Thread、File、Directory、HttpClient、Socket 等。
  • GAgent service governance 已经有 service policy / activation admission / invoke admission 的雏形。
  • NyxID 侧已经有 credential、scope、approval、agent binding、rate limit、audit attribution 等外部 service 治理能力,Aevatar 应优先复用。

主要欠缺

  1. 没有统一的 GovernancePolicy / PermissionProfile

当前规则分散在 tool 声明、middleware、connector config、workflow role、scripting sandbox、service governance、NyxID approval 里。缺少一个 Harness 层可解释、可继承、可审计的 policy 模型。

建议不要只做“工具审批配置”,而是定义统一的 AgentGovernanceProfile 或同等契约,至少表达:

  • permission mode;
  • tool rules;
  • command rules;
  • path rules;
  • connector / service rules;
  • memory mutation rules;
  • model/provider rules;
  • budget/rate rules;
  • approval routing;
  • audit/readmodel policy。
  1. Permission mode 太粗

当前 ToolApprovalMode 只有工具级 NeverRequire / AlwaysRequire / Auto,不能表达 run/session/agent/scope 级权限模式。

Harness 层需要多级 permission mode,例如:

  • Disabled:agent 暂停,不能执行动作。
  • ReadOnly:只能读 readmodel、读文件、读外部服务;不能写状态、发消息、调用写接口。
  • SuggestOnly:可以生成计划、diff、命令建议,但不能真正 dispatch。
  • ApprovalRequired:所有写操作、外部调用、memory mutation 都需要 approval。
  • AutoWithGuardrails:只读和低风险动作自动执行,高风险动作升级 approval,deny rule 永远优先。
  • Trusted:允许预配置范围内自动执行,但仍受 hard deny、budget、scope、path rules 约束。

这些 mode 应该能按层级继承:tenant/org -> scope/team -> agent definition -> session/run -> tool/command invocation。原则上 explicit deny 优先,低层只能收窄不能放宽高层限制。

  1. 缺少通用 Path Rules

Aevatar 已经有 HTTP allowedPaths,但它只是 connector 局部能力。Harness 需要更通用的 path/resource rule:

  • HTTP method + path allow/deny。
  • NyxID proxy service slug + path allow/deny。
  • file path / workspace path allow/deny。
  • CLI operation allow/deny。
  • MCP server/tool allow/deny。
  • memory path/state field allow/deny。
  • workflow/script resource path allow/deny。

而且需要同时支持 allow、deny、escalate-to-approval。只做 allowlist 不够,因为有些场景默认允许某个 service,但要明确 deny 删除、转账、发公网消息、修改权限等路径。

  1. 缺少 Denied Commands 机制

Aevatar 现在有 command dispatch pipeline,但没有统一的 command deny layer。

需要能按强类型 command 语义拒绝:

  • command type URL / message type;
  • target actor kind;
  • target actor id / scope;
  • operation kind,比如 create/update/delete/rollback/restore/send;
  • payload 中的关键字段;
  • caller identity / session / run。

被拒绝的 command 不应该只是返回一个字符串错误,而应该形成 GovernanceDecisionEvent 或同等 committed observation,进入 denied-command ledger/readmodel。

  1. Hooks 现在是 observation hook,不是 hard gate

AgentHookPipeline 当前是 best-effort:hook 抛错只 log warning,不阻塞主流程。这很适合 telemetry、trace、notification,但不适合做强安全策略。

需要把 hook 分成两类:

  • ObservationHook:best-effort,不影响主流程。
  • PolicyGate / GuardrailEvaluator:强门禁,必须返回 allow / deny / require_approval / redact / rewrite,失败时默认 fail-closed。

否则未来把安全逻辑写进 hook,会出现“hook 失败但动作继续执行”的风险。

  1. Interactive approval 没有统一成一个系统

现在至少有几套 approval:

  • tool approval middleware;
  • RoleGAgent pending approval continuation;
  • workflow human_approval;
  • NyxID remote approval;
  • channel interactive cards / approve/reject fallback;
  • scripting promote/rollback 等高风险工具的 AlwaysRequire。

这些还没有统一的 approval request/readmodel/decision contract。缺少:

  • 统一 approval request id;
  • approval subject/action/risk/diff/argument summary;
  • approval requester / approver / timeout / channel;
  • approval decision event;
  • approval ledger;
  • approval 后如何恢复 run/session/actor continuation 的统一协议。
  1. Tool 风险分类不够可靠

很多 tool 默认继承 NeverRequire、IsReadOnly = false、IsDestructive = false 的隐含语义。对于治理来说,这个默认值太危险:一个新工具如果忘了声明,就可能绕过 approval。

需要至少做到:

  • Aevatar-native tools 必须显式声明 risk classification。
  • 未分类工具默认 ApprovalRequired 或 UnknownRisk,不能静默自动执行。
  • 外部 NyxID-backed plugin 的风险优先来自 NyxID service config / endpoint metadata / approval policy。
  • Ornn skill 的风险来自 skill manifest / runtime permissions / required services。
  1. Budget / rate / cost 还只是观察,不是治理

BudgetMonitorHook 目前只是 log warning。Harness 需要 run-level 和 scope-level budget:

  • max tokens;
  • max tool calls;
  • max external spend;
  • max runtime duration;
  • max approval wait;
  • max retries;
  • per-tool / per-service rate limit。

超过预算时应能 deny、pause、require approval 或 degrade model,而不是只写日志。

  1. Policy decision 没有统一 ledger/readmodel

Governance 的竞争力不只在“挡住危险动作”,还在“能解释为什么挡住/为什么放行”。

需要 readmodel:

  • policy decision ledger;
  • denied command ledger;
  • approval ledger;
  • tool invocation ledger;
  • budget ledger;
  • external service access ledger;
  • memory mutation ledger。

这些都应该带 run/session/agent/scope/correlation id 和 state version/watermark。

  1. 缺少运行中 revoke / pause / kill switch

Harness 治理需要能在 run 开始后改变策略:

  • 暂停某个 agent;
  • 撤销某个 tool/service;
  • 停止某个 session/run;
  • 暂停所有 destructive actions;
  • scope 级紧急只读模式。

这类变更应由 actor-owned governance state 或 readmodel 观察,不应依赖进程内开关。

建议方向

  1. 定义统一 Governance Profile

建议新增或设计一套强类型 governance 契约,表达类似:

  • permission_mode;
  • tool_rules;
  • command_rules;
  • path_rules;
  • connector_rules;
  • memory_rules;
  • budget_rules;
  • approval_policy;
  • audit_policy。

规则的 action 建议统一为:

  • allow;
  • deny;
  • require_approval;
  • redact;
  • rewrite;
  • observe_only。
  1. 建立统一 Policy Evaluation Pipeline

至少在这些边界做强门禁:

  • ingress / user command normalization;
  • pre-LLM:是否允许本次 model/provider 调用;
  • post-sampling:是否允许模型输出的 tool calls;
  • pre-tool:是否允许工具执行;
  • pre-connector:是否允许 HTTP/CLI/MCP/service path;
  • pre-command-dispatch:是否允许 actor command;
  • pre-memory-mutation:是否允许 remember/forget/restore/rollback;
  • pre-reply:是否允许对外发送消息或附件。

Policy evaluator 的输出应是强类型 decision:Allowed / Denied / ApprovalRequired / Redacted / Rewritten,并包含 matched rules 和 reason。

  1. 把 Path Rules 做成一等能力

现有 connector allowlist 可以复用,但要升格为通用模型:

  • resource_kind: http / nyxid_proxy / cli / mcp / file / memory / actor_command / workflow / script
  • resource_id: connector name、service slug、actor kind、tool name 等。
  • method_or_operation: GET/POST、CLI operation、MCP tool、command type URL。
  • path_pattern: exact / prefix / glob / regex。
  • payload_rules: allowed/denied JSON paths、max body size、sensitive fields。
  • action: allow / deny / require_approval。

匹配原则:explicit deny > require approval > allow;没有匹配时由 permission mode 决定默认行为。

  1. 引入 Denied Commands / Denied Tool Calls

建议将拒绝动作建模为事件和 readmodel,而不是散落在错误字符串里:

  • GovernanceDecisionRecordedEvent
  • ToolCallDeniedEvent
  • CommandDispatchDeniedEvent
  • ConnectorInvocationDeniedEvent
  • MemoryMutationDeniedEvent
  • ApprovalRequiredEvent
  • ApprovalDecisionRecordedEvent

这些事件进入 projection 后,可以支撑 UI、审计、调试和 agent 自我解释。

  1. 统一 Interactive Approval

把 tool approval、workflow human approval、NyxID approval、channel card approval 收敛到一个 approval contract:

  • approval_request_id;
  • subject_kind: tool / command / connector / memory / workflow / service;
  • subject_id;
  • action;
  • risk_level;
  • argument_summary / diff_summary;
  • requested_by_agent_id / session_id / run_id;
  • approver_policy;
  • timeout;
  • decision。

外部 service/plugin 的 approval 仍然优先交给 NyxID;Aevatar-native runtime action 的 approval 由 Aevatar 自己产生事件、持久化 pending state,并通过 UI/channel/NyxID handler 路由到人。

  1. 把 Hooks 从治理里“降级”为扩展点,把 Hard Gate 做成正式端口

保留现有 IAIGAgentExecutionHook 做 trace、metrics、notification、debug。

另设治理端口,例如:

  • IAgentGovernancePolicyEvaluator
  • IToolInvocationPolicyGate
  • ICommandDispatchPolicyGate
  • IConnectorInvocationPolicyGate
  • IMemoryMutationPolicyGate

强门禁失败时必须 fail-closed,且产出治理事件。

  1. 与 NyxID / Ornn 的边界
  • NyxID-backed external tools/plugins:credential、scope、approval、rate limit、audit 优先由 NyxID 负责。Aevatar 做 run/session 级 observation 和必要的二次 hard deny。
  • Ornn-backed skills:skill provenance、runtime permissions、sandbox 能力优先来自 Ornn manifest/runtime。Aevatar 负责是否允许本 agent/run 使用这个 skill,以及记录 skill usage ledger。
  • Aevatar-native tools:必须走 Aevatar governance profile、approval、ledger。
  1. 优先做最小闭环

第一阶段建议做一个最小可落地闭环:

  • 盘点所有 Aevatar-native tools,强制补齐 risk classification。
  • 定义 AgentGovernanceProfile 的最小版本:permission mode + tool rules + command deny rules + path rules + approval policy。
  • 在 tool execution 前增加 hard policy gate。
  • 在 connector invocation 前复用并记录 path rule decision。
  • 在 command dispatch 前增加 denied command gate。
  • 把 approval requested/decided、tool denied、command denied、budget exceeded 投影成 governance readmodel。
  • 对外部 NyxID-backed tools,只记录 Aevatar run observation,不重复实现 NyxID credential/approval。

不建议做

  • 不把安全策略写进 best-effort hook 当作强门禁。
  • 不继续依赖 tool 默认值推断风险。
  • 不只做 allowlist,不做 explicit deny / require approval。
  • 不把 denied/approval/budget 只写日志,不进 event/readmodel。
  • 不让外部 service/plugin 绕过 NyxID 的 credential、scope、approval、audit。
  • 不用进程内计数器作为长期治理事实;denial/budget/approval 应进入 actor state 或 projection ledger。

5. Multi-Agent

基本判断

Multi-Agent 这里不应该主要看 StreamingProxy。StreamingProxy 只是一个 group/chat 业务形态,不是 Aevatar multi-agent 能力的根。

Aevatar 本身就是一个搭建在 Orleans 上的 multi-agent platform:

  • 每个 GAgent 是一个 actor / Orleans grain 承载的智能体实例。
  • agent 之间通过 EventEnvelope 传递强类型 protobuf event。
  • SendToAsync 表达 point-to-point 投递到目标 actor inbox。
  • PublishAsync 表达 topology publication,例如 self / parent / children / parent-and-children。
  • Orleans stream 是 actor message plane 的底层传输。
  • GAgent 通过 [EventHandler] 和 IEventModule<IEventHandlerContext> 消费事件、推进状态、继续发布事件。
  • stateful GAgent 通过 event sourcing 持有自己的权威状态,并把 committed facts 送入 projection/readmodel。

所以 Aevatar 的 Multi-Agent 特色不是“有一个聊天室”,而是“默认运行时就是多 agent 的事件驱动系统”。Harness 层要做的是把这套底座产品化、协议化、治理化,而不是重新发明一个并行的 multi-agent 框架。

当前已有

相关路径:

  • src/Aevatar.Foundation.Abstractions/agent_messages.proto
  • src/Aevatar.Foundation.Abstractions/IEventPublisher.cs
  • src/Aevatar.Foundation.Abstractions/Attributes/EventHandlerAttribute.cs
  • src/Aevatar.Foundation.Abstractions/EventModules/IEventModule.cs
  • src/Aevatar.Foundation.Abstractions/EventModules/IEventHandlerContext.cs
  • src/Aevatar.Foundation.Core/GAgentBase.cs
  • src/Aevatar.Foundation.Core/Pipeline/EventHandlerDiscoverer.cs
  • src/Aevatar.Foundation.Core/Pipeline/EventPipelineBuilder.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans/Grains/RuntimeActorGrain.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans/Actors/OrleansGrainEventPublisher.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans/Actors/OrleansActorRuntime.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/OrleansActorStream.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/OrleansDistributedStreamForwardingRegistry.cs
  • src/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/Topology/StreamTopologyGrain.cs
  • src/Aevatar.Foundation.Core/MultiAgent/TeamManagerGAgent.cs
  • src/Aevatar.Foundation.Core/MultiAgent/TaskBoardGAgent.cs
  • src/Aevatar.Foundation.Abstractions/MultiAgent/multi_agent_messages.proto

已经具备:

  • EventEnvelope 已经有 direct route、publication route、publisher actor id、propagation、runtime、dedup/retry/callback/forwarding 等语义字段。
  • IEventPublisher 明确区分 PublishAsync 和 SendToAsync,并说明 publish/send 不代表 inline execution。
  • GAgentBase 已经提供统一 event pipeline:静态 [EventHandler] 和动态 IEventModule 按 priority 合并执行。
  • EventHandlerDiscoverer 可以从 GAgent 类型上发现 protobuf event handler。
  • StaticHandlerAdapter 会按 payload type 匹配事件,并处理 self-handling / only-self-handling 语义。
  • IEventHandlerContext 暴露 PublishAsync、SendToAsync、durable self timeout/timer,支持事件化 continuation。
  • Orleans runtime 下,RuntimeActorGrain 是实际承载 IAgent 的 grain,并通过 ImplicitStreamSubscription 订阅 actor stream。
  • OrleansActor.HandleEventAsync / OrleansAgentProxy.HandleEventAsync 都是把 envelope 写入 actor stream,而不是直接调用具体 GAgent 实例。
  • OrleansGrainEventPublisher 用 Orleans stream 实现 topology publication 和 direct delivery。
  • OrleansActorRuntime.LinkAsync(parent, child) 会设置 parent/child 关系,并通过 stream forwarding 建立 hierarchy binding。
  • OrleansDistributedStreamForwardingRegistry + StreamTopologyGrain 已经把 stream forwarding topology 放进 Orleans grain state,而不是单机内存表。
  • Orleans stream backend 支持 InMemory,也支持 Kafka provider-native backend;Garnet persistence 下 event store 可恢复。
  • TeamManagerGAgent 已经有 member registration、status、broadcast 的 actor-owned 状态与事件。
  • TaskBoardGAgent 已经有 task create/claim/complete/fail/request-work 的协调 actor,支持原子 claim、依赖解除、work assignment。
  • Workflow 模块中已经有对目标 role/actor 的 SendToAsync,说明 workflow 可以作为 multi-agent orchestration 的一种上层形态。

这些说明:Aevatar 的 multi-agent 底座不是缺失的,缺的是 Harness 层对这套能力的统一抽象、产品表达和约束。

主要欠缺

  1. Multi-Agent 没有被明确包装成 Harness 核心能力

现在底层能力很强,但产品/文档层容易让人误以为 Multi-Agent 是 StreamingProxy、group chat 或 workflow 的附属能力。

需要明确:

  • GAgent runtime 本身就是 multi-agent runtime。
  • Orleans grain 是 agent instance 的分布式执行载体。
  • EventEnvelope + stream 是 agent-to-agent message plane。
  • EventHandler 是 agent protocol handler。
  • Event sourcing + projection 是 multi-agent 状态与观察主链。
  1. 缺少统一 Multi-Agent Session / Team / Topology 语义

底层已经有 parent/child link、stream forwarding、TeamManager、TaskBoard,但还没有统一成 Harness 可见的:

  • team/session id;
  • participants;
  • roles;
  • topology;
  • protocol subscriptions;
  • shared task board;
  • message ledger;
  • participant status;
  • lifecycle。

现在这些能力分散在 runtime、workflow、multi-agent prototype、业务 GAgent 中。

  1. Agent-to-agent protocol 还缺少显式描述

Aevatar 已经支持“发 protobuf event,让对方 handler 处理”。但 Harness 层还缺 protocol descriptor:

  • 一个 agent 支持哪些 command/event/signal;
  • 哪些事件是 request,哪些是 reply,哪些是 notification;
  • correlation id / causation id / timeout / retry 如何表达;
  • reply event 如何回到原 actor;
  • 哪些协议允许跨 scope / 跨 team;
  • 哪些协议需要 approval 或治理。

如果不把协议显式化,multi-agent 会退化成“大家随便 SendToAsync 一个 event”。

  1. 缺少标准协作模式

底层支持消息通信,但 Harness 层还没有沉淀常见协作模式:

  • planner -> worker;
  • reviewer -> implementer;
  • manager -> task board -> worker;
  • debate / vote / consensus;
  • supervisor / watchdog;
  • specialist delegation;
  • tool-owning agent / memory-owning agent / governance-owning agent。

TaskBoardGAgent 和 workflow modules 已经有一些雏形,但还没有变成稳定 platform primitive。

  1. Multi-Agent readmodel / observability 不完整

如果 Aevatar 要把 multi-agent 做成优势,需要让用户和 agent 都能看见协作过程:

  • agent topology readmodel;
  • team/session participant readmodel;
  • inter-agent message ledger;
  • task board readmodel;
  • protocol run / correlation timeline;
  • pending reply / timeout / retry 状态;
  • agent health/status/capability snapshot。

当前底层 envelope 有 trace/correlation/route 信息,但还没有统一投影成 multi-agent dashboard 和 query surface。

  1. Agent-to-agent governance 还不完整

前面 Governance 提到 tool/command/path rules。Multi-Agent 还需要专门处理:

  • 哪个 agent 可以给哪个 agent 发 command;
  • 哪些 event type 可以跨 agent;
  • 哪些 agent 可以广播到 children / parent;
  • 哪些 topology link 可以创建或删除;
  • 哪些协作需要 human approval;
  • 高风险 agent 是否只能 read-only / suggest-only;
  • team/scope 级 kill switch 是否能暂停整个协作。
  1. 协议级可靠性还需要产品化表达

Runtime 已经有 dedup、retry、durable callback、stream forwarding 等基础设施。但 multi-agent 协议层还需要明确:

  • handler 必须幂等;
  • request/reply 必须 continuation 化;
  • timeout 通过 durable self callback 唤醒;
  • query 读取 readmodel,不向另一个 actor 做 generic query;
  • failure/retry/timeout 要进入 protocol ledger。

这部分如果表达清楚,会和 Aevatar 的 actor/event sourcing 架构形成很强的差异化。

建议方向

  1. 把 Multi-Agent 分成四层表达

建议 Harness 文档按四层讲清楚:

  • Runtime Layer:Orleans GAgent、actor identity、stream inbox、event handler。
  • Protocol Layer:protobuf event contracts、direct send、topology publish、correlation/causation、timeout/reply。
  • Coordination Layer:TeamManager、TaskBoard、WorkflowRun、GroupSession、Supervisor 等 aggregate actors。
  • Observation Layer:projection/readmodel、message ledger、task board、topology graph、health/status。

这样能避免把业务应用形态误认为底层能力。

  1. 定义 Multi-Agent Session / Team Aggregate

建议新增或收敛一个 actor-owned aggregate:

  • 拥有 team/session membership;
  • 维护 participant roles/status;
  • 维护 task board / collaboration plan;
  • 维护 protocol run/correlation;
  • 负责创建/链接/解绑参与 agent;
  • 所有稳定事实通过 event sourcing + projection 暴露。

TeamManagerGAgent 和 TaskBoardGAgent 可以作为这个方向的基础,但需要从 sample/prototype 变成正式平台能力,补 readmodel、governance、lifecycle 和 API。

  1. 把 Agent Protocol Descriptor 做成一等契约

每类 GAgent 应该能声明或被发现:

  • supported inbound event types;
  • emitted event types;
  • command/reply/signal 分类;
  • required permissions;
  • expected timeout/retry semantics;
  • whether it can be run-scoped / session-scoped / long-lived;
  • whether it owns authoritative state / readmodel。

这可以来自 [EventHandler] discovery + typed metadata + docs/manifest,而不是让调用方猜。

  1. 标准化 agent-to-agent 通讯规则

建议写成 Harness 规则:

  • SendToAsync = 投递到目标 actor inbox,不代表同步执行完成。
  • PublishAsync = 按 topology 发布,不代表所有订阅者已处理。
  • request/reply 必须用 correlation id 和 reply event continuation。
  • timeout/retry 用 durable callback 事件化。
  • 读取另一个 agent 的事实走 readmodel,不做 generic actor query。
  • 跨 agent 协议必须是强类型 protobuf event,不用字符串 bag 承载核心语义。
  1. 补齐 Multi-Agent readmodel

优先做这些 readmodel:

  • AgentTopologyReadModel:parent/child/link/stream forwarding view。
  • TeamSessionReadModel:team/session participants、roles、status。
  • AgentMessageLedger:agent-to-agent messages、route、correlation、causation、result。
  • TaskBoardReadModel:tasks、owner、status、dependencies、blocked/unblocked。
  • ProtocolRunReadModel:request/reply/timeout/retry/failure timeline。
  • AgentCapabilityReadModel:每类 agent 支持的 protocol/capability。
  1. 把常见协作模式做成内建 patterns

可以逐步提供:

  • manager-worker;
  • planner-executor-reviewer;
  • task-board work stealing;
  • vote/consensus;
  • supervisor-watchdog;
  • specialist delegation。

这些不需要破坏底层模型,本质都是 aggregate actor + typed protocol + readmodel。

  1. 把 Multi-Agent 与 Governance / Memory 打通
  • Governance:agent-to-agent command/path/protocol rule,禁止越权 dispatch。
  • Memory:team memory 由 aggregate actor/readmodel 拥有,不放中间层字典。
  • Session:multi-agent session 的上下文、任务、消息、结果全部可投影。
  • Audit:每次 dispatch / deny / approval / timeout / retry 都有 ledger。

不建议做

  • 不把 StreamingProxy 当作 Aevatar Multi-Agent 的核心定义。
  • 不新增一套绕过 GAgent/EventEnvelope/Orleans stream 的 multi-agent 通讯框架。
  • 不做 generic request-reply actor query。
  • 不通过进程内 registry/dictionary 管 team/session/participant 事实。
  • 不把 agent protocol 退化成字符串消息或 JSON bag。
  • 不把 parent/child stream topology 当成唯一产品语义;它是底层路由能力,上层还需要 team/session/task/protocol 语义。

建议验收标准

  • Aevatar Harness 文档明确五类能力边界:Agent Loop、Tools / Skills / Plugins、Memory / Session、Governance、Multi-Agent。
  • Tools / Plugins 默认走 NyxID services/proxy/MCP,Aevatar 不再把新增外部服务默认做成本地 typed tool provider。
  • Skills 默认走 Ornn,Aevatar 不重复实现 skill registry/sandbox 平台。
  • Aevatar-native tools 有明确白名单和职责说明,包括 self-memory/state inspection 这类内部能力。
  • Governance 明确定义多级 permission mode,例如 ReadOnly / SuggestOnly / ApprovalRequired / AutoWithGuardrails / Trusted / Disabled。
  • Governance 支持通用 path rules / command rules / tool rules,并明确 explicit deny 优先。
  • Denied tool call、denied command、approval requested/decided、budget exceeded 都有事件或 readmodel ledger,不只写日志。
  • Hooks 与 hard policy gate 分责:best-effort hooks 只做观察扩展,强治理通过 fail-closed policy evaluator 执行。
  • Interactive approval 统一表达 tool / command / connector / memory / workflow 等动作的 approval request 与 decision。
  • Aevatar-native tools 必须显式声明风险分类;未分类工具不能静默自动执行。
  • NyxID-backed plugin 的 credential/scope/approval/audit 由 NyxID 负责,Aevatar 只记录 run observation。
  • Ornn-backed skill 至少支持 search/load,并规划 runtime execution 委托。
  • Agent Loop 的关键阶段有统一 observation/readmodel 方向。
  • Multi-Agent 明确以 Orleans GAgent runtime 为核心表达,而不是以 StreamingProxy/group chat 作为主定义。
  • Multi-Agent 文档说明 EventEnvelope、SendToAsync、PublishAsync、Orleans stream、[EventHandler] 的 agent-to-agent 通讯语义。
  • Multi-Agent 协作有正式的 team/session/topology/task/protocol readmodel,而不是散落在业务实现里。
  • Agent-to-agent protocol 使用强类型 protobuf event,带 correlation/timeout/continuation 语义,不引入 generic actor query/reply。
  • Agent-to-agent dispatch 纳入 Governance,支持 command/event/protocol/topology 级 allow/deny/approval。
  • Memory / Session 明确采用 state + committed events + projection readmodel 作为核心模型,而不是只依赖 chat history/vector memory。
  • Agent 可以通过受控 memory query surface 查看自己的 current state summary、state version 和投影后的 event timeline。
  • 回滚/遗忘/纠偏采用追加补偿事件或恢复事件,不删除历史事件,不直接改写 event store。
  • Memory readmodel 暴露 source version / watermark,诚实表达最终一致性。
  • 不引入 query-time replay。
  • 不依赖进程内 dictionary 作为跨 run/session 权威事实。
  • 不要求修改 NyxID / chrono-ornn / chrono-storage 外部仓库。

Activity

  1. changed the title [-][Aevatar Harness] 梳理 Agent Loop 现状并收敛统一运行模型[/-] [+][Aevatar Harness] 梳理 Harness 核心能力现状与演进边界[/+] on May 5, 2026
  2. eanzhao commented on May 5, 2026

    @eanzhao
    ContributorAuthor

    已迁移到 Discussion,后续团队讨论请在这里继续:

    #568

    结构上保留一个总讨论贴,并将 Harness 五个角度分别拆成顶层回复帖:

    这个 issue 作为迁移来源关闭。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions