首页/新闻资讯/正文详情

EMQX A2A Registry 命名空间格式化修复解析:HTTP API 中全局命名空间如何以 `null` 呈现

发布时间:2026/9/24 16:27:41 来源:云帆数科 栏目:资讯中心
EMQX A2A Registry 命名空间格式化修复解析:HTTP API 中全局命名空间如何以 `null` 呈现
后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载A2AAgent-to-AgentRegistry 是 EMQX 中用于注册、发现和检索 AI Agent 卡片的命名空间化存储能力。本文围绕变更记录 fix-17936.en.md 展开修复了 HTTP API 中属于全局命名空间的 A2A 卡片在返回时namespace字段被格式化为字符串global的问题现在统一以 JSON 的null呈现从而与具体命名空间明确区分。读完本文你将理解该修复的成因、card_out/1格式化函数的实现原理、相关 HTTP API 与 CLI 的完整行为以及测试用例如何固化这一契约。一、变更背景A2A Registry 与命名空间模型A2A Registry 是 EMQX 中面向 AI Agent 场景的注册表功能用于让 Agent 通过标准化的Agent Card代理卡片发布自身能力供其他 Agent 或上层编排系统发现和调用。在 emqx_a2a_registry 应用中可以找到其完整实现emqx_a2a_registry.erl — 核心存储与查询逻辑基于 EMQX 内置的 Retainer保留消息实现卡片的持久化emqx_a2a_registry_api.erl — 基于minirest_api的 HTTP 接口层emqx_a2a_registry_adapter.erl — 卡片输出格式化与注册错误归一化emqx_a2a_registry_cli.erl —emqx_ctl命令行入口。A2A 卡片通过**发现主题discovery topic**存储。从 emqx_a2a_registry_internal.hrl 可知-define(A2A_TOPIC_NS, $a2a). -define(A2A_TOPIC_V1, v1). -define(A2A_TOPIC_DISCOVERY, discovery).emqx_a2a_registry.erl 中discovery_topic/4展示了命名空间对主题的两种构造方式%% 全局命名空间$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id} discovery_topic(?global_ns, OrgId, UnitId, AgentId) - emqx_topic:join([?A2A_TOPIC_NS, ?A2A_TOPIC_V1, ?A2A_TOPIC_DISCOVERY, OrgId, UnitId, AgentId]); %% 特定命名空间{namespace}/$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id} discovery_topic(Namespace, OrgId, UnitId, AgentId) when is_binary(Namespace) - emqx_topic:join([Namespace, ?A2A_TOPIC_NS, ?A2A_TOPIC_V1, ?A2A_TOPIC_DISCOVERY, OrgId, UnitId, AgentId]).也就是说全局命名空间是一个特殊的系统级命名空间它不参与主题前缀而任何具体命名空间都会作为主题前缀出现。在 EMQX 的配置体系中全局命名空间常量定义在 emqx_config.hrl-define(global_ns, global).即global_ns就是原子global——这正是问题产生的地基。二、问题描述字符串global带来的歧义变更记录原文指出Fixed the formatting of A2A cards belonging to the global namespace in the HTTP API. Previously, they would show as the stringglobal. Now, they are formatted asnullto distinguish them from specific namespaces.修复了 HTTP API 中属于全局命名空间的 A2A 卡片格式化问题。此前它们会显示为字符串global现在格式化为null以便与具体命名空间区分。为什么字符串global是有问题的从 emqx.erl 的注释可以印证global原子作为?global_ns使用时会产生歧义produce ambiguous。具体来说JSON 语义歧义客户端无法从namespace: global判断这究竟表示全局命名空间这一特殊标记还是表示一个恰好名为global的具体命名空间数据建模问题全局命名空间并不是一个真实存在的命名空间名称将其序列化为普通字符串会污染数据的语义边界过滤与匹配歧义调用方若基于namespace字段做筛选或去重字符串global与真实命名空间global无法区分。因此修复的目标是全局命名空间的卡片在 API 输出中namespace字段必须为null而具体命名空间仍输出其名称字符串。三、修复实现card_out/1格式化函数的源码级解析修复的核心落在 emqx_a2a_registry_adapter.erl 的card_out/1card_out(Card) - emqx_utils_maps:update_if_present( namespace, fun (?global_ns) - null; (Ns) - Ns end, Card ).其逻辑非常清晰仅当卡片 map 中存在namespace字段时update_if_present才进行转换若该字段的值等于?global_ns即原子global则替换为null其他任何值具体命名空间的二进制字符串原样保留。这里null是 Erlang 的原子在 JSON 编码时会被序列化为 JSON 的null而非字符串。这正是与global字符串在 JSON 层面的本质区别。3.1 调用链API 响应如何走到card_outcard_out/1在 HTTP API 的每个读取路径上都被调用见 emqx_a2a_registry_api.erl列表接口handle_list_cards/2第 269-277 行?OK(lists:map(fun card_out/1, Cards))对每张卡片逐一格式化单卡查询handle_get_card/2第 279-289 行命中后?OK(card_out(Card))。API 输出字段定义在fields(card_out)第 150-159 行包括namespace、id、name、version、description、statusonline/offline和raw原始卡片 JSON。其中status由 emqx_a2a_registry.erl 的lookup_agent_status/1根据客户端在线状态动态计算。3.2 CLI 同样受益修复并不仅限于 HTTP API。emqx_ctl命令a2a_registry list/get同样通过emqx_a2a_registry_adapter:card_out/1输出结果见 emqx_a2a_registry_cli.erl 与 第 109 行。因此通过 CLI 查询全局命名空间卡片时namespace也会呈现为null保证两种管理入口的语义一致。四、行为验证测试用例如何固化契约该修复的行为被 emqx_a2a_registry_api_SUITE.erl 的 CRUD 冒烟测试显式断言。在非命名空间即全局场景下?assertMatch({200, #{namespace : _}}, get_card(?ORG_ID, ?UNIT_ID, ?AGENT_ID, TCConfig)), maybe false ? get_config(namespaced, TCConfig, false), ?assertMatch({200, [#{namespace : null}]}, list_cards(#{}, TCConfig)), ?assertMatch( {200, #{namespace : null}}, get_card(?ORG_ID, ?UNIT_ID, ?AGENT_ID, TCConfig) ) end,两个关键断言list_cards(#{})不带命名空间时等价于全局命名空间返回的列表元素中namespace : nullget_card(...)单卡查询返回namespace : null。同时测试矩阵t_crud/1覆盖了?no_namespace与?namespaced两种配置第 193-194 行确保命名空间化场景下namespace仍能正确输出具体值第 206 行仅断言namespace : _存在。这组用例从正反两个方向锁定了全局为null、具体命名空间为字符串的行为契约。五、实际使用HTTP API 与命名空间解析5.1 接口总览API 由 emqx_a2a_registry_api.erl 的paths/0声明命名空间前缀为a2a方法路径说明GET/a2a/cards/list列出卡片支持org_id、unit_id、agent_id、ns、only_global查询参数GET/a2a/cards/card/:org_id/:unit_id/:agent_id查询单张卡片POST/a2a/cards/card/:org_id/:unit_id/:agent_id注册/更新卡片请求体为{card: {...}}DELETE/a2a/cards/card/:org_id/:unit_id/:agent_id删除卡片其中:org_id、:unit_id、:agent_id三个路径段均须匹配段 ID 正则^[A-Za-z0-9._-]$见 emqx_a2a_registry_cli.erl类型定义见 emqx_a2a_registry_types.erl。5.2ns查询参数与全局过滤命名空间通过ns查询参数传入。在/a2a/cards/list的处理逻辑第 243-250 行中/a2a/cards/list(get, #{query_string : QueryParams} Req) - Namespace0 get_namespace(Req), Namespace case maps:get(only_global, QueryParams, false) of false when Namespace0 ?global_ns - all; _ - Namespace0 end, handle_list_cards(Namespace, QueryParams).值得注意的细节请求方未指定命名空间Namespace0 ?global_ns且未设置only_globaltrue时Namespace被置为all此时 emqx_a2a_registry.erl 会同时用全局与通配命名空间两条主题过滤匹配即默认列出全部命名空间的卡片请求方显式设置only_globaltrue时仅列出全局命名空间的卡片——这类卡片的namespace字段在响应中即为null传入具体ns时仅匹配该命名空间下的卡片其namespace字段输出为对应字符串。5.3 命名空间权限校验与审计在 filter/2 中每个请求都会先经resolve_namespace/2解析目标命名空间若请求方自身处于具体命名空间ActorNamespace / ?global_ns却试图用ns参数操作其他命名空间则返回 403not_authorized第 426-442 行若是受管命名空间还需通过namespace.resource_pre_create钩子确认其存在第 454-465 行否则返回 400 Managed namespace not found。修复还联动优化了审计日志log_ns/1第 447-452 行在请求全局命名空间卡片时向minirest_handler的日志元数据写入namespace global弥补了仅凭 URL 无法区分全局卡片与命名空间卡片的审计盲区代码注释中明确关联了同类问题 emqx/emqx#18653。5.4 响应示例修复后全局命名空间卡片的典型响应如下namespace为null{ namespace: null, id: my.org:my.unit:my.agent, name: some_agent, version: 1, description: description, status: online, raw: {...} }而具体命名空间如my-ns下卡片的响应则为namespace: my-ns。六、前置条件与配置A2A Registry 依赖 EMQX 的 Retainer保留消息功能因为卡片正是以保留消息形式存储在$a2a/v1/discovery/...主题上。若 Retainer 未启用所有接口会返回 404 并附带提示信息见 emqx_a2a_registry_api.erlA2A registry requires the retainer feature. Enable retainer under Retained Messages in the Dashboard, or setretainer.enable truein the configuration.相关开关配置路径由 emqx_a2a_registry_config.erl 定义is_enabled() - emqx_config:get([a2a_registry, enable], false). is_schema_validation_enabled() - emqx_config:get([a2a_registry, validate_schema], true).a2a_registry.enable功能总开关默认false。关闭时 HTTP 接口统一返回 503 Not enabled见 filter/2CLI 命令同样拒绝执行见 emqx_a2a_registry_cli.erla2a_registry.validate_schema注册卡片时是否按 agent_card_schema.json 做 schema 校验默认true。卡片注册时的错误信息也由 emqx_a2a_registry_adapter.erl 统一格式化例如Bad org_id id: xxx、Card does not conform to schema、Namespace not found: xxx等分别对应 400 或 500 响应。七、总结本次修复对应 fix-17936.en.md从数据语义层面消除了 A2A Registry HTTP API 的一个歧义点行为变化全局命名空间卡片的namespace字段由字符串global改为 JSONnull具体命名空间仍输出字符串实现落点card_out/1emqx_a2a_registry_adapter.erl作为唯一格式化出口同时作用于 HTTP API 与 CLI 查询路径保证语义一致契约固化emqx_a2a_registry_api_SUITE.erl 以断言形式锁定了全局返回null的行为防止回归。对于基于 EMQX 构建 Agent 生态的开发者而言理解这一约定至关重要在消费/a2a/cards/list或/a2a/cards/card/:org_id/:unit_id/:agent_id的响应时应以namespace null判定全局命名空间卡片而非字符串global从而避免与真实命名为global的命名空间混淆。赞分享后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载相关推荐EMQX A2A Registry HTTP API 命名空间隔离机制深度解析EMQX A2A Registry HTTP API 命名空间隔离机制深度解析 A2AAgent to AgentRegistry 是 EMQX 提供的智能后端物联网消息队列通信TypeSpec 全局命名空间场景解析typespec/http-client-js 如何为无顶层命名空间的规范生成 TypeScript 客户端TypeSpec 全局命名空间场景解析typespec/http client js 如何为无顶层命名空间的规范生成 TypeScript 客户端 本文基于编程语言编译器后端Slate v2 API Helper 命名空间重命名以 *Api 后缀消除 DOM 全局变量遮蔽Slate v2 API Helper 命名空间重命名以 Api 后缀消除 DOM 全局变量遮蔽 导读 本文基于仓库中的 Slate v2 Api Helpe前端富文本UI组件上一篇Sendwithus邮件模板安全性分析Apache 2.0许可证下的最佳实践下一篇终极指南如何使用GoSumemory打造专业级osu!游戏直播效果 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

主库宕机,切换要30秒?业务全挂!我手搓了人大金仓“秒级故障转移”高可用集群,附Java应用防抖终极指南
主库宕机,切换要30秒?业务全挂!我手搓了人大金仓“秒级故障转移”高可用集群,附Java应用防抖终极指南

摘要:本文基于人大金仓 KingbaseES V9,从物理层、数据库层、应用层三道防线,详解企业级高可用集群的部署与 Java 应用端“秒级无感”故障转移方案。目标读者为 DBA、运维工程师及 Java 后端开发者。阅读后可掌握 Keepalived VIP 漂移、同步流复制、防脑裂探针及 HikariCP 多… · 2026/9/24 16:27:41

从 Yii 1.1 升级到 Yii 2:Yii2 框架全面重写后的迁移指南与核心架构变迁解析
从 Yii 1.1 升级到 Yii 2:Yii2 框架全面重写后的迁移指南与核心架构变迁解析

后端Web框架 【免费下载链接】yii2 Yii 2: The Fast, Secure and Professional PHP Framework 项目地址: https://gitcode.com/gh_mirrors/yi/yii2 点击查看 免费下载 Yii 2.0 是相对 1.1 的完全重写版本,二者之间的差异远非一次简单的"小版本升级… · 2026/9/24 16:27:41

锂电池阳极材料市场迎增长机遇 2025年销售额94.28亿、2032年望达248.3亿
锂电池阳极材料市场迎增长机遇 2025年销售额94.28亿、2032年望达248.3亿

一、全球锂离子电池阳极材料市场规模与核心基本面据权威产业统计数据,2025年全球锂离子电池阳极材料市场销售额已达到94.28亿美元,预计2032年将攀升至248.3亿美元,2026-2032年复合年均增长率高达14.0%,是整个锂电核心材料赛道中需… · 2026/9/24 16:27:34

第24篇-MCP-Client架构-Host应用如何管理多个Server连接
第24篇-MCP-Client架构-Host应用如何管理多个Server连接

【MCP 全栈教程】第 24 篇:MCP Client 架构——Host 应用如何管理多个 Server 连接 本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。… · 2026/9/24 17:01:59

第21篇-MCP-Server测试-MCP-Inspector与自动化测试
第21篇-MCP-Server测试-MCP-Inspector与自动化测试

【MCP 全栈教程】第 21 篇:MCP Server 测试——MCP Inspector 与自动化测试 本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。 本篇你… · 2026/9/24 17:01:59

OneNote 笔记如何备份才不丢数据:3 种方案完整保姆级攻略
OneNote 笔记如何备份才不丢数据:3 种方案完整保姆级攻略

OneNote 笔记如何备份才不丢数据:3 种方案完整保姆级攻略 【免费下载链接】cs-408 计算机考研专业课程408相关的复习经验,资源和OneNote笔记 项目地址: https://gitcode.com/GitHub_Trending/cs/cs-408 用 OneNote 攒了几个月笔记,某次… · 2026/9/24 17:01:59

使用 AWS SDK for C++ 编写 Hello SNS:通过 ListTopics 入门 Amazon SNS
使用 AWS SDK for C++ 编写 Hello SNS:通过 ListTopics 入门 Amazon SNS

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/24 17:01:53

pip 的 towncrier 变更日志模板解析:从 news fragment 到 NEWS.rst 的渲染机制
pip 的 towncrier 变更日志模板解析:从 news fragment 到 NEWS.rst 的渲染机制

包管理器开发工具 【免费下载链接】pip The Python package installer 项目地址: https://gitcode.com/gh_mirrors/pi/pip 点击查看 免费下载 本篇技术指南围绕 pip 仓库中维护变更日志的核心模板文件 tools/news/template.rst 展开,系统讲解 pip 如何基… · 2026/9/24 17:01:53

Visual Explainer Quick 模式深度指南:用紧凑 JSON Spec 一键渲染自包含 HTML 可视化页面
Visual Explainer Quick 模式深度指南:用紧凑 JSON Spec 一键渲染自包含 HTML 可视化页面

【免费下载链接】visual-explainer Agent skill that generates rich HTML pages or slide decks for diagrams, diff reviews, plan audits, data tables, and project recaps 项目地址: https://gitcode.com/gh_mirrors/vi/visual-explainer 点击查看 免费下载 Q… · 2026/9/24 17:01:53

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码