@kassing/pi-vision

extension

pi 视觉理解桥接扩展:当前模型不支持图片时,自动调用外部视觉模型分析图片并注入结果

by — · v0.1.1 · published 1mo ago

$ pi install npm:@kassing/pi-vision
downloads/mo
97
stars
—
last push
—
open issues
—

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

No downloads in the last 12 weeks.

README

pi-vision — 视觉理解桥接扩展

当你在消息中附带图片时,如果当前模型不支持图片输入(非 VLM),本扩展会自动调用配置的视觉理解模型分析图片,并把理解结果以一条自定义消息注入会话,供当前模型参考。

如果当前模型本身支持 VLM,则直接使用当前模型,扩展不做任何干预。

工作原理

用户上传图片 + 提示词
        │
        ▼
before_agent_start 事件
        │
        ├─ 当前模型 input 包含 "image"? ──► 直接使用当前模型(跳过)
        │
        └─ 否则 ──► 调用视觉理解模型(含用户原文,跟随用户语言)
                        │
                        ▼
             注入 custom message "vision-bridge"
             (会话可见、持久化、参与 LLM 上下文)

原图保留在会话中;发给非 VLM 模型时 pi 内置机制会自动把图片替换为 (image omitted: model does not support images) 占位符,不会报错。

为什么需要修复占位符(重要)

非 VLM 主模型收到的消息里,图片附件会被 pi 内置机制替换成文本占位符 (image omitted: model does not support images)。即使视觉理解结果已经注入为 vision-bridge 消息,模型看到这个占位符也常常直接回答“当前模型不支持图片、 我看不到图片”,而忽略注入的视觉结果。

本扩展在 context 事件(每次 LLM 调用前)自动修复:

  • 会话中存在 vision-bridge 消息时,把用户消息里的图片附件/图片路径替换为 引导文本(如 [图片已由外部视觉模型分析,内容见下方 vision-bridge 消息]), pi 不再生成误导性占位符;
  • 给 vision-bridge 消息内容加前缀 [图片视觉分析结果(外部视觉模型)] , 让主模型明确知道它就是图片的完整描述。

以上修改只影响发给 LLM 的内容,不改变会话存储(原图、注入消息保持原样)。 仅当会话中存在 vision-bridge 消息时才会生效;当前模型是 VLM(或 forceVisionBridge 关闭时)直接看图,不做任何干预。

安装

# 开发测试(从插件目录)
pi -e ./vision-bridge.ts

# 全局安装(所有项目生效,之后 /reload 热加载)
cp vision-bridge.ts ~/.pi/agent/extensions/

# 或项目级安装
mkdir -p .pi/extensions && cp vision-bridge.ts .pi/extensions/

配置

配置文件按优先级合并(后面的覆盖前面的):

位置说明
~/.pi/agent/vision-bridge.json全局配置
<项目>/.pi/vision-bridge.json项目配置,覆盖全局
环境变量 VISION_BRIDGE_*覆盖以上两者

可参考 vision-bridge.example.json。

字段说明

{
  "enabled": true,                  // 总开关
  "forceVisionBridge": false,       // true = 即使当前模型是 VLM 也走外部视觉模型
  "maxTokens": 2048,                // 视觉模型最大输出 token
  "timeoutMs": 60000,               // 单次视觉调用超时
  "systemPrompt": "",               // 自定义系统提示词(空 = 使用内置默认)
  "vision": {
    "active": "doubao",             // 激活的模型名(缺省 = 列表第一个)
    "models": [                      // 多模型列表(推荐);旧版单模型字段仍兼容
      {
        "name": "doubao",                       // 唯一名称(/vision use/remove 用)
        "type": "openai-compat",                // "openai-compat" | "pi-registry"
        "baseUrl": "https://api.openai.com/v1",
        "apiKey": "$VISION_API_KEY",            // 支持 $ENV_VAR 或字面量
        "model": "gpt-4o-mini",
        "maxTokensField": "max_tokens",         // OpenAI o 系列模型请改为 "max_completion_tokens"
        "headers": {},                          // 附加请求头(可选)
        "fallbackOnError": false                // true = 本模型失败时自动尝试下一个模型
      },
      {
        "name": "gemini",
        "type": "pi-registry",                 // 复用 pi 模型目录里的模型,走 pi 鉴权
        "registryProvider": "google",
        "registryModel": "gemini-2.5-flash"
      }
    ]
  }
}

兼容:vision.models 缺失时自动回退到旧版单模型字段(baseUrl/model/apiKey 或 registryProvider/registryModel),第一次用 /vision add|use|remove 管理时会自动迁移为 models 列表格式。

环境变量

变量作用
VISION_BRIDGE_ENABLED"false" 可关闭
VISION_BRIDGE_BASE_URL覆盖 vision.baseUrl
VISION_BRIDGE_API_KEY覆盖 vision.apiKey
VISION_BRIDGE_MODEL覆盖 vision.model

常见服务商示例

OpenAI

{
  "vision": {
    "mode": "openai-compat",
    "baseUrl": "https://api.openai.com/v1",
    "apiKey": "$OPENAI_API_KEY",
    "model": "gpt-4o-mini"
  }
}

OpenRouter

{
  "vision": {
    "mode": "openai-compat",
    "baseUrl": "https://openrouter.ai/api/v1",
    "apiKey": "$OPENROUTER_API_KEY",
    "model": "google/gemini-2.5-flash"
  }
}

Ollama(本地)

{
  "vision": {
    "mode": "openai-compat",
    "baseUrl": "http://localhost:11434/v1",
    "apiKey": "ollama",
    "model": "llama3.2-vision"
  }
}

硅基流动 SiliconFlow

{
  "vision": {
    "mode": "openai-compat",
    "baseUrl": "https://api.siliconflow.cn/v1",
    "apiKey": "$SILICONFLOW_API_KEY",
    "model": "Qwen/Qwen2.5-VL-7B-Instruct"
  }
}

阿里云百炼 DashScope(OpenAI 兼容)

{
  "vision": {
    "mode": "openai-compat",
    "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
    "apiKey": "$DASHSCOPE_API_KEY",
    "model": "qwen-vl-plus"
  }
}

使用

/vision 命令(配置管理)

命令作用
/vision查看状态:当前模型是否支持图片、模型库列表(★=激活)、可用 VLM 模型
/vision list [序号|名称]模型库管理:查看/选择模型 → 设为激活 / 测试 / 删除
/vision add交互式添加视觉模型(OpenAI 兼容接口 或 pi 模型目录),追加到模型库
/vision use [序号|名称]切换激活模型(不填参数则交互选择)
/vision remove [序号|名称]移除视觉模型(不填参数则交互选择)
/vision test <图片> [问题]用当前激活模型测试一张图片

/vision add 引导你完成配置:

  1. 选择接入方式:OpenAI 兼容接口(输入 baseUrl / model / API Key)或 pi 模型目录(从已注册的、支持图片的 VLM 模型中选)
  2. 选择保存位置:全局 ~/.pi/agent/vision-bridge.json(所有项目生效)或项目 .pi/vision-bridge.json(仅当前项目)

添加后自动写入配置文件(保留原有其他字段),无需重启即可生效(下次发图时使用)。

自动理解

  • 自动:直接上传图片即可,无需任何命令。
  • 也支持粘贴/拖入图片文件路径文本(如 C:\...\a.png):扩展会自动检测消息中的图片路径并读取该文件进行视觉理解。只识别磁盘上真实存在的图片文件(png/jpg/jpeg/gif/webp/bmp),代码里提到的文件名不会误触发。
  • 当前模型支持 VLM 时直接使用当前模型;否则自动调用配置的视觉模型,并把结果注入会话。
  • 加载效果:视觉模型识别期间,TUI 会在编辑器上方显示一个旋转动画加载面板(图片数量 + 模型名,/vision test 同样适用),识别完成后自动消失;底部状态栏也有 Vision: 正在理解… 提示。

说明与限制

  • 视觉理解结果会注入为一条 vision-bridge 自定义消息,持久化在会话中并参与 LLM 上下文;TUI 中显示为 [vision-bridge] 标签的消息。
  • 发给非 VLM 主模型时,context 事件会把图片附件/路径替换为引导文本并给视觉结果加前缀,避免模型被 pi 的 image omitted 占位符误导(详见上文为什么需要修复占位符)。
  • 视觉调用会附带你的原始提示词,视觉模型据此用同样的语言作答。
  • 按 Esc 中断时不会注入错误消息。
  • 图片会先经 pi 处理(自动转 PNG / 缩放),以 base64 形式传给视觉模型。
  • 若视觉调用失败,会注入一条错误消息并弹出通知,而不是让对话悄悄丢失图片信息。