[建议]图片Image read功能是否可以由多模态模型直接接管?

## 问题背景 (Background)

### 当前实现

目前 iFlow CLI 的 `image_read` 工具采用以下流程:

```

图片 → qwen3-vl-plus (VLM) → 文字描述 → 主模型

```

### 局限性

1. **信息丢失**:VLM 生成的文字描述无法完全保留图片中的所有细节

2. **Token 浪费**:需要额外的 VLM 调用,产生额外的 token 消耗

3. **缺乏上下文**:VLM 分析图片时无法感知当前对话上下文,导致分析可能与用户意图不符

4. **延迟增加**:多了一步 VLM 转换,增加了整体响应时间

-–

## 提议方案 (Proposed Solution)

### 方案一:直接使用多模态模型原生视觉能力(推荐)

当主模型本身具备多模态能力时(如 `kimi-k2.5`),直接传递图片给主模型:

```

图片 + 对话上下文 → kimi-k2.5 → 直接分析结果

```

**优势**

- 主模型直接"看到"原图,无信息丢失

- 减少一次 VLM 调用,降低延迟

- 模型可以自主决定关注图片的哪些区域

- 统一的上下文管理

### 方案二:保留 VLM 但添加上下文感知(兼容性方案)

对于不具备原生多模态能力的模型,保留现有架构但增强上下文:

```

图片 + 对话上下文 → kimi-k2.5 (VLM) → 带上下文的描述 → 主模型

```

**优势**

- 向后兼容现有非多模态模型

- VLM 可以基于对话历史提供更有针对性的分析

-–

## 技术实现细节 (Implementation Details)

### 1. 模型识别与路由

需要检测当前使用的主模型是否支持原生多模态:

```javascript

// 支持原生视觉的模型列表

const NATIVE_VISION_MODELS = [

‘kimi-k2.5’,

];

function shouldUseNativeVision(modelName) {

return NATIVE_VISION_MODELS.some(m => modelName.includes(m));

}

```

### 2. 对话上下文获取

在 `image_read` 类中添加获取对话历史的方法:

```javascript

getConversationContext() {

try {

    let sessionId = this.config.getSessionId();

    if (!sessionId) return "";

    

    let geminiClient = this.config.getGeminiClient?.();

    if (!geminiClient) return "";

    

    let chat = geminiClient.getChat?.();

    if (!chat) return "";

    

    let history = chat.getHistory?.();

    if (!history || !Array.isArray(history) || history.length === 0) return "";

    

    // 获取最近 5 轮对话

    let recentHistory = history.filter(msg => 

        msg.role === "user" || msg.role === "model"

    ).slice(-5);

    

    let contextText = recentHistory.map(msg => {

        let role = msg.role === "user" ? "User" : "Assistant";

        let content = "";

        if (typeof msg.content === "string") {

            content = msg.content;

        } else if (Array.isArray(msg.content)) {

            content = msg.content.map(c => c.text || "").join(" ");

        }

        return \`${role}: ${content}\`;

    }).filter(text => text.length > 0).join("\\n");

    

    return contextText ? 

        \`=== Conversation Context ===\\n${contextText}\\n===========================\\n\\nBased on the above conversation, please analyze the image:\` : 

        "";

} catch (e) {

    return "";

}

}

```

### 3. execute 方法改造

```javascript

async execute(args) {

const imageData = await this.loadImage(args.image_input, args.input_type);

const basePrompt = args.prompt || "请描述这张图片";



// 检查是否使用原生视觉

if (shouldUseNativeVision(this.config.modelName)) {

    // 方案一:直接传递图片给主模型

    const contextPrompt = this.getConversationContext();

    const finalPrompt = contextPrompt ? 

        \`${contextPrompt}\\n\\n${basePrompt}\` : 

        basePrompt;

    

    // 将图片和prompt一起传递给主模型

    return {

        type: "image_with_text",

        image: imageData,

        text: finalPrompt

    };

} else {

    // 方案二:使用 VLM 生成描述

    const contextPrompt = this.getConversationContext();

    const finalPrompt = contextPrompt ? 

        \`${contextPrompt}\\n\\n${basePrompt}\` : 

        basePrompt;

    

    const description = await this.multimodalHelper.generateImageDescription(

        imageData, 

        this.config.modelName, 

        finalPrompt

    );

    return description;

}

}

```

### 4. VLM 模型升级

将默认 VLM 从 `qwen3-vl-plus` 升级为 `kimi-k2.5`:

```javascript

// 原代码

let model = this.isIFlowMode && (this.baseUrl === “https://apis.iflow.cn/v1” || this.baseUrl.includes(“iflow”))

? "qwen3-vl-plus" 

: this.modelName;

// 修改后

let model = this.isIFlowMode && (this.baseUrl === “https://apis.iflow.cn/v1” || this.baseUrl.includes(“iflow”))

? "kimi-k2.5" 

: this.modelName;

```

-–

## 预期收益 (Benefits)

| 指标 | 当前方案 | 提议方案 | 改善 |

|------|----------|----------|------|

| 图片信息保真度 | 中等(经VLM转换) | 高(原生处理) | :up_arrow: 显著提升 |

| 响应延迟 | 高(2次模型调用) | 低(1次调用) | :down_arrow: 减少 30-50% |

| Token 消耗 | 高(VLM + 主模型) | 低(仅主模型) | :down_arrow: 节省 VLM token |

| 上下文感知 | 无 | 有(最近5轮) | :up_arrow: 显著提升 |

| 复杂图片理解 | 受限 | 更强 | :up_arrow: 显著提升 |

-–

## 兼容性考虑 (Compatibility)

1. **向后兼容**:对于不支持原生视觉的模型,保持现有 VLM 方案作为 fallback

2. **配置选项**:允许用户通过配置强制使用特定模式

3. **渐进式部署**:可以先在特定模型上启用,验证效果后推广

-–

## 参考对比 (Reference)

### 与 Claude Code 的对比

| 特性 | iFlow CLI (当前) | iFlow CLI (提议) | Claude Code |

|------|------------------|------------------|-------------|

| 图片处理方式 | 图片 → VLM → 文字 → 主模型 | 图片+上下文 → 多模态模型 | 图片直接给 Claude |

| 主模型是否"看"原图 | :cross_mark: | :white_check_mark: | :white_check_mark: |

| Token 消耗 | 额外 VLM token | 直接视觉 token | 直接视觉 token |

| 上下文感知 | :cross_mark: | :white_check_mark: | :white_check_mark: |

| 延迟 | 较高 | 较低 | 低 |

-–

1 个赞

如果是k2.5使用的话,我记得是直接传给k2.5的,没有vlm过程。
但如果是vlm解释图片,传入context是一个很聪明的做法,但对服务器压力有点大。(正常情况上下文都有缓存命中,但你用另一个vlm来解释就需要重新计算kv缓存了,计算开销有点大,速度也慢(prefill的速度似乎挺快的,这点我撤回)。以我有限的理解大概是这样的)

节前有在研究,这个等节后我们继续看看