1. 为什么要在 Codex 里给 DeepSeek 补上识图能力Codex 桌面端现在把 ChatGPT 和 Codex 合并成了一个客户端很多人拿它当本地编码助手用。DeepSeek 系列模型在代码补全、工具调用上表现不错Terminal-Bench 这类偏工程任务的评测里也能跑到比较靠前的位置输出成本又低所以把它接进 Codex 当主力模型是很自然的选择。但问题也很直接DeepSeek 的对话模型本身不是多模态的。你截一张报错图、贴一张 UI 设计稿、丢一张接口返回的 JSON 截图过去它只能告诉你“我看不到图片内容”。在真实开发里这种场景太多了——前端对着设计稿改样式、后端对着日志截图排查、运维对着监控面板问异常全都需要模型能读图。这篇要解决的就是这件事用 TaoToken 作为统一 API 通道把 DeepSeek 接进 Codex再通过 MCP skill 的方式挂一个视觉模型上去让 DeepSeek 在需要的时候自动调用识图能力。整套流程我会给出可以直接复制的config.toml和 MCP skill 骨架最后给一个验证识图是否真正生效的测试步骤。适合谁看已经在用 Codex 或准备用 Codex 做日常编码、想让本地 Agent 具备多模态输入能力的开发者。不需要你之前配过 MCP跟着做就行。2. TaoToken 前置准备统一通道与 Key 获取在动手改配置之前先把通道和凭证准备好。TaoToken 在这里的角色是一个统一的 API 入口Codex 和后面要挂的视觉模型都走同一个 base_url省得你在多个平台之间来回切 Key、改配置。第一步打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册并登录。登录后进入控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。第二步在控制台里找到 API Keys 页面新建一个 Key。建议命名成codex-deepseek这种能一眼看出用途的名字方便后面区分。创建完成后立刻复制保存页面刷新后就看不到完整 Key 了。第三步确认你要用的模型名。DeepSeek 的对话模型和视觉模型比如 GLM-4.6V-Flash 这类在 TaoToken 的模型列表里都能查到记下准确的模型 ID后面写进配置里要用。模型对话页面可以直接在线试跑地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 不确定模型名的时候先去这里搜一下。第四步如果你打算长期用 Codex 做编码和 Agent 任务可以顺手看一下 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它针对的就是这种高频编码场景比按量单独算更省心。到这里你手里应该有三样东西一个 API Key、一个 base_urlhttps://taotoken.net/api、以及要用的模型 ID。接下来全部配置都围绕这三样展开。注意API Key 只显示一次建议存进密码管理器。不要直接提交到 Git 仓库后面配置里我会用环境变量引用的方式。3. 可复制配置config.toml 与 MCP skill 骨架Codex 的配置核心是config.toml。默认位置在用户目录下的.codex/config.tomlWindows 是C:\Users\你的用户名\.codex\config.tomlmacOS/Linux 是~/.codex/config.toml。如果目录不存在就手动建一个。3.1 主模型配置DeepSeek 走 TaoToken先写模型提供方和默认模型。下面这段可以直接复制把env_key指向你存放 Key 的环境变量名# ~/.codex/config.toml [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat [profiles.deepseek] model_provider taotoken model deepseek-chat model_reasoning_effort medium然后在系统里设置环境变量。macOS/Linux 写进~/.zshrc或~/.bashrcexport TAOTOKEN_API_KEYsk-你复制的KeyWindows PowerShell 用setx TAOTOKEN_API_KEY sk-你复制的Key设置完记得重开终端让环境变量生效。wire_api chat表示走标准的 Chat Completions 协议DeepSeek 系列用这个就行。3.2 MCP skill 骨架把视觉模型挂上去DeepSeek 自己看不见图所以我们挂一个 MCP server内部调用视觉模型。Codex 支持在config.toml里声明 MCP server写法如下# 追加到 ~/.codex/config.toml [mcp_servers.vision] command python args [/绝对路径/vision_mcp.py] env { TAOTOKEN_API_KEY sk-你复制的Key, VISION_MODEL glm-4.6v-flash }对应的vision_mcp.py骨架长这样核心逻辑就是接收图片路径或 base64转发给 TaoToken 的视觉模型再把文字结果返回# vision_mcp.py import os, base64, json, sys import httpx from mcp.server import Server from mcp.server.stdio import stdio_server from mcp.types import Tool, TextContent API_BASE https://taotoken.net/api API_KEY os.environ[TAOTOKEN_API_KEY] VISION_MODEL os.environ.get(VISION_MODEL, glm-4.6v-flash) app Server(vision) def encode_image(path: str) - str: with open(path, rb) as f: return base64.b64encode(f.read()).decode() app.list_tools() async def list_tools(): return [Tool( namedescribe_image, description识别本地图片内容返回文字描述, inputSchema{ type: object, properties: {image_path: {type: string}}, required: [image_path], }, )] app.call_tool() async def call_tool(name, arguments): if name ! describe_image: raise ValueError(funknown tool: {name}) b64 encode_image(arguments[image_path]) payload { model: VISION_MODEL, messages: [{ role: user, content: [ {type: text, text: 详细描述这张图片的内容如果是报错截图请提取错误信息。}, {type: image_url, image_url: {url: fdata:image/png;base64,{b64}}}, ], }], } headers {Authorization: fBearer {API_KEY}} async with httpx.AsyncClient(timeout60) as client: r await client.post(f{API_BASE}/v1/chat/completions, jsonpayload, headersheaders) r.raise_for_status() text r.json()[choices][0][message][content] return [TextContent(typetext, texttext)] async def main(): async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ __main__: import asyncio asyncio.run(main())依赖装一下pip install mcp httpx3.3 封装成 skillMCP 是能力skill 是让 DeepSeek 知道“什么时候该用这个能力”。在 Codex 的 skill 目录一般是~/.codex/skills/下新建vision.md--- name: vision description: 当用户提供图片路径、截图或需要识别图像内容时调用 tools: - vision.describe_image --- 当用户消息里出现图片路径、截图、设计稿、报错图时调用 vision.describe_image 工具 把 image_path 传进去拿到文字描述后再继续回答。这样 DeepSeek 在对话中遇到图片相关请求就会自动触发这个 skill转去调视觉模型。4. 验证请求确认识图调用真的生效配置写完不代表生效必须实测。分两步验证。4.1 先验证主模型通道打开 Codex随便问一句用一句话说明你现在用的是哪个模型。如果返回正常说明config.toml里的 provider 和 Key 都通了。如果报 401多半是环境变量没生效报 404检查base_url是不是写成了https://taotoken.net/api不要多加/v1Codex 会自己拼。4.2 再验证识图链路准备一张测试图比如随便截一张终端报错的图存成/tmp/test_error.png。然后在 Codex 里输入帮我看看 /tmp/test_error.png 里是什么错误。预期行为是DeepSeek 识别到这是图片请求触发 vision skill调用describe_image把图片转给视觉模型最后返回图片里的错误内容。如果你想单独测 MCP 是否通可以绕过 Codex直接手动跑一次 serverecho {jsonrpc:2.0,id:1,method:tools/list} | python /绝对路径/vision_mcp.py正常会返回describe_image这个工具的定义。如果这里就报错说明 Python 依赖或路径有问题先修这个再回 Codex 测。实测下来最容易出问题的是图片路径。Codex 传给你的可能是相对路径而 MCP server 的工作目录不一定一致所以 skill 里最好约定用绝对路径或者在describe_image里加一层os.path.abspath兜底。5. 本篇常见错排查配置过程中踩坑基本集中在这几类对照着查。报 401 UnauthorizedKey 没读到。先确认环境变量名和config.toml里env_key写的一致再确认终端重开过。Windows 用setx之后必须新开窗口当前窗口不会自动刷新。报 404 或 model not found模型 ID 写错了。去模型对话页面搜一下准确名称注意大小写和连字符。另外确认base_url结尾没有多余的斜杠或/v1。MCP server 启动失败多半是command或args路径不对。command建议写 Python 的绝对路径比如/usr/bin/python3避免 Codex 启动时 PATH 不一致。args里的脚本路径也必须是绝对路径。识图返回空或超时视觉模型响应比文本慢httpx的 timeout 设 60 秒比较稳。如果图片太大base64 之后请求体可能超限建议先压缩到 2MB 以内再传。skill 不触发检查vision.md的 frontmatter 格式tools里的名字要和 MCP server 注册的名字完全对应vision.describe_image。description 写得太模糊也会导致模型不调用把触发条件写具体一点。改了配置没反应Codex 需要重启才会重新读config.toml和 MCP 声明。改完配置先完全退出再打开。提示排查时优先看 Codex 的日志输出MCP 的 stderr 会打到那里比盲猜快很多。6. 继续往下走把通道和文档用起来识图跑通之后这套结构其实可以继续扩展。比如再加一个生图 skill内部调一个图像生成接口让 DeepSeek 在需要配图时自动调用或者把常用的日志分析、接口调试也封装成独立 skill让 Codex 变成一个多能力聚合的本地 Agent。如果你在接入过程中卡在 Key 或模型名上直接去 API Keys 页面重新确认一遍https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。完整的接入参数和协议说明在文档里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先在线验证视觉模型能不能正常读图用模型对话页面传一张图试最快https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。长期用 Codex 做编码和 Agent 任务的话Coding Plan 会比按量单独算更合适地址在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。配置这件事一次弄好后面就是纯收益。
