# Agent Note: 简化 Web 图片输入第一版

Status: implemented

[English](2026-07-29-simplify-web-image-input-v1.md) | 中文

## 问题

首个持久化 Web 图片输入切片在引入按顺序接收多张图片的必需能力时，也引入了由 CLI（命令行界面）挂载任意提供方、输出模态发现、替代文本、提供方无关的视觉 token 定价，以及没有跨包（package）消费方的浏览器生命周期 API 等推测性表面。保留这些推测性表面会把尚未选择的未来行为变成公共契约，并使初始能力更难评审和维护。

## 决策

第一版接受有序图片批次，并以可配置的每条消息图片数量与图片总字节数上限，以及单张图片字节数与像素上限约束批次。浏览器会在分配预览前拒绝声明不支持的格式，而宿主会以权威方式解码完整批次、检查当前部署上限、在不写入存储的情况下校验每张图片，之后才保存每张图片，并在生成的持久图片块中保留提交顺序。请求缓冲上限直接由附件服务的图片总字节数上限派生。这样无需添加批次事务、回滚协议或 `host.describe` 中的策略快照，就能保持校验的原子性。

提供方／模型选择仍属于配置和 profile 状态。启动组合会注册交付的 DeepSeek、OpenAI 和 Anthropic 路由；CLI 不会添加图片专用选择标志、检查 yml 提供方清单或动态挂载适配器。

确切模型元数据只携带当前准入决策会消费的输入模态。`ImageBlock` 携带持久附件引用；其可选显示名称提供无障碍 UI 文本，因此核心块没有单独的替代文本字段。与提供方无关的 token 估算不会把某一提供方的视觉定价公式应用于其他路由。

附件 seam 公开其限制、不触碰存储的 `validateImage`，以及 `saveImage` 和 `readImage`。宿主依赖该 seam，而不是实现层重新导出的内容。浏览器草稿和历史图片操作仍是具体会话插件的内部实现；公开的 `IConversation` 表面只包含输入注册表，以及跨包边界使用的按作用域发送、取消和历史记录操作。

## 曾考虑的替代方案

**只接受一张图片。** 比较或组合多张图片是当前产品要求。图片数量和总字节数上限使这条路径保持有界，而无需将其缩减为单张图片。

**添加存储事务或回滚协议。** 不触碰存储的校验能防止后面的畸形成员使前面有效的成员成为无引用对象。若要在独立的内容寻址对象之间实现更强的全有或全无存储保证，就需要当前产品路径并不需要的所有权或回收语义。

**将面向未来的字段和方法保留为占位符。** 输出模态、块替代文本和活跃模型握手数据目前都没有决策消费方。等到第一个消费方出现时再加入这些内容，可以保留选择正确契约的自由。

**使用一种图块公式估算每张图片。** 视觉定价因提供方、模型、细节模式和预处理而异。一项硬编码且与提供方无关的估算会看似权威，实际却是错误的；提供方用量才是权威核算来源。

**添加 CLI 提供方／模型选择或动态挂载。** 配置已经负责路由选择、插件组合和凭据。在图片输入标志中重复这些选择，会要求在 loader 之外解析或修改配置树。

## 后果

该功能保留了多图片提示词所需的两个批次上限和一个不触碰存储的校验方法，同时移除了无关的公开字段、生命周期操作、策略快照和路由组装分支。提供方／模型选择仍属于组合或 profile 配置。在设计出提供方感知型估算器之前，请求前的 token 压力计算可能少计视觉输入，而上报的用量仍保持精确。

重新引入任何已移除表面时，都必须有具体消费方，并为其定义失败、生命周期、回放和测试契约，而不是为了兼容这一预发布形态。
