Skip to content

Bash 原生图片支持:最小请求层实现(仅草稿审阅) - #92

Draft
lloydzhou wants to merge 2 commits into
mainfrom
feat/bash-native-vision
Draft

Bash 原生图片支持:最小请求层实现(仅草稿审阅)#92
lloydzhou wants to merge 2 commits into
mainfrom
feat/bash-native-vision

Conversation

@lloydzhou

@lloydzhou lloydzhou commented Sep 13, 2026

Copy link
Copy Markdown
Owner

范围

仅供 Bash 草稿审阅,不合入、不发布;Go/Rust/C 尚未同步。

  • 默认关闭,保持原请求路径;支持 --vision on|offAGENT_VISION
  • 开启时仅在统一请求入口解析原有附件映射,保留原文本/数组,追加会话 PNG 图片块。
  • 三协议先转换短标记,后输出图片编码,避免公共 JSON 解析器处理大编码。
  • 视觉解析位于独立 src/awk/vision_body.awk,主脚本仅保留调用;按现有机制接入单文件打包。
  • 不改图片保存、会话格式、恢复、分叉、子代理、压缩、共享提示或工具定义。不增加视频支持。

验证

  • 构建、源码及单文件脚本语法检查、差异空白检查。
  • 独立 AWK 与拆分前内联内容逐字节一致。
  • python3 tests/test_vision.py:源码与单文件版三协议双大 PNG 编码完整性、数组保留、普通路径忽略、越界/缺失附件拒绝、关闭请求与基线逐字节一致。
  • 拆分后完整 Bash 回归:226 通过、0 失败。
  • 未进行真实模型联网视觉测试。

行数(相对 6cf4b90

范围 新增 删除
Bash 主脚本 41 2
独立视觉 AWK 45 0
AWK 协议转换器 22 0
构建脚本 2 0
测试 71 0
文档 14 2

单文件构建:3779 → 3886 行,净增 107 行。构建产物按仓库原规则不提交。

限制

会话目录与附件映射须可信;不防御本机并发替换附件。图片需留在映射原位置,服务端决定尺寸及请求大小限制。保留原技能回退文字,不改变共享提示。

@lloydzhou

Copy link
Copy Markdown
Owner Author

审查结论

审查范围:6cf4b90..d9c05df 的完整差异。本次仅审查与本地复现,未修改实现。建议继续保持草稿;除下述问题外,正式合入前仍需完成 Go/Rust/C 的运行时行为同步。

1. P2:附件解析应限制为用户消息,否则助手引用的映射会阻断后续请求

位置:src/awk/vision_body.awk:6–31src/agent.sh:589–596

解析器遍历所有消息而不检查 role。如果助手回复中引用了完整的 <attached-images> 映射,该文字也会被转换成真实图片附件。

本地复现:仅提供一条 assistant 文本消息,内容含指向会话 s/images/99.png 的附件映射,文件不存在。三个协议的 llm_vision_body 均返回 1,报“无法读取有效的 PNG 附件”,阻断整个请求。即使 Chat Completions / Responses 转换器已丢弃助手图片块,后续校验仍会检查该路径。文件存在时,Claude 请求中则实际出现助手角色的图片块;另外两种协议丢弃该块,行为不一致。

建议仅识别用户消息中的附件映射,补充“助手引用映射不读取附件、不影响请求”的测试。这不是对本机恶意并发修改的防御要求,而是正常消息角色边界。

2. P2:关闭路径回归测试没有使用真正的基线转换器

位置:tests/test_vision.py:58–69

基线只读取旧版 src/agent.sh,但运行时 AWK_DIR 仍指向当前 src/awk。因此旧脚本和新脚本实际上共用修改后的协议转换器;同时影响两边的转换回归仍能通过“逐字节一致”断言。

建议把基线脚本及其 AWK 依赖一起导出到临时目录,再与当前源码和打包版本比较。另外,目前 Makefiletest-bash / tests/test.sh 没有调用新视觉测试,应提供明确测试入口并接入对应检查流程。

转换边界及测试补充(非当前附件生成路径的阻断项)

  • src/awk/transport_openai_body.awk:160–162 在遇到图片时立即插入用户消息。对已有内容数组 tool_result(a), image, tool_result(b),转换会得到 tool(a), user(image), tool(b),打断尚未完成的多工具回复序列。当前附件解析器将新图片统一追加到数组末尾,因此常规新生成附件不会触发此顺序;建议转换器仍将同批工具回复全部输出后再输出图片,并增加测试。
  • 混合 tool_result + text + image 时,Chat Completions 丢弃同级文字、保留图片。文字丢失在基线中已存在,不计作本次新增缺陷;但当前“数组保留”测试用 cat 替代转换器,并不能证明三协议端到端保留内容。建议增加真实转换器下的混合数组测试。
  • 补充符号链接、错误 PNG 文件头、恢复/分叉历史、视觉开关环境变量与命令行优先级测试。现有非法路径用例主要覆盖越界及不存在的文件。

关于 llm_vision_body 仍然较长

值得拆分,但核心不是约 29 行的长度,而是同时承担临时文件生命周期、解析、协议转换、路径/文件校验、占位符替换和编码输出。

建议优先提取独立图片校验函数,集中表达“项目会话根范围 → 会话/images/数字.png 形状 → 符号链接/可读普通文件 → PNG 文件头”的规则;主函数保留清晰的“解析 → 转换 → 校验 → 替换”流程。随后再视复杂度收拢重复清理;不建议为减少行数引入全局 trap 或过多只有一行的包装函数。

另外,llm_call 仍以 body=$(llm_vision_body "$body") 保存完整编码请求,因此目前只是延后编码、减少转换器处理大字符串,并非端到端流式上传。不是本次阻断项,但后续讨论内存优化时应明确这一边界。

验证记录

  • 本轮通过:make build-bashpython3 tests/test_vision.pygit diff --check、源码与打包产物的 bash -n
  • 视觉测试覆盖源码/单文件的三协议大图编码、基础数组保留、普通路径忽略、非法附件拒绝;关闭路径比较通过,但存在上述基线隔离缺陷。
  • 上轮完整 Bash 测试记录:226 通过、0 失败;本轮未重复完整套件。
  • 四处 tools.json 的 SHA256 一致;共享系统提示未改动。
  • 未进行真实模型联网验证;上述协议输出与失败行为均为本地构建/转换复现,不声称已观察到真实服务端拒绝。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant