Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/edgeflow-adapter-developer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ description: 新增或修改 LLM-EdgeFlow Adapter 的业务输入输出、InputC
| --- | --- |
| 请求校验、字段选择与内部 payload | `src/adapter/input/`,`InputConverterDefinition` + `REGISTER_INPUT_CONVERTER` |
| 完整响应组装、序列化和拷贝 | `src/adapter/output/`,`OutputConverterDefinition` + `REGISTER_OUTPUT_CONVERTER` |
| 新业务边界与连接 | `src/adapter/biz/`,`BizDefinition` 声明 ingress/egress;`IoBindingDefinition` + `REGISTER_IO_BINDING` 选择转换器;批次上限默认 64,只有实测确需更小值时才覆盖;同名端口自动映射,只写不同名的映射 |
| 新业务边界与连接 | `src/adapter/biz/`,`BizDefinition` 声明 ingress/egress;`IoBindingDefinition` + `REGISTER_IO_BINDING` 选择转换器;批次上限默认 64,只有实测确需更小值时才覆盖;转换器端口名即业务键,绑定不做改名 |
| 确需新的宿主值类型/分配方式 | `include/adapter/operator_value_type.h`,按 [输出分配指南](../../../doc/dev_guide/operator_output_allocation.md) 注册 |

从 [翻译输入](../../../src/adapter/input/translate_json_input.cpp)、
Expand Down
2 changes: 1 addition & 1 deletion configs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Validator 从输入数据的唯一生产者推导依赖,`depends_on` 仅用于
## 业务入口与输出配置

每份 Pipeline 显式填写 `deployment.io.io_binding`,它决定外部 C 结构体与内部数据的转换契约。
框架从注册关系获得业务边界、输入/输出转换器、端口映射和输出类型,不靠文件名或后缀猜测。
框架从注册关系获得业务边界、输入/输出转换器、端口和输出类型,不靠文件名或后缀猜测。
Demo 根据配置自动选取运行入口,Profile 只保存配置路径、数据集和执行参数。
同一业务的多个 binding 必须声明一致的外部协议、载体和有效槽位,注册审计及部署预检都会校验。

Expand Down
15 changes: 12 additions & 3 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## Unreleased

转换器回调去掉 `InputPortBindings` / `OutputPortBindings` 参数:`DecodeInputFn` / `EncodeOutputFn`、
`DecodeRequestRows`、`EncodeResultRows` 与 `ReadOutputValue` 直接使用端口常量读写 `AlgContext`。
写入未声明端口不再被静默发布到空键名。

删除 IoBinding 的端口改名映射(`input_ports` / `output_ports`、`BindIoPort`、`EffectivePortMapping`):
转换器逻辑端口名即业务 Blackboard Key,注册审计直接按端口名核对业务出入口与类型;Catalog 与
`validate-io` 不再输出 `*_port_mapping`。业务接入指南补充端口命名约定。Pipeline JSON 不变。

对话合规审核的输出 Converter 直接使用业务出口键 `matched_policy`,删除只为改名存在的
`kMatchedPolicies`(`matched_policies`)及其 Binding 端口映射;Pipeline 配置与外部契约不变。

Converter 定义精简(不涉及 Operator ABI、Pipeline JSON 与 `.conf`):删除没有运行时作用的
`schema_version`、`external_type`、输出 `cardinality` 与 `capacity_policy`,以及槽位的 `value_type` 与
`capacity_fields`。输出槽容量字段只由 ValueType 决定,`ExternalInputSlot` / `ExternalOutputSlot`
Expand All @@ -24,8 +35,7 @@ Converter 定义精简(不涉及 Operator ABI、Pipeline JSON 与 `.conf`)
- Model 继承 `ModelIdentity<Model, 能力接口>`、Backend Provider 继承 `BackendIdentity<Backend>`,
身份只声明一次,Definition 从 `MakeModelDefinition` / `MakeBackendDefinition` 开始;
配置读取使用 `ConfigValueOrDefault`,默认值只写在 `config_fields`。
- `InputPortBindings` / `OutputPortBindings` 共用 `PortBindings<方向>`;`ResolvedInputLimits`
更名为 `InputLimits` 且不再出现在部署配置中。
- `ResolvedInputLimits` 更名为 `InputLimits` 且不再出现在部署配置中。
- 删除 `include/adapter/biz_results.h`、`ModelManager::RegisterModel`(改用 `RegisterBatch`)和
`RuntimeOptions` 中只写不读的 `biz_type`、`depth_num`、`biz_name`;`NodeBase` 的类写法端口辅助
函数移到 `dev_support` 的 `LegacyNodeBase`。
Expand Down Expand Up @@ -105,7 +115,6 @@ Pipeline 配置格式保持不变。
声明一次:转换器的 `max_batch_size` 默认改为 0(不设限),有效上限取绑定与两个转换器中正值的
最小值,三者显式为 0 时注册审计和部署准备报错。Binding 现默认使用框架标准批次上限 64,
只有实测确需更小值时才覆盖 `max_batch_size`。
绑定的 `input_ports` / `output_ports` 可以省略同名映射,需要完整映射的代码改用 `EffectivePortMapping`。
`ValidateDecodeRequest`、`DecodeRequestRows` 删除批次上限参数,改读 Operator 填入的
`InputDecodeOptions::max_batch_size`。Catalog 中生产转换器的 `max_batch_size` 由 64 变为 0;各业务的
有效批次上限、Pipeline 配置格式与公共 Operator ABI 不变。
Expand Down
2 changes: 1 addition & 1 deletion doc/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Demo 不得提前拆解请求或在 SDK 返回后补组业务响应;内部节

- 标准 C++ Operator API(`llm_edgeflow::operator_api`)为唯一公开算法接口,承诺 6 个导出符号(3 个 Operator API 函数与 3 个 AlgBase 日志函数)。Node、Registry、Model、Backend 及第三方运行时符号使用 hidden visibility,不构成稳定动态 ABI。
- 同一 handle 的 `Process` 与 `Control` 串行执行;不同 handle 可并行。`Destroy` 前调用方必须停止提交并等待该 handle 上所有调用返回,释放全部输出指针引用,返回后句柄永久失效。`DeInit` 清理全局登记的所有 handle,调用前须对所有实例完成同样的停流与释放;完整规则见[宿主调用与生命周期](dev_guide/operator_output_allocation.md#宿主调用与生命周期)。
- C++ Operator API 根据 Key 的最后一个点号解析外部槽位的 `key_suffix`;槽位的 `type_suffix` 再选择 `OperatorValueTypeRegistry` 中的外部 C++ 类型。不同槽位后缀可以复用同一类型。`IoBindingRegistry` 负责将转换器的逻辑端口映射到内部 Pipeline 端口,具体区别见[输出分配方案](dev_guide/operator_output_allocation.md)。
- C++ Operator API 根据 Key 的最后一个点号解析外部槽位的 `key_suffix`;槽位的 `type_suffix` 再选择 `OperatorValueTypeRegistry` 中的外部 C++ 类型。不同槽位后缀可以复用同一类型。`IoBindingRegistry` 负责关联转换器与业务契约,转换器逻辑端口名即内部 Pipeline 的 Blackboard Key,具体区别见[输出分配方案](dev_guide/operator_output_allocation.md)。
- 组件调用关系:`外部调用方 → Operator → Pipeline → Node → Model → Backend → Platform`。
`Operator` 表达对外交付的算法实例,`Platform`(`ComputePlatform`)表达底层硬件执行平台(CPU、CUDA、AX650、Ascend 等)。
- 同一业务可以使用一个聚合结构槽位,也可以由多个原子槽位组成;支持多槽位解绑。
Expand Down
2 changes: 1 addition & 1 deletion doc/architecture_flow.puml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ package "创建期:接入准备与统一校验" {
artifact "PreparedDeployment\n中性 Pipeline JSON + PipelineIoBoundary" as Prepared
component "PipelineValidator\n显式 DAG / 类型端口 / 并发写冲突" as Validator
artifact "ValidatedPipelinePlan" as PipelinePlan
artifact "ValidatedIoPlan\nI/O Definition 与端口映射\n输出池规格 + Pipeline 计划" as IoPlan
artifact "ValidatedIoPlan\nConverter 选择与 I/O 边界\n输出池规格 + Pipeline 计划" as IoPlan
}

package "运行期:C++ Operator SDK" {
Expand Down
4 changes: 2 additions & 2 deletions doc/assets/architecture_flow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 16 additions & 14 deletions doc/dev_guide/business_onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
| `InputConverterDefinition::decode_fn` | 校验外部请求、解析完整载荷、选择业务字段,转换为请求内的中性值发布至 `AlgContext` |
| Pipeline / Nodes | 对内部 typed ports 的数据执行算法;可解析模型生成的结构化内容,不承担外部协议转换 |
| `OutputConverterDefinition::encode_fn` | 从 `AlgContext` 读取中性结果,按外部契约组装序列化响应并写入已租用输出池 |
| `IoBinding` | 声明业务逻辑端口与 Pipeline Blackboard Key 的映射关系,将转换器与业务编排关联 |
| `IoBinding` | 选择输入/输出转换器并关联业务契约;转换器端口名即 Pipeline Blackboard Key |

Demo 输出里的日志、统计和展示字段可以另行组织,但不能为 SDK 补做业务字段提取、
字段改名、响应组装或默认成功结果。宿主程序直接调用 Operator SDK 就应获得约定响应。
Expand Down Expand Up @@ -56,7 +56,7 @@ Catalog 的 ingress/egress 是转换器与 Pipeline 之间的内部逻辑端口
“结构体布局相同”不等于“业务契约相同”:同一个 `const char*` 承载纯文本与承载完整
JSON 请求是不同的输入约定。已有 Nodes 能完成算法,也不代表转换器已支持新协议。

当前共享 SDK 的 Operator 初始化会全量审计**所有已注册的绑定**:转换器、端口映射、
当前共享 SDK 的 Operator 初始化会全量审计**所有已注册的绑定**:转换器、端口、
业务契约和批次上限必须完整一致,任何一个绑定不合格,SDK 全局初始化都会失败。
业务能否部署取决于是否注册了绑定;配置引用不存在的绑定时,部署准备报 `UNKNOWN_IO_BINDING`。

Expand Down Expand Up @@ -86,13 +86,13 @@ JSON 请求是不同的输入约定。已有 Nodes 能完成算法,也不代
| 内部数据边界 | [业务 key](../../include/adapter/biz_blackboard_keys.h)、[中性结果类型](../../include/core/common_contracts.h) | ingress/egress typed key 与 Pipeline 产出的中性结果;已有类型可复用,外部响应由输出转换器组装 |
| 输入转换器 | [text_input.cpp](../../src/adapter/input/text_input.cpp) | 外部输入校验、中性数据封装及 `REGISTER_INPUT_CONVERTER` |
| 输出转换器 | [keyword_result_output.cpp](../../src/adapter/output/keyword_result_output.cpp) | 内部结果关联、写入已分配的输出结构及 `REGISTER_OUTPUT_CONVERTER` |
| 业务契约与绑定 | [keyword_match_bindings.cpp](../../src/adapter/biz/keyword_match_bindings.cpp) | 声明 `BizDefinition`、转换器组合和非同名端口映射;默认批次上限为 64,用 `REGISTER_IO_BINDING` 注册 |
| 业务契约与绑定 | [keyword_match_bindings.cpp](../../src/adapter/biz/keyword_match_bindings.cpp) | 声明 `BizDefinition` 与转换器组合;默认批次上限为 64,用 `REGISTER_IO_BINDING` 注册 |
| Operator 类型注册(仅新宿主类型) | [operator_builtin_value_types.cpp](../../src/adapter/operator/operator_builtin_value_types.cpp) | 复用已注册类型时无需改动;新宿主类型见[实现与注册](operator_output_allocation.md#实现与注册) |
| Demo 数据转换 | [keyword_match_demo.cpp](../../demo/biz/keyword_match_demo.cpp) | 为新绑定补充 `REGISTER_DEMO_BIZ`;已有运行代码无法表达载体或数据集格式时,再实现输入构造与输出复制 |
| 构建与部署 | [Pipeline](../../configs/pipeline_keyword_match_rules.json)、[部署配置](../../configs/pipeline_keyword_match_rules.conf) | 新增 `.cpp` 自动编入;编排业务端口,配置路径和输出容量 |

配置作者只选择 `io_binding`(`keyword_match.operator.v1`)。它关联注册的内部业务边界、
输入/输出转换器和端口映射;Demo 从配置自动选择运行入口。Operator 槽位后缀
配置作者只选择 `io_binding`(`keyword_match.operator.v1`)。它关联注册的内部业务边界
和输入/输出转换器;Demo 从配置自动选择运行入口。Operator 槽位后缀
(`keyword_in` / `keyword_out`)属于宿主调用契约,由绑定关联到已注册宿主类型。

## 3. 实现并注册转换器与绑定
Expand Down Expand Up @@ -129,8 +129,7 @@ JSON 请求是不同的输入约定。已有 Nodes 能完成算法,也不代
调用 `PipelineCatalog::RegisterBizDefinition` 登记;业务端口契约不由转换器读写集合推导。
在 `IoBindingDefinition` 中指定 `binding_id`、`biz_name`、`input_converter_id`、
`output_converter_id`,使用 `REGISTER_IO_BINDING` 注册。
转换器的逻辑端口默认映射到同名的 Blackboard Key,`input_ports` / `output_ports`
只写不同名的映射。
转换器的逻辑端口名就是 Blackboard Key,绑定不做改名;命名遵循本节后文的端口命名约定。
Binding 的批次上限默认为框架标准值 64,只有实测确需更小值时才覆盖 `max_batch_size`;
转换器只在自身确有限制时才声明上限,0 表示不设限。
有效上限取绑定与两个转换器中正值的最小值,Operator 再按实际输出池深收紧;
Expand All @@ -143,12 +142,15 @@ JSON 请求是不同的输入约定。已有 Nodes 能完成算法,也不代
Operator 的宿主输入校验会拒绝 `CompanyString` 中的原始嵌入 NUL;JSON 文本中的
`\u0000` 转义仍可在解包后成为内部字符串的一部分。

共享端口用 `MakeBlackboardKey<T>(name)` 定义一次;转换器 Definition 使用
`RequiredInputPort(port)` / `OutputPort(port)`,回调通过 `bindings.Key(port)`
读取或发布。同名端口在绑定中无需声明;非同名映射使用
`BindIoPort(logical_port, actual_key)`,两端的 C++ 类型必须一致。例如审核输出使用
`BindIoPort(kMatchedPolicies, kMatchedPolicy)`,不能直接绕过绑定读写实际 key。
需要完整映射的代码调用 `EffectivePortMapping`,不要直接读取绑定的端口表。
共享端口用 `MakeBlackboardKey<T>(name)` 在 `adapter/biz_blackboard_keys.h` 定义一次;转换器
Definition 使用 `RequiredInputPort(port)` / `OutputPort(port)`,回调直接用同一端口常量读写
`AlgContext`。转换器端口名就是业务出入口的 Blackboard Key,绑定不做改名。端口命名约定:

- 同一业务内同名即同一份数据、同一类型;复用已定义的常量,不重复手写字符串。
- 可被多个业务复用的转换器使用中性、按角色命名的端口(如 `input_sentences`、`llm_answers`),
不使用业务专属名称;其他业务复用它时沿用这些名字。
- 输入侧与输出侧的端口不重名;只有输出转换器有意回传请求数据时才读取入口键。
- 业务专属转换器直接使用业务键名,例如审核输入的 `user_texts`、`channel_names`。

外部必需槽的常见写法是 `ExternalInputSlot<T>(slot)` 和
`ExternalOutputSlot<T>(slot)`,类型由 traits 推导。
Expand All @@ -164,7 +166,7 @@ Operator 的宿主输入校验会拒绝 `CompanyString` 中的原始嵌入 NUL
| 规则匹配 | [关键词输入](../../src/adapter/input/text_input.cpp) / [关键词输出](../../src/adapter/output/keyword_result_output.cpp) | 命中与业务状态 |
| 完整 JSON 请求响应 | [翻译输入](../../src/adapter/input/translate_json_input.cpp) / [翻译输出](../../src/adapter/output/translation_json_output.cpp) | JSON 字段与响应协议 |
| 可选字段、三路结果 | [文档输入](../../src/adapter/input/doc_query_input.cpp) / [文档输出](../../src/adapter/output/doc_answer_output.cpp) | 文档缺省、回答/意图/片段数关联 |
| 风险判定、非同名端口 | [审核输入](../../src/adapter/input/audit_input.cpp) / [审核输出](../../src/adapter/output/audit_result_output.cpp) | 风险分数/枚举与排名校验 |
| 风险判定、排名首项 | [审核输入](../../src/adapter/input/audit_input.cpp) / [审核输出](../../src/adapter/output/audit_result_output.cpp) | 风险分数/枚举与排名校验 |
| 音频、两路结果 | [音频输入](../../src/adapter/input/audio_input.cpp) / [音频输出](../../src/adapter/output/audio_result_output.cpp) | PCM 与采样率、转写/意图组合 |
| 多个外部槽 | [图像问题输入](../../src/adapter/input/image_query_input.cpp) / [票据输出](../../src/adapter/output/invoice_result_output.cpp) | frame 的请求 ID、票据与 OCR boxes |
| 候选展开与排名 | [重排输入](../../src/adapter/input/rerank_input.cpp) / [重排输出](../../src/adapter/output/rerank_result_output.cpp) | sub_id、排名和原始索引恢复 |
Expand Down
4 changes: 2 additions & 2 deletions doc/dev_guide/source_layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ src/adapter/
常见单槽、每请求一行的回调使用 `DecodeRequestRows` / `EncodeResultRows` 调用普通业务函数,
批次与绑定归辅助层;多槽、展开和汇聚保留显式算法。
各业务接入绑定在 `src/adapter/biz/` 中声明 `IoBindingDefinition`,通过 `REGISTER_IO_BINDING` 注册。
端口 Definition、回调的 `bindings.Key(port)` 和 `BindIoPort` 映射共用 typed 声明;
非同名映射显式传入逻辑端口与实际 key。常见必需槽可用 `ExternalInputSlot<T>` /
端口 Definition 与回调共用同一 typed 端口常量,端口名即业务键名,
绑定不做改名。常见必需槽可用 `ExternalInputSlot<T>` /
`ExternalOutputSlot<T>` 推导类型和默认同名后缀,输出容量字段由已注册 ValueType 决定;
特殊布局仍使用完整定义。
业务专属实现可按修改关联同文件组织,共享 converter 保留独立引用;不要求为每个业务创建聚合宏或新注册表。
Expand Down
6 changes: 3 additions & 3 deletions doc/developer_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ Backend;出现调度、模型语义或硬件能力缺口时,再查阅相应

C++ `NamedIoBatch` 是算法的公开 Process 边界。`OperatorValueTypeRegistry` 注册
外部类型、规范后缀及校验/分配生命周期;`InputConverter` 负责读取和深拷贝完整请求,
`OutputConverter` 使用 Create 期输出池组装完整响应。`IoBindingDefinition` 声明业务、
转换器、逻辑槽位与内部端口映射,注册审计检查类型和契约一致性。
`OutputConverter` 使用 Create 期输出池组装完整响应。`IoBindingDefinition` 声明业务与
转换器,注册审计检查端口、类型和契约一致性。

`CompanyString` 按 `length` 表达文本;Operator 输入校验拒绝原始嵌入 NUL,JSON 中
转义的 NUL 可在解包后保留。输出按显式长度复制,二进制内容使用 `CompanyBuffer`。
Expand Down Expand Up @@ -81,7 +81,7 @@ CrossRerank 的排名数组和 Compliance 的首项选择使用 `N:1 / aggregate
`AdapterValidationHelper` 完成批次、指针和长度校验,发布中性数据至 `AlgContext`。
3. 在 `src/adapter/output/` 实现 `OutputConverter`,完成输出结构租约组装与容量检查。
4. 在 `src/adapter/biz/` 声明 `BizDefinition` 并实现 `IoBinding` 绑定:选择转换器、
批次上限默认为框架标准值 64,只有实测确需更小值时才覆盖;逻辑端口默认映射到同名 Blackboard Key,只写不同名的映射。
批次上限默认为框架标准值 64,只有实测确需更小值时才覆盖;转换器逻辑端口名即 Blackboard Key,绑定不做改名。
5. 解码与编码使用 `core/common_contracts.h` 中的中性值类型,并在
`adapter/biz_blackboard_keys.h` 集中声明业务 ingress/egress `BlackboardKey<T>`;
Core、Node 和 Engine 不得包含该业务 key 头。
Expand Down
3 changes: 0 additions & 3 deletions include/adapter/biz_blackboard_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ inline constexpr auto kStructuredVerdicts =
MakeBlackboardKey<StructuredDocumentBatch>("structured_verdicts");
inline constexpr auto kMatchedPolicy =
MakeBlackboardKey<RankedTextBatch>("matched_policy");
// 输出 Converter 的逻辑端口名与业务 Blackboard 键不同。
inline constexpr auto kMatchedPolicies =
MakeBlackboardKey<RankedTextBatch>("matched_policies");
inline constexpr auto kImagePaths =
MakeBlackboardKey<ImageRefBatch>("image_paths");
inline constexpr auto kUserQueries =
Expand Down
Loading
Loading