适用场景
底层模型为纯文本模型(如 DeepSeek deepseek-v4-flash),不支持图片输入。通过外接一个视觉模型 API,让 AI 具备识图能力。
原理
图片 → vision.js 转 base64 → 视觉模型 API → 返回文字描述 → 主模型
视觉模型走 OpenAI 兼容格式,换厂商只需改 BASE_URL、API_KEY、MODEL 三个值。
前置要求
- Node.js 18+
- 一个视觉模型 API Key(推荐阿里云百炼,新用户送 100 万 token;智谱
glm-4.6v-flash免费但高峰期 429 限流严重)
一、获取 API Key
阿里云百炼:https://bailian.console.aliyun.com/ → 开通百炼 → API-KEY 管理 → 创建 Key(sk- 开头)
智谱:https://open.bigmodel.cn/ → 注册实名认证 → 创建 Key(xxxxx.xxxxx 格式)
二、创建 vision.js
新建 vision.js,内容如下:
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const https = require("https");
// ==== 需要修改的三个配置 ====
const BASE_URL = process.env.DASHSCOPE_BASE_URL || "https://dashscope.aliyuncs.com/compatible-mode/v1";
const API_KEY = process.env.DASHSCOPE_API_KEY || "sk-你的Key"; // ← API Key
const MODEL = process.env.VISION_MODEL || "qwen3.5-omni-plus"; // ← 模型名
// ============================
function resolveImageUrl(source) {
const resolved = path.resolve(source);
if (!fs.existsSync(resolved)) throw new Error(`文件不存在: ${resolved}`);
const ext = path.extname(resolved).toLowerCase().replace(".", "");
const mimeMap = { jpg: "jpeg", jpeg: "jpeg", png: "png", gif: "gif", webp: "webp", bmp: "bmp" };
const data = fs.readFileSync(resolved);
return `data:image/${mimeMap[ext] || "jpeg"};base64,${data.toString("base64")}`;
}
function request(payload) {
const url = new URL(BASE_URL.replace(/\/?$/, "/") + "chat/completions");
const body = JSON.stringify(payload);
return new Promise((resolve, reject) => {
const req = https.request(url, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(body),
},
}, (res) => {
let data = "";
res.on("data", (c) => data += c);
res.on("end", () => {
if (res.statusCode >= 400) return reject(new Error(`API ${res.statusCode}: ${data.slice(0, 300)}`));
try { resolve(JSON.parse(data)?.choices?.[0]?.message?.content || data); }
catch { resolve(data); }
});
});
req.on("error", reject);
req.write(body);
req.end();
});
}
async function main() {
const args = process.argv.slice(2);
const imagePath = args[0];
const prompt = args[1] || "请详细描述这张图片的内容。";
if (!imagePath) {
console.error("用法: node vision.js <图片路径> [问题]");
process.exit(1);
}
const imageUrl = resolveImageUrl(imagePath);
const result = await request({
model: MODEL,
messages: [{ role: "user", content: [
{ type: "image_url", image_url: { url: imageUrl } },
{ type: "text", text: prompt },
]}],
stream: false,
max_tokens: 1024,
});
console.log(result);
}
main().catch(e => { console.error("识图失败:", e.message); process.exit(1); });
三、配置 Agent
Claude Code:项目根目录的 CLAUDE.md 中添加:
# 识图能力
你的底层模型不具备原生识图能力。遇到图片时,不要用 Read 工具,改用 vision.js:
node vision.js "<图片路径>" "用中文描述这张图片"
## 触发场景
- 用户分享图片路径(本地或网络 URL)
- 消息中出现 "Saved attachments:" 并列出图片
- 用户要求分析、描述、识别图片内容
Codex:同样的内容加到项目根目录的 AGENTS.md。
四、视觉模型对照
| 厂商 | BASE_URL | MODEL |
|---|---|---|
| 阿里云百炼 | https://dashscope.aliyuncs.com/compatible-mode/v1 |
qwen3.5-omni-plus / qwen-vl-max |
| 智谱 | https://open.bigmodel.cn/api/paas/v4 |
glm-4.6v-flash |
| OpenAI | https://api.openai.com/v1 |
gpt-4o-mini |
五、验证
node vision.js "/path/to/image.png" "请用中文描述这张图片的内容"
能正确返回图片内容即配置成功。
注意事项
- 429 限流:免费模型高峰期频繁返回 429,建议用千问或加 30 秒以上间隔的重试。
- Key 安全:Key 不要明文提交到 git,放
.env并在.gitignore忽略,或用环境变量DASHSCOPE_API_KEY。 - 图片限制:≤10MB,支持 jpg/png/webp/gif/bmp;过大先压缩。
- 只提文字用 OCR:仅需提取文字可本地用 tesseract;需要理解图片语义必须用视觉模型。
阅读进度 0%
private note
交流
文章暂不开放公开评论。如果你有想法、问题或建议,欢迎私下联系站长。
联系站长 →