Repository navigation
[Aevatar Harness] 梳理 Harness 核心能力现状与演进边界 #567
Description
背景
这个 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.cssrc/Aevatar.AI.Core/Chat/ChatRuntime.cssrc/Aevatar.AI.Core/Tools/ToolCallLoop.cssrc/Aevatar.AI.Core/Tools/StreamingToolExecutor.cssrc/Aevatar.AI.Core/RoleGAgent.cssrc/Aevatar.Foundation.Core/GAgentBase.cssrc/Aevatar.Foundation.Core/GAgentBase.TState.cssrc/workflow/Aevatar.Workflow.Core/WorkflowRunGAgent.cssrc/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-searchkeyword / semantic search。/skills/{idOrName}/json拉取 skill package JSON。- skill generation。
- playground chat。
- runtime-based skill 通过 chrono-sandbox 执行。
Aevatar 当前已经实现
相关路径:
src/Aevatar.AI.Abstractions/ToolProviders/IAgentTool.cssrc/Aevatar.AI.Abstractions/ToolProviders/IAgentToolSource.cssrc/Aevatar.AI.Abstractions/Middleware/IToolCallMiddleware.cssrc/Aevatar.AI.Core/Tools/ToolManager.cssrc/Aevatar.AI.Core/Tools/ToolCallLoop.cssrc/Aevatar.AI.Core/Tools/StreamingToolExecutor.cssrc/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。
当前欠缺
- Tools / Plugins 边界还没有收敛到 NyxID
Aevatar 现在还有不少直接 tool providers:
Aevatar.AI.ToolProviders.LarkAevatar.AI.ToolProviders.TelegramAevatar.AI.ToolProviders.ChronoStorageAevatar.AI.ToolProviders.WebAevatar.AI.ToolProviders.WorkflowAevatar.AI.ToolProviders.ScriptingAevatar.AI.ToolProviders.BindingAevatar.AI.ToolProviders.ServiceInvokeAevatar.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 上已经做好的能力。
- 缺少 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。
- 缺少动态刷新 / 激活语义
当前 Aevatar tool discovery 多数是启动或 agent activation 时发现并缓存。NyxID services/plugins 是用户可配置的,配置会变化;如果 Aevatar 不能刷新 tool list,就会出现:
- 用户在 NyxID 连接了新 service,agent 不知道。
- 用户撤销 service 或 credential,agent 仍以为可用。
- NyxID MCP 侧已经有 dynamic tools changed 的语义,但 Aevatar 没有对应接入。
- 治理边界需要明确
外部 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 和结果摘要。
- Skills 目前偏“加载指令”,不是完整 Ornn skill runtime
当前 use_skill 的主要行为是:
- 找到 skill;
- 返回
SKILL.mdinstructions; - 附带 associated files;
- 由 LLM 继续按说明执行。
这适合 plain skills,但对 runtime-based / tool-based / mixed skills 还不够。Ornn 已经有 playground/sandbox 能力,Aevatar 不应自己再造 sandbox;更好的方向是把 runtime execution 委托给 Ornn / chrono-sandbox。
- 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。
- 非流式 tool metadata 传递存在风险
流式路径创建 StreamingToolExecutor 时会传 requestMetadata,所以 NyxID/Ornn tools 能通过 AgentToolRequestContext 拿 token。
但非流式 ToolCallLoop.ExecuteToolCallsCoreAsync 中创建 StreamingToolExecutor 时没有传 metadata。虽然外层设置过 AgentToolRequestContext.CurrentMetadata,executor 内部执行时又会设置自己的 _requestMetadata,这里可能导致某些非流式 tool 拿不到 NyxID token。
建议单独修复:让非流式路径也把 metadata 传给 executor,或者统一工具执行上下文传递方式。
建议方案
- 定义工具分层
建议明确三类工具:
NyxID-backed external tools:外部 services/plugins,默认走 NyxID。Ornn-backed skills:skills 的搜索、加载、运行,默认走 Ornn。Aevatar-native tools:只保留 Aevatar 运行时内部必须拥有的能力。
- 新增或收敛 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 的映射。
- 逐步降级 Aevatar direct external providers
对 Lark / Telegram / Web / ChronoStorage / generic external API:
- 短期可保留 typed facade,服务现有场景;
- 中期在文档和配置上标记为 transitional;
- 长期尽量迁移为 NyxID service/plugin;
- 只保留真正属于 Aevatar runtime 内部的原生 tools。
- 把 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、哪个版本、输入摘要和输出摘要。
- 明确治理归属
- NyxID-backed plugin:NyxID 管 credential/scope/approval/audit。
- Ornn-backed skill:Ornn 管 skill package/provenance/runtime/sandbox,必要时结合 NyxID 权限。
- Aevatar-native tool:Aevatar 本地 approval/middleware 管。
- 补齐测试和守卫
建议优先加:
- 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.cssrc/Aevatar.Foundation.Core/EventSourcing/IEventSourcingBehavior.cssrc/Aevatar.Foundation.Core/EventSourcing/EventSourcingBehavior.cssrc/Aevatar.Foundation.Abstractions/agent_messages.protosrc/Aevatar.AI.Core/RoleGAgent.cssrc/Aevatar.AI.Abstractions/ai_messages.protosrc/workflow/Aevatar.Workflow.Core/WorkflowRunGAgent.cssrc/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 可以拉开差异的地方。
主要欠缺
- Memory 模型还没有被产品化表达出来
现在代码里有 state、event sourcing、session、projection,但 Harness 层还没有一个清晰的 AgentMemory / SessionMemory / RunMemory 语义。用户看到的可能仍然只是“有 chat history”,而不是“agent 有一套可信的状态记忆”。
- 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。
这些现在还没有统一命名和查询契约。
- 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。
- “回滚”语义需要收敛成 event sourcing 的正确姿势
让 agent 读取自己的 event logs,并自己决定 raise 一个 event 来回滚 state,是一个有价值的方向,但需要改一下表达:
- 不应该删除、改写或倒放历史事件。
- 不应该让 LLM 直接操作 event store。
- 不应该在 query path 里 replay event 后临时拼 state。
- 正确模型应该是:agent 可以提出一个 corrective command,由 actor 验证后追加一个新的补偿事件或恢复事件。
例如:
PreferenceRemovedEventConfigurationRolledBackEventSessionMemoryForgottenEventStateRestoredFromVersionEventToolBindingRevokedEvent
这些事件被 append 到同一个 event stream,再由 actor transition 出新的 current state,并通过 CommittedStateEventPublished(state_event + state_root) 更新 readmodel。历史仍然完整,当前态可以恢复,审计也能解释“谁在什么时候因为哪个原因做了回滚”。
- 缺少 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,诚实表达最终一致性。
- 遗忘、隐私、权限和审计还没有统一治理
event log 很强,但也意味着敏感信息不能随意扩散。
需要明确:
- 哪些事件可以被 agent 自我查询。
- 哪些字段需要 redaction 后才能进入 memory readmodel。
- 哪些 memory 操作需要用户 approval。
- 哪些 memory 可以忘记,哪些只能追加 tombstone/forget event。
- secret、credential、raw external payload 不应进入普通 memory projection。
建议方向
- 把 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 拥有,不在中间层临时拼。
- 提供 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。
- 把回滚定义为“追加补偿事件”
推荐原则:
- rollback 是 domain command,不是 storage operation。
- rollback 结果是新的 committed event,不是删除旧 event。
- actor 自己验证目标 version、可恢复字段、权限、当前版本冲突。
- destructive restore / forget / revoke 默认需要 approval。
- projection 用新的 state version 覆盖当前 readmodel,旧 timeline 仍可审计。
这样 agent 可以有自我修复能力,但不会破坏 event sourcing 的事实链。
- 用 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 拥有,而不是散落在各个进程缓存或向量库里。
- 优先做一个最小闭环
建议第一阶段不要一上来做通用 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.cssrc/Aevatar.AI.Abstractions/ToolProviders/ToolApprovalMode.cssrc/Aevatar.AI.Abstractions/ToolProviders/IToolApprovalHandler.cssrc/Aevatar.AI.Core/Middleware/ToolApprovalMiddleware.cssrc/Aevatar.AI.Core/Middleware/YieldApprovalHandler.cssrc/Aevatar.AI.Core/RoleGAgent.cssrc/Aevatar.AI.Core/Hooks/IAIGAgentExecutionHook.cssrc/Aevatar.AI.Core/Hooks/AgentHookPipeline.cssrc/Aevatar.AI.Core/Hooks/BuiltIn/BudgetMonitorHook.cssrc/Aevatar.Configuration/AevatarConnectorConfig.cssrc/Aevatar.Bootstrap/Connectors/HttpConnector.cssrc/Aevatar.Bootstrap/Connectors/CliConnector.cssrc/Aevatar.AI.ToolProviders.MCP/MCPConnector.cssrc/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cssrc/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_samplinghook 已经处在 LLM 输出和 tool 执行之间,理论上可以做 tool call 参数预审、输出过滤和 tool call blocking。BudgetMonitorHook已经能观察 token 使用,但目前主要是 warning,不是硬门禁。- Connector 已经有局部 allowlist:HTTP
allowedMethods / allowedPaths / allowedInputKeys,CLIallowedOperations / allowedInputKeys,MCPallowedTools / 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 应优先复用。
主要欠缺
- 没有统一的 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。
- 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 优先,低层只能收窄不能放宽高层限制。
- 缺少通用 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 删除、转账、发公网消息、修改权限等路径。
- 缺少 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。
- 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 失败但动作继续执行”的风险。
- 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 的统一协议。
- 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。
- 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,而不是只写日志。
- 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。
- 缺少运行中 revoke / pause / kill switch
Harness 治理需要能在 run 开始后改变策略:
- 暂停某个 agent;
- 撤销某个 tool/service;
- 停止某个 session/run;
- 暂停所有 destructive actions;
- scope 级紧急只读模式。
这类变更应由 actor-owned governance state 或 readmodel 观察,不应依赖进程内开关。
建议方向
- 定义统一 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。
- 建立统一 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。
- 把 Path Rules 做成一等能力
现有 connector allowlist 可以复用,但要升格为通用模型:
resource_kind:http / nyxid_proxy / cli / mcp / file / memory / actor_command / workflow / scriptresource_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 决定默认行为。
- 引入 Denied Commands / Denied Tool Calls
建议将拒绝动作建模为事件和 readmodel,而不是散落在错误字符串里:
GovernanceDecisionRecordedEventToolCallDeniedEventCommandDispatchDeniedEventConnectorInvocationDeniedEventMemoryMutationDeniedEventApprovalRequiredEventApprovalDecisionRecordedEvent
这些事件进入 projection 后,可以支撑 UI、审计、调试和 agent 自我解释。
- 统一 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 路由到人。
- 把 Hooks 从治理里“降级”为扩展点,把 Hard Gate 做成正式端口
保留现有 IAIGAgentExecutionHook 做 trace、metrics、notification、debug。
另设治理端口,例如:
IAgentGovernancePolicyEvaluatorIToolInvocationPolicyGateICommandDispatchPolicyGateIConnectorInvocationPolicyGateIMemoryMutationPolicyGate
强门禁失败时必须 fail-closed,且产出治理事件。
- 与 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。
- 优先做最小闭环
第一阶段建议做一个最小可落地闭环:
- 盘点所有 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.protosrc/Aevatar.Foundation.Abstractions/IEventPublisher.cssrc/Aevatar.Foundation.Abstractions/Attributes/EventHandlerAttribute.cssrc/Aevatar.Foundation.Abstractions/EventModules/IEventModule.cssrc/Aevatar.Foundation.Abstractions/EventModules/IEventHandlerContext.cssrc/Aevatar.Foundation.Core/GAgentBase.cssrc/Aevatar.Foundation.Core/Pipeline/EventHandlerDiscoverer.cssrc/Aevatar.Foundation.Core/Pipeline/EventPipelineBuilder.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans/Grains/RuntimeActorGrain.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans/Actors/OrleansGrainEventPublisher.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans/Actors/OrleansActorRuntime.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/OrleansActorStream.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/OrleansDistributedStreamForwardingRegistry.cssrc/Aevatar.Foundation.Runtime.Implementations.Orleans.Streaming/Streaming/Topology/StreamTopologyGrain.cssrc/Aevatar.Foundation.Core/MultiAgent/TeamManagerGAgent.cssrc/Aevatar.Foundation.Core/MultiAgent/TaskBoardGAgent.cssrc/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 层对这套能力的统一抽象、产品表达和约束。
主要欠缺
- 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 状态与观察主链。
- 缺少统一 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 中。
- 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”。
- 缺少标准协作模式
底层支持消息通信,但 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。
- 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。
- 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 是否能暂停整个协作。
- 协议级可靠性还需要产品化表达
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 架构形成很强的差异化。
建议方向
- 把 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。
这样能避免把业务应用形态误认为底层能力。
- 定义 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。
- 把 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,而不是让调用方猜。
- 标准化 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 承载核心语义。
- 补齐 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。
- 把常见协作模式做成内建 patterns
可以逐步提供:
manager-worker;planner-executor-reviewer;task-board work stealing;vote/consensus;supervisor-watchdog;specialist delegation。
这些不需要破坏底层模型,本质都是 aggregate actor + typed protocol + readmodel。
- 把 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
[-][Aevatar Harness] 梳理 Agent Loop 现状并收敛统一运行模型[/-][+][Aevatar Harness] 梳理 Harness 核心能力现状与演进边界[/+]eanzhao commentedon May 5, 2026
已迁移到 Discussion,后续团队讨论请在这里继续:
#568
结构上保留一个总讨论贴,并将 Harness 五个角度分别拆成顶层回复帖:
这个 issue 作为迁移来源关闭。