【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载本篇基于 capsules/capsule-forge/src/guides/ipc.md 展开,系统讲解 Unicity AOS(capsule-forge 作者手册中ipc一章)里工具事件在类型化 IPC 上的完整流动方式:[publish]/[subscribe]主题键如何同时充当强制 ACL 与路由声明、通配符*在四个匹配上下文中的不同语义,以及priority如何决定事件分发采用并发 fan-out 还是有序中间件链。读完本篇,你能正确编写工具胶囊的发布/订阅清单、设计需要顺序执行的策略层,并理解为什么加一个不同的 priority会悄悄改变整个匹配集合的分发模型。核心定位:内核只路由事件,tool 是胶囊空间的约定ipc.md 开篇给出的第一原则是:The kernel routes events; tool is a capsule-space convention over typed IPC.内核只负责路由事件。工具(tool)并不是内核级的一等概念,而是构建在类型化 IPC 之上的胶囊空间约定;Capsule.toml里的[publish]/[subscribe]键既是路由声明,也是被强制执行的发布/订阅 ACL。换句话说,主题键决定了谁能发、谁能收,而handler字段决定了收到后交给哪个导出函数。这一原则在仓库中有直接佐证:capsules/capsule-forge/src/lib.rs 中GUIDE_CHAPTERS把ipc一章注册为forge_guide工具的主题,摘要即为 tool flow, topics, ACL matching, handlers, fan-out, layering, and priority;而 capsules/capsule-router/Capsule.toml 里aos-router只声明主题键与 handler,不实现任何工具逻辑——工具执行的路由中间件本身就是内核路由、约定分层这一设计的实例。工具请求流:从模型选择到统一结果原文档给出的工具执行全链路是:model chooses foo - tool execute front door - router validates and publishes tool.v1.execute.foo - handler tool_execute_foo runs in the provider capsule - provider publishes tool.v1.execute.foo.result - router emits the unified result matched by call_id拆解这六步:模型选择工具foo;请求进入工具执行前门(tool execute front door);路由器(router)校验后发布tool.v1.execute.foo——注意这里发布的是具体主题,而不是通配主题;提供方胶囊里的tool_execute_foohandler 执行;提供方发布tool.v1.execute.foo.result;路由器按call_id匹配并吐出统一结果。对照 capsules/capsule-router/Capsule.toml 可以看到路由端的真实声明:它订阅tool.v1.request.execute(handlerhandle_execute_request)与tool.v1.execute.*.result(handlerhandle_execute_result),并发布tool.v1.execute.*与tool.v1.execute.result。结果回收依赖call_id匹配这一事实,意味着提供方与路由器之间是纯主题通信,不依赖任何带外通道。每个工具都需要一条具体的订阅(不能直接用通配占位):[subscribe] tool.v1.execute.foo { wit unicity-astrid/wit/types/tool-call, handler tool_execute_foo }其结果与 describe 响应则各需要一条发布 ACL:[publish] tool.v1.execute.*.result { wit unicity-astrid/wit/types/tool-call-result } tool.v1.response.describe.* { wit unicity-astrid/wit/tool/describe-response }这三条行(tool.v1.execute.tool订阅 两条 publish)是工具胶囊的强制接线,capsule-forge的 manifest lint 会把缺失它们当作 error 处理,具体见后文的仓库佐证。工具发现流:describe 请求与响应提示词构建(prompt construction)阶段会发布tool.v1.request.describe;每个胶囊由 SDK 宏生成的tool_describehandler 会在 describe 响应子树下发布自己的 schema 响应;提示词构建器随后收集并去重工具名。原文档对此给出的清单写法是只声明、不手写实现:[subscribe] tool.v1.request.describe { wit unicity-astrid/wit/tool/describe-request, handler tool_describe }响应由 SDK 宏发布。需要特别注意原文档的一句警告:A return-only describe path produces no fan-out response——如果你的 describe 路径只是函数返回而没有真正发布,就不会有扇出响应,工具对模型不可见。这也解释了 capsules/capsule-forge/src/lib.rs 中capsule_doctor诊断附带的DOCTOR_GUIDANCE:如果工具声明在 manifest 里但模型看不到,几乎一定是 manifest 问题——检查每个工具是否有自己的tool.v1.execute.tool订阅行和tool_execute_toolhandler,以及tool.v1.execute.*.result与tool.v1.response.describe.*是否在[publish]中。注释还指出:早期内核中启动后首次提示时 describe 扇出竞态导致工具偶发不可见的问题在当前内核已修复,因此现在看不到工具应指向真实的 manifest 缺陷,而不是内核竞态。通配符的四个匹配上下文:*不是一个语义原文档专门警告:不要假设*处处同义。四个上下文分别是:事件投递(event delivery):尾随*订阅整个主题子树。ACL 授权(ACL authorization):publish/subscribe 的模式授权匹配的主题;工具结果模式在.result前使用通配段(tool.v1.execute.*.result)。静态 handler 分发(static handler dispatch):段数必须匹配,一个通配段只匹配一个段。每个生成的工具 handler 都要有具体的 execute 行,而不是靠通配兜底。动态ipc::subscribe:最多接受一个通配符,且必须是尾随的;即便如此,manifest 里仍需要有覆盖该订阅的 ACL。安全语义上,两条底线:畸形或未声明的主题 fail closed——投递失败是安全默认;避免直接使用未校验的 LLM 字符串派生主题名。工具命名被刻意限制,使单个工具名无法注入额外主题段(否则会改变段数,从而绕过段数必须匹配的静态分发规则)。无 handler 订阅:仅为动态订阅预留权限[subscribe]中不带handler的条目只授予运行时创建动态订阅的权限,并不绑定任何组件导出。并且:无 handler 的条目不能设置priority——manifest 解析器会直接拒绝这种组合。这一约束在capsule-forge的 lint 逻辑中有对应检查,见下文的check_tool_bus:任何priority与缺失handler的组合都会产出 error 级 finding。priority 决定分发模型:fan-out 还是有序链priority是可选u32,数值越小越先执行,默认 100。原文档强调,它的行为比简单排序重要得多:若所有匹配 handler 的 priority相同(含全部缺省):运行时采用独立并发 fan-out。每个 handler 看到的是原始事件;某个兄弟 handler 返回Final、Deny、报错或改写载荷,都不会抑制或改写另一个兄弟 handler 的输入。若匹配集合中存在任何一个不同的 priority:整个匹配集合变成一个有序中间件链,handler 按 priority 升序执行。有序链内同优先级平局是确定性的:先比胶囊 ID,再比 action/handler 名。因此加入一个不同的 priority,可能把全部匹配 handler 从 fan-out 切换成链。原文档要求把这件事当作架构决策,而不是外观上的排序装饰。仓库里有一个现成的反面教材式正面示例:capsules/capsule-hook-adapter-oracle/Capsule.toml 的订阅表头注释明确写着:[subscribe] # Exactly one adapter owns each authenticated frontend topic. No priority is # set: these are protocol ingress points, not a middleware chain. oracle.v1.hook.validated.codex { wit opaque, handler on_codex_hook } oracle.v1.hook.validated.claude { wit opaque, handler on_claude_hook }即:协议入口点刻意不设 priority,保持独立 fan-out,而不是被误升级成中间件链。有序拦截器的结果语义(fail-open 陷阱)在有序链中,各 handler 的返回值语义如下:结果语义Continue(non_empty_payload)替换传给下一层的载荷Continue(empty_payload)保留当前载荷Final(payload)终止链并返回最终结果Deny { reason }以拒绝终止链NotSupported继续到下一层普通 handler 错误仅记录日志,链继续最后一条规则是中间件错误的fail-open:普通Err不会阻断链路。因此安全或策略层如果意图阻断某个动作,必须返回Deny,而不是Err。原文档同时要求:对策略层要同时测试它的决策结果和它在有序链中的位置——因为一个策略 handler 若被其他 handler 排错序,其Deny可能永远轮不到执行。如何选择 priority原文档的建议是:只有在确实需要载荷变换或可执行的顺序化策略路径时才使用 priority,并在胶囊源码中把预期阶段写清楚,例如:10 validate and normalize 20 enforce policy (return Deny on refusal) 50 enrich context 100 execute provider并明确反对:不要为了让日志看起来有序而分配不同的 priority——那会悄悄把彼此独立的订阅者变成中间件,改变 fan-out 语义。并发与 principal 作用域调用身份来自内核盖章的信封(kernel-stamped envelope),而不是 handler 自报。运行时按需要在每个胶囊 × 每个 principal维度串行化执行,避免可变状态变成跨 principal 的竞态;相应地,不要添加全局缓存去破坏这一隔离。动态接收在超时时返回Ok且消息集合为空——应检查集合是否为空,而不是去匹配错误字符串。在执行敏感副作用前,每条消息都要校验 source 与 principal。评审清单(Review checklist)原文档给出的七条评审检查项,可直接用于代码评审:每条 publish/subscribe 都声明了预期的 WIT 载荷;工具 execute handler 使用具体主题和生成的 handler 名(tool_execute_tool);结果与 describe 响应两条 ACL(tool.v1.execute.*.result、tool.v1.response.describe.*)齐备;动态订阅使用合法的尾随通配,且有 ACL 覆盖;fan-out 场景下 priority 缺省,中间件场景下有意错开;策略拒绝返回Deny而非普通错误;分层涉及安全时,测试覆盖变换后的载荷、终止行为、同优先级平局与 handler 失败。仓库佐证:checks.rs 如何强制这套接线ipc.md 的多数规则在 capsules/capsule-forge/src/checks.rs 的 manifest lint 中有可执行的对应实现,可作为文档规则 → 机器检查的映射:工具总线强制接线(check_tool_bus,checks.rs L222-L292):每条tool.v1.execute.tool订阅必须带非空handler;一旦出现任何工具 execute 订阅,tool.v1.execute.*.result与tool.v1.response.describe.*两条 publish 缺失即报 error,tool.v1.request.describe订阅缺失也报 error(tools wont be discoverable)。priority 校验(checks.rs L232-L252):priority无handler时报 error(Add a real handler binding or remove priority from the ACL-only subscription);priority 必须为整数且落在0..u32::MAX。对应的单元测试priority_requires_a_handler与priority_must_be_an_integer分别覆盖字符串10与浮点10.0两个非法形态。主题形状检查(check_topic_shapes,checks.rs L295-L316):空段(前导/尾随/连续点)报 error;超过 8 段的主题报 warn(deep topic trees usually indicate a naming error)——这与不要从 LLM 字符串直接派生主题名的安全建议一脉相承。capsule-forge的骨架生成器 capsules/capsule-forge/src/scaffold.rs 里scaffold_capsule产出的Capsule.toml模板,与 ipc.md 给出的最小工具接线完全一致:两个强制 publish 键、tool.v1.execute.hello具体订阅(handlertool_execute_hello)、以及tool.v1.request.describe(handlertool_describe)——即脚手架默认输出就是这套规则的合规样例。最后,capsule-forge的测试 ipc_manual_explains_priority_mode_switch_and_fail_open_errors 对本章内容本身做了回归断言,要求 ipc 章节必须持续包含四个关键表述:concurrent fan-out、ordered middleware chain、ordinary handler error is logged and the chain continues、must returnDeny, notErr。从源码结构看,作者把fan-out/有序链切换和fail-open 错误两条语义视为该指南不可丢失的核心论断。小结ipc.md 的核心结论可以浓缩为四句话:[publish]/[subscribe]的键是强制 ACL 兼路由声明;*在事件投递、ACL 授权、静态分发、动态订阅四个上下文里语义不同,未声明或畸形主题 fail closed;priority 相同即并发 fan-out,出现差异即整体转为有序中间件链,平局按胶囊 ID 再 handler 名确定性打破;策略层拒绝必须用Deny,因为普通 handler 错误在链上是 fail-open 的。对胶囊作者而言,最可操作的收尾就是按前文评审清单逐条过一遍 manifest,并用validate_manifest/capsule_doctor(见 capsules/capsule-forge/src/lib.rs)把常见接线错误在构建前暴露出来。赞分享【免费下载链接】aos-ceAOS Community Edition: the open agent operating system.项目地址https://gitcode.com/gh_mirrors/ao/aos-ce点击查看免费下载相关推荐aos-ce capsule-forge 的权限模型Agent 主动性、OS 授权、同意与激活的边界分离aos ce capsule forge 的权限模型Agent 主动性、OS 授权、同意与激活的边界分离 本文围绕 Unicity AOSaos ce 社区pyspider深度揭秘为什么这款带WebUI可视化调试的Python爬虫系统如此强大pyspider深度揭秘为什么这款带WebUI可视化调试的Python爬虫系统如此强大 pyspider 是一款功能强大的 Python 爬虫Web Cra网页爬虫后端任务调度如何安装DFlashuv、Docker、pip三大方式完整指南如何安装DFlashuv、Docker、pip三大方式完整指南 DFlash 是一款轻量的 块扩散Block Diffusion模型 专为 推测解码S人工智能大模型模型推理服务本地部署上一篇Office Custom UI Editor3步打造专属Office功能区工作效率提升300%下一篇终极指南如何用Office Custom UI Editor轻松打造专属办公界面创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考