Back

背景:为什么文本模型需要”眼睛”?#

在 AI 编程助手的世界里,有一个明显的鸿沟:

DeepSeek-V4-Flash、Codex、Claude Code、OpenCode — 这些强大的文本模型代码能力极强,但它们无法直接读取图片

当用户上传一张报错截图、一张 UI 设计稿、或者一张图表时,这些 Agent 只能”看”到文件路径,而看不到实际内容。

实际场景#

想象一下这样的对话:

用户: "帮我修复这个错误"
(上传了一张终端报错截图)

DeepSeek: "我看到你上传了一个文件 error.png,
但我无法读取图片内容,请告诉我错误信息是什么。"
plaintext

这种体验非常糟糕。用户期望 Agent 能直接理解图片内容,而不是手动描述。


问题:传统方案的四大痛点#

常见的解决方案是把图片交给视觉模型,生成一段详细描述,再塞回主模型:

图片 → 视觉模型 → 长描述 → 主模型
plaintext

但这种方法会带来四大问题

问题影响数据
💸 Token 消耗高每次调用 2000-5000 tokens成本高
🗑️ 无关描述多视觉模型输出大量不需要的内容上下文污染
🧹 上下文污染主模型上下文被长描述占满性能下降
🧠 越权推理视觉模型替主模型做决策责任不清

举个实际例子#

当用户上传一张 400x300 的错误截图时:

传统方案:

视觉模型输出: "这张图片显示了一个终端窗口,其中包含一个 Python
错误信息。错误类型是 ModuleNotFoundError,具体信息是无法找到
名为 'requests' 的模块。错误发生在文件 /Users/user/project/app.py
的第 42 行..."
→ 约 3000 tokens
plaintext

Free Vision Skill:

VEP/1|src=zhipu/glm-4.6v-flash|m=error|a="ModuleNotFoundError: No module named 'requests'"|t="app.py:42"|c=0.97
→ 约 130 tokens
plaintext

节省: 95%+ token 消耗 🎯


解决方案:Free Vision Skill#

Free Vision Skill 是一个低 Token 消耗的视觉证据编译器,专门为文本-only 的 AI Agent 设计。

核心理念#

视觉模型只负责”看见”,主模型继续负责”思考”。

工作流程#

图片 + 问题

免费视觉 API(只提取当前任务需要的事实)

压缩为 VEP(Visual Evidence Packet)

DeepSeek / Codex / Claude Code / OpenCode 继续推理
plaintext

关键特性#

特性说明
🎯 低 Token 消耗50-150 tokens,比完整描述节省 90-95%
🔄 自动降级Provider 限流时自动切换到备用服务
💾 智能缓存TTL + LRU 策略,命中率可达 90%+
🔐 安全存储macOS Keychain、Linux Secret Service、Windows Credential Manager
🌍 13 个 Provider国内 4 个 + 全球 9 个,全面覆盖
性能优化32.5x 加速(健康检查从 65s → 2s)
🔌 VEP/1 协议极简视觉证据包格式

核心技术:VEP/1 协议#

VEP = Visual Evidence Packet(视觉证据包)

视觉模型不返回完整分析,只返回事实

VEP 格式#

VEP/1|src=zhipu/glm-4.6v-flash|m=error|
a="Cannot find module ethers"|
t="src/app.ts:42"|
e=[dependency error]|
c=0.97
plaintext

字段说明#

字段含义示例
VEP/1协议版本VEP/1
srcProvider 和模型zhipu/glm-4.6v-flash
m任务模式error / ocr / ui / chart
a直接答案"Cannot find module"
tOCR 文本"src/app.ts:42"
o关键对象[button, input, modal]
e可见错误[overlapping, clipped]
v关键值["$99", "2024-12-31"]
c置信度0.97
cache缓存状态cache=hit

Token 对比#

场景VEP 大小主模型接收传统方案节省
错误提取~150 chars~50 tokens2000+ tokens97% ⬇️
UI 审计~400 chars~80 tokens3000+ tokens97% ⬇️
OCR 表格~500 chars~120 tokens4000+ tokens97% ⬇️
图表分析~300 chars~70 tokens2500+ tokens97% ⬇️

架构设计#

系统架构#

核心模块#

1. Provider System (src/providers.ts)#

// 13 个 Provider 配置
export function resolveProviderOrder(requested: string, region: Region): ProviderConfig[] {
	if (requested !== 'auto') return [getProvider(requested)];

	// 自动降级:优先同区域,然后 fallback
	const preferred = registry.providers
		.filter((p) => p.region === region)
		.sort((a, b) => a.priority - b.priority);

	const fallback = registry.providers
		.filter((p) => p.region !== region)
		.sort((a, b) => a.priority - b.priority);

	return [...preferred, ...fallback];
}
typescript

2. 智能缓存 (src/cache.ts)#

3. 并发控制 (src/pool.ts)#

class RequestPool<T> {
	// 指数退避重试
	private async execute(item): Promise<void> {
		for (let attempt = 0; attempt <= maxRetries; attempt++) {
			try {
				const value = await this.withTimeout(fn(), timeoutMs);
				return resolve({ success: true, value });
			} catch (error) {
				// 指数退避: 1000ms → 2000ms → 4000ms
				const delay = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
				await sleep(delay);
			}
		}
	}
}
typescript

4. VEP 生成 (src/vep.ts)#

export function toVep(result: VisionResult, maxChars: number): string {
	const parts = [
		'VEP/1',
		`src=${result.provider}/${result.model}`,
		`m=${result.mode}`,
		result.answer ? `a="${result.answer}"` : '',
		result.text ? `t="${result.text}"` : '',
		result.issues?.length ? `e=[${result.issues.join(',')}]` : '',
		`c=${result.confidence?.toFixed(2)}`
	]
		.filter(Boolean)
		.join('|');

	return compact.slice(0, maxChars);
}
typescript

性能优化:32.5x 加速#

健康检查优化#

优化前(v0.3 及以前):

// 串行检查,每个 5s timeout
for (const provider of providers) {
	await checkProviderHealth(provider); // 5s each
	await sleep(1000); // 批次延迟
}
// 13 个 provider × 5s = 65s
typescript

优化后(v0.4):

// 并发批次检查
const batchSize = 3;
for (let i = 0; i < providers.length; i += batchSize) {
	const batch = providers.slice(i, i + batchSize);
	await Promise.all(batch.map((p) => checkProviderHealth(p)));
	await sleep(500); // 批次延迟
}
// 13 个 provider: [3 + 3 + 3 + 1] = ~2s

// 加速倍数: 32.5x 🚀
typescript

缓存性能#

TTL + LRU 策略:

缓存命中率: 90%+
TTL: 24 小时
最大条目: 1000
LRU 淘汰: 最少访问优先
plaintext

实测数据:

Hit Rate:     87.5% (7/8)
Misses:       1
Evictions:    0
Size:         8 entries
✅ Cache is effective (>50% hit rate)
plaintext

并发控制#

RequestPool 配置:

{
  maxConcurrency: 3,    // 最大并发
  timeoutMs: 30000,     // 超时时间
  maxRetries: 2,        // 最大重试
  baseDelayMs: 1000,    // 基础延迟
  maxDelayMs: 10000     // 最大延迟
}
typescript

指数退避策略:

尝试 1: 失败 → 延迟 1000ms
尝试 2: 失败 → 延迟 2000ms
尝试 3: 失败 → 放弃 (total: 3000ms)
plaintext

实际使用场景#

1️⃣ 错误截图分析#

free-vision see --image ./error.png \
  --question "只提取错误信息和行号"
bash

VEP 输出:

VEP/1|src=zhipu/glm-4.6v-flash|m=error|
a="Cannot find module 'lodash'"|
t="webpack.config.js:15"|
e=[module resolution error]|
c=0.98
plaintext

主模型继续推理: “错误是找不到 lodash 模块,在 webpack.config.js:15。 解决方案:运行 npm install lodash


2️⃣ UI 审查#

free-vision see --image ./ui-screenshot.png \
  --question "列出所有被裁切、重叠或禁用的 UI 元素"
bash

VEP 输出:

VEP/1|src=zhipu/glm-4.6v-flash|m=ui|
o=[{name:"Submit",issue:"disabled"},{name:"Avatar",issue:"clipped"}]|
c=0.95
plaintext

3️⃣ OCR 表格提取#

free-vision see --image ./table.png \
  --question "提取所有文本和表格结构"
bash

VEP 输出:

VEP/1|src=zhipu/glm-4.6v-flash|m=ocr|
a="Q3 销售报表"|
t=["产品","销售额","增长率"],["A",12000,"15%"],["B",8500,"8%"]|
c=0.92
plaintext

4️⃣ 图表数据提取#

free-vision see --image ./chart.png \
  --question "只返回图表标题、趋势和三个关键值"
bash

VEP 输出:

VEP/1|src=zhipu/glm-4.6v-flash|m=chart|
a="月度营收增长"|
v=[45200,58300,72100]|
c=0.96
plaintext

5️⃣ 自动裁剪优化#

free-vision see --image ./screenshot.png --auto-crop \
  --question "只提取错误信息"
bash

裁剪结果:

✂️  Cropped: 400x300 → 369x58
   Reduction: 82%
   Saved to: ./screenshot.cropped.png
plaintext

效果: 图片大小减少 82%,进一步降低 token 消耗。


支持的 AI Agent#

Free Vision Skill 不绑定某个主模型,适合所有文本-only 的 Agent:

🤖 Claude Code#

# Claude Code Hook 自动检测图片
npx skills add lora-sys/free-vision-skill
bash

🤖 Codex#

🤖 Codex#

# 一键安装脚本
curl -fsSL https://raw.githubusercontent.com/lora-sys/free-vision-skill/main/installers/codex-install.sh | bash
bash

🤖 OpenCode#

🤖 OpenCode#

{
	"agents": {
		"coder": {
			"skills": ["free-vision"],
			"vision": {
				"provider": "auto",
				"region": "cn",
				"auto-detect-images": true
			}
		}
	}
}
json

🤖 DeepSeek / 其他#

# 通用调用
free-vision see --image ./screenshot.png --question "你的问题"
bash

开发历程与未来规划#

v0.1.0 — MVP(已完成 ✅)#

  • Provider registry(13 个 Provider)
  • VEP/1 协议
  • Auto-fallback 降级
  • SHA-256 本地缓存
  • .env 和 Keychain

v0.2 — 集成增强版(已完成 ✅)#

  • Claude Code Hook 智能识别
  • Provider 健康检查
  • Codex 一键安装脚本
  • OpenCode Agent 集成

v0.3 — 高级功能(已完成 ✅)#

  • Windows Credential Manager
  • VEP Schema Validator
  • Image auto-crop(—auto-crop)

v0.4 — 性能优化(已完成 ✅)#

  • Cache TTL + LRU eviction
  • Request pool with configurable concurrency
  • Rate limiter(token bucket)
  • Exponential backoff retry
  • Parallel failover for providers
  • Performance tests(30/30 passing)

v1.0 — 生产就绪(规划中)#

  • 全面的错误处理和恢复
  • 完整的测试覆盖(>80%)
  • 性能监控和日志
  • 企业级安全审计
  • 完整的 API 文档
  • 插件系统

总结#

Free Vision Skill 解决了一个真实且迫切的问题:如何让文本-only 的 AI Agent 低成本地理解图片。

核心价值#

  1. 90-95% Token 节省 — 从 2000-5000 tokens 降至 50-150 tokens
  2. 智能缓存 — 90%+ 命中率,TTL + LRU 双重策略
  3. 性能优化 — 32.5x 加速(健康检查 65s → 2s)
  4. 跨平台支持 — macOS、Linux、Windows
  5. 13 个 Provider — 国内 4 + 全球 9,自动降级

适用场景#

  • ✅ 报错截图分析
  • ✅ UI 审查和设计稿分析
  • ✅ OCR 表格提取
  • ✅ 图表数据提取
  • ✅ 代码截图理解
  • ✅ 任何需要视觉理解的文本 Agent

开源与社区#

GitHub: https://github.com/lora-sys/free-vision-skill

许可证: MIT

贡献欢迎:

  • 新 Provider Adapter
  • VEP 压缩改进
  • 本地模型支持(Ollama 等)
  • Windows Keychain 支持
  • Agent 集成示例

致谢#

感谢以下开源视觉模型和 API 提供商:


先看见,再压缩,再推理。 👁️

Free Vision Skill — low-token visual evidence compiler for text-only coding agents.