当前位置: 首页 > news >正文

解决 cc-connect + Claude Code 图片识别问题

解决 cc-connect + Claude Code 图片识别问题:一次完整的排查与修复之旅

背景

我使用 cc-connect 桥接飞书和本地 AI 编程代理 Claude Code,并配置了 mimo-media-recognition-mcp MCP 服务器用于图片/音频/视频分析。

架构如下:

飞书用户 → cc-connect → Claude Code → MIMO API(文本模型)↓MCP 服务器 → MIMO API(多模态模型,支持图片)
  • Claude Code 主模型mimo-v2.5-pro(仅支持文本)
  • MCP 模型mimo-v2-omni(支持图片、音频、视频)

期望的行为:通过飞书发图片 → Claude Code 调用 MCP 分析图片 → 返回分析结果

实际的行为:通过飞书发图片 → Claude Code 返回"无法看到图片" → MCP 从未被调用


第一步:确认 MCP 本身是正常的

首先验证 MCP 服务器能否独立工作:

MIMO_API_KEY="your-key" MIMO_API_BASE="https://your-api-base" MIMO_MODEL="mimo-v2-omni" \
python -c "
from mimo_media_recognition_mcp.server import understand_image
import asyncio
result = asyncio.run(understand_image(prompt='描述这张图片',image_path='/path/to/test.jpg'
))
print(result)
"

结果:正常返回图片描述。MCP 服务器没有问题。


第二步:分析 cc-connect 日志

启动 cc-connect 并通过飞书发送图片,观察日志:

cc-connect --force 2>&1 | tee cc-connect.log

关键日志:

feishu: downloaded image key=img_xxx size=120814 mime=image/jpeg
claudeSession: image saved path=/home/user/projects/.cc-connect/attachments/img_xxx.jpg size=120814
turn complete tools=0 response_len=173 input_tokens=0 output_tokens=0

注意两个关键信息:

  1. tools=0 — Claude Code 没有调用任何工具(包括 MCP)
  2. input_tokens=0 — API 调用的输入 token 为 0

这说明 Claude Code 根本没有发送 API 请求


第三步:定位根本原因

通过阅读 cc-connect 源码,找到了问题所在。

cc-connect 如何处理图片

cc-connect 有两个 agent 实现:

  • agent/acp/session.go — ACP 协议代理(用于 Cursor、Windsurf 等)
  • agent/claudecode/session.go — Claude Code 专用代理

Claude Code 代理的 Send 函数agent/claudecode/session.go 第 530-598 行):

func (cs *claudeSession) Send(prompt string, images []core.ImageAttachment, files []core.FileAttachment) error {// ...// 保存图片到磁盘for i, img := range images {fpath := filepath.Join(attachDir, fname)os.WriteFile(fpath, img.Data, 0o644)savedPaths = append(savedPaths, fpath)// ⚠️ 问题在这里!把图片编码为 base64 发送给 Claude Codeparts = append(parts, map[string]any{"type": "image","source": map[string]any{"type":       "base64","media_type": mimeType,"data":       base64.StdEncoding.EncodeToString(img.Data),},})}// 发送给 Claude Codereturn cs.writeJSON(map[string]any{"type":    "user","message": map[string]any{"role": "user", "content": parts},})
}

cc-connect 把图片以 Anthropic 格式的 base64 数据内联发送给 Claude Code。

Claude Code 的图片检查机制

Claude Code 在发送 API 请求之前,会检查配置的模型是否支持图片。如果不支持,直接返回固定的"无法看到图片"回复,不会发送任何 API 请求

用户发图片 → cc-connect 编码为 base64 → 发给 Claude Code
→ Claude Code 检查模型(mimo-v2.5-pro)→ 不支持图片
→ 返回"无法看到图片"(不调用 API,不使用 MCP)

这就是为什么 input_tokens=0tools=0

对比:ACP 代理的处理方式

有趣的是,ACP 代理(agent/acp/session.go)的处理方式不同:

func (s *acpSession) appendImageRefs(prompt string, images []core.ImageAttachment) string {// 只保存图片到磁盘for i, img := range images {fpath := filepath.Join(attachDir, fname)os.WriteFile(fpath, img.Data, 0o644)paths = append(paths, fpath)}// 只发送文件路径,不发送 base64 数据return prompt + "\n\n(Image files saved locally: " + strings.Join(paths, ", ") + ")"
}

ACP 代理只发送文件路径,不发送 base64 数据。但 Claude Code 代理没有这样做。


第四步:修复方案

修改 agent/claudecode/session.goSend 函数,移除 base64 编码部分,只保留文件保存和路径引用。

修改前(原始代码):

// Save and encode images
for i, img := range images {ext := extFromMime(img.MimeType)fname := fmt.Sprintf("img_%d_%d%s", time.Now().UnixMilli(), i, ext)fpath := filepath.Join(attachDir, fname)if err := os.WriteFile(fpath, img.Data, 0o644); err != nil {slog.Error("claudeSession: save image failed", "error", err)continue}savedPaths = append(savedPaths, fpath)slog.Debug("claudeSession: image saved", "path", fpath, "size", len(img.Data))mimeType := img.MimeTypeif mimeType == "" {mimeType = "image/png"}// ❌ 这行发送 base64 数据给 Claude Codeparts = append(parts, map[string]any{"type": "image","source": map[string]any{"type":       "base64","media_type": mimeType,"data":       base64.StdEncoding.EncodeToString(img.Data),},})
}

修改后:

// Save images to disk (do NOT send base64 inline)
for i, img := range images {ext := extFromMime(img.MimeType)fname := fmt.Sprintf("img_%d_%d%s", time.Now().UnixMilli(), i, ext)fpath := filepath.Join(attachDir, fname)if err := os.WriteFile(fpath, img.Data, 0o644); err != nil {slog.Error("claudeSession: save image failed", "error", err)continue}savedPaths = append(savedPaths, fpath)slog.Debug("claudeSession: image saved", "path", fpath, "size", len(img.Data))// ✅ 不再发送 base64 数据,只保存到磁盘
}

同时移除未使用的 encoding/base64 导入。


第五步:编译和部署

1. 克隆源码

git clone https://github.com/chenhg5/cc-connect.git
cd cc-connect

2. 修改代码

编辑 agent/claudecode/session.go,按上述方式修改 Send 函数。

3. 安装 Go 编译器

cc-connect 需要 Go 1.25.0:

# 从镜像下载
curl -L https://mirrors.aliyun.com/golang/go1.25.0.linux-amd64.tar.gz -o /tmp/go.tar.gz
mkdir -p ~/go-install
tar -C ~/go-install -xzf /tmp/go.tar.gz
export PATH=$HOME/go-install/go/bin:$PATH

4. 编译

cd ~/cc-connect
export GOPROXY=https://mirrors.aliyun.com/goproxy/
go build -tags no_web -o cc-connect-modified ./cmd/cc-connect

使用 -tags no_web 跳过 Web UI 构建(需要 Node.js 构建前端资源)。

5. 替换原版

# 停止原版 cc-connect
pkill -f cc-connect# 启动修改版
~/cc-connect/cc-connect-modified --force

修复后的流程

飞书发图片→ cc-connect 下载图片,保存到 .cc-connect/attachments/→ cc-connect 发送文本消息给 Claude Code:"User sent image(s).(Images also saved locally: /path/to/img.jpg)"→ Claude Code 收到文本消息→ Claude Code 读取 CLAUDE.md 中的图片分析指令→ Claude Code 调用 MCP 工具分析图片→ MCP 使用 mimo-v2-omni 模型分析图片→ 返回分析结果给用户

CLAUDE.md 配置

确保项目目录下有 CLAUDE.md,告诉 Claude Code 如何处理图片:

# Image Analysis ProtocolWhen you receive a message that mentions an image, picture, photo, or screenshot,
the image file has already been saved to disk by cc-connect.## Steps to analyze an image:1. Find the latest image file:
```bash
ls -t /home/user/projects/.cc-connect/attachments/ | head -1
  1. Analyze it using MCP:
MIMO_API_KEY="your-key" MIMO_API_BASE="your-api-base" MIMO_MODEL="mimo-v2-omni" \
python -c "
from mimo_media_recognition_mcp.server import understand_image
import asyncio
result = asyncio.run(understand_image(prompt='详细描述这张图片的内容',image_path='/home/user/projects/.cc-connect/attachments/IMAGE_FILENAME'
))
print(result)
"
  1. Reply with the analysis result in the user's language.

IMPORTANT: You MUST use the Bash tool to run the analysis command.
NEVER say you cannot see images.

总结

项目 说明
问题 cc-connect 把图片以 Anthropic base64 格式发给 Claude Code,但 MIMO 模型不支持图片格式,Claude Code 直接返回"无法看到图片"
根因 agent/claudecode/session.goSend 函数把图片编码为 base64 内联发送
修复 移除 base64 编码,只保存图片到磁盘,通过文件路径引用
效果 Claude Code 收到文本消息,读取 CLAUDE.md,调用 MCP 分析图片

核心思路:不让 Claude Code 看到图片数据(它处理不了),而是让它知道图片在哪里(文件路径),然后通过 MCP 工具去分析。


附录:一键启动脚本

#!/bin/bash
# start-cc-connect.shpkill -f cc-connect 2>/dev/null
sleep 1# 使用修改版 cc-connect
~/cc-connect/cc-connect-modified --force
chmod +x start-cc-connect.sh
./start-cc-connect.sh
http://www.jsqmd.com/news/891837/

相关文章:

  • 基于DTW与XGBoost的能源安全指数高频预测:代理变量遴选与建模实战
  • 构建可伸缩CNN:混合粒度剪枝与运行时切换技术实践
  • Unity启动页帧动画实现原理与工程实践
  • 用状态机做移动游戏端到端稳定性自动化
  • Blender导出OBJ到Unity模型发白的三大断点与解决方案
  • 基于循环嵌入与自举法的复向量信号物理参数置信区间估计
  • DVWA文件上传漏洞原理与四层纵深防御实践
  • WPA2-PSK WiFi攻防实战:从网卡驱动到handshake破解全流程
  • 四种索引,一个系统,重新定义 AI 如何理解知识
  • 解锁PC游戏新维度:Ryujinx Switch模拟器完全指南
  • EtherCAT PDO映射实战:从XML文件到STM32代码,搞定一个自定义模拟量变量
  • AutoRaise终极指南:macOS窗口悬停自动提升的完整教程
  • 2026 百色房屋漏水不用愁!雨中匠人免费上门检测,本地专业防水公司常年TOP1!卫生间免砸砖防水,快速解决您的烦恼。权威!靠谱!稳定!售后无忧!!! - 防水百科
  • Python构建独立发行版的深度技术解析与实战指南
  • 企业内训场景下利用 Taotoken 为学员提供统一的模型练习环境
  • 物理嵌入神经网络:融合高光谱廓线与卫星图像提升对流临近预报
  • 从LSB隐写到Nihilist密码:一次完整的Misc实战解密之旅
  • saentis刚玉球SA50008467,氧化铜SA99060305,锡箔杯SA76152301选哪家?天津欧捷科技获得用户推荐 - 品牌推荐大师1
  • 量子优化算法在软件工程中的应用与实现
  • 阿里云代理商:解密HappyHorse 阿里原生音视频联合生成 AI 大模型的技术架构
  • Unity TMP SDF字体问号乱码的根因与修复指南
  • Git clean命令详解:安全清理未追踪文件的完整指南
  • 手把手教你用MATLAB/Simulink搭建三相逆变器SVPWM仿真模型(附代码)
  • ARMv8 A64原子操作指令详解与并发编程实践
  • 从攻击到防御:手把手教你用Hydra破解自家Win10后,如何设置强密码策略和账户锁定
  • 仿生双传感纤维:一根棉线实现温度与应变独立测量
  • 3个隐藏的魔法公式:让B站字幕成为你的私人知识库
  • *题解:CF2229E Deconstruction Tree
  • Unity GameObject-Component 架构底层原理与性能优化
  • Frida Android 快速上手:从环境搭建到 Java/Native 层 Hook 实战