
1. 从 700 张硬盘照片到一张 Excel我为什么用 Claude Code 做 OCR先说清楚这篇要解决的事你手里有一堆截图、扫描件、设备照片需要把里面的文字抠出来还要整理成结构化报告Excel/CSV/Markdown 都行。传统做法是本地装 PaddleOCR 或 Tesseract但没显卡、环境依赖一堆、中文识别率还飘。Claude Code 这类 CLI 工具配合多模态模型可以直接把图片丢给模型做视觉理解把「OCR 字段抽取 汇总」串成一条链路。这篇适合谁需要批量处理截图/扫描件的开发者、运维、测试同学尤其是那种「700 张硬盘照片要提取品牌、容量、型号、SN」的重复劳动场景。核心检索词就三个Claude Code、OCR、导出报告。我试过的场景是统计一批硬盘照片信息把品牌、容量、型号、S/N 提取出来写进 Excel同时输出一份「成功多少张、失败哪些」的核对清单。整条链路的关键不在模型多强而在于统一 Key 配置和可核验的导出脚本。下面按「配置 → 调用 → 验证 → 排障」的顺序走一遍配置骨架和脚本片段都能直接复制。2. TaoToken 统一 Key 前置一次配置多模型切换Claude Code 默认走 Anthropic 官方端点但如果你想在 Kimi、豆包这类多模态模型之间切换或者团队里统一管理额度就需要一个兼容层。TaoToken 提供的就是这个角色一个统一 Key兼容 Anthropic 风格的接口Claude Code 通过环境变量指向它即可。先拿到 Key。打开控制台创建 API Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建后复制那串sk-开头的 Key只显示一次丢了就重建。这里有个坑不要把 Key 硬编码进脚本提交到 Git用环境变量或本地配置文件。TaoToken 的 API 基址是https://taotoken.net/api注意这个不加 UTM 参数是给程序调用的。Claude Code 需要两个环境变量ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY。前者指向 TaoToken 的兼容端点后者填你刚创建的 Key。注意Claude Code 读取的是 Anthropic 协议格式TaoToken 做了协议适配所以模型名可以填 Kimi-K2.5、doubao-seed-2.0-code 这类多模态模型具体可用模型以文档为准。文档入口放这里配置细节对不上时去查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite3. settings.json 配置骨架与 OCR 调用脚本3.1 Claude Code 的 settings.json 骨架Claude Code 支持项目级配置在项目根目录建.claude/settings.json。下面这份骨架把端点、模型、权限都写清楚你可以直接改 Key 后使用{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的Key填这里, ANTHROPIC_MODEL: Kimi-K2.5 }, permissions: { allow: [ Read, Write, Bash(python:*), Bash(ls:*) ], deny: [] } }如果你更习惯用 shell 环境变量等价写法是export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的Key填这里 export ANTHROPIC_MODELKimi-K2.5两种方式选一种即可settings.json 优先级更高适合团队共享Key 用占位符各人本地覆盖。3.2 需求文档让 Claude Code 知道要干什么在项目根目录写一个task.md把字段和输出格式讲清楚。这一步决定了后面 OCR 抽取的准确率别偷懒# 任务硬盘照片信息提取 ## 输入 - 目录./photos/ 下的所有 jpg/png - 每张图是一块硬盘的标签照片 ## 提取字段 | 字段 | 说明 | |------|------| | 序号 | 按文件名排序 | | 品牌 | 如 Seagate / WD / Toshiba | | 容量 | 如 500GB / 2TB | | 型号 | 如 ST11503XXAS | | S/N | 序列号 | ## 输出 1. result.xlsx成功提取的记录 2. failed.txt识别失败或字段缺失的文件名列表 3. summary.txt成功数 / 失败数 / 总数然后在项目目录打开终端运行claude /init生成CLAUDE.md再发指令claude # 进入交互后输入 阅读 task.md开始你的工作。Claude Code 会自己写 Python 脚本、调用多模态模型逐张识别、汇总结果。但「它自己写」这件事有个前提你得把导出逻辑约束死否则每次生成的表头都不一样。3.3 可复制的 OCR 导出脚本片段下面这段是我实测能跑的骨架核心思路是遍历图片 → 转 base64 → 调多模态接口 → 解析 JSON → 写 Excel。你可以让 Claude Code 基于它改也可以直接用import os, base64, json, time import requests import pandas as pd API_URL https://taotoken.net/api/v1/messages API_KEY os.environ[ANTHROPIC_API_KEY] MODEL os.environ.get(ANTHROPIC_MODEL, Kimi-K2.5) PHOTO_DIR ./photos PROMPT 你是OCR助手。识别这张硬盘标签照片只返回JSON {brand:,capacity:,model:,sn:} 识别不到的字段填空字符串不要编造。 def encode_image(path): with open(path, rb) as f: return base64.b64encode(f.read()).decode() def ocr_one(path): payload { model: MODEL, max_tokens: 512, messages: [{ role: user, content: [ {type: image, source: { type: base64, media_type: image/jpeg, data: encode_image(path) }}, {type: text, text: PROMPT} ] }] } headers { x-api-key: API_KEY, anthropic-version: 2023-06-01, content-type: application/json } r requests.post(API_URL, headersheaders, jsonpayload, timeout60) r.raise_for_status() text r.json()[content][0][text] text text.strip().removeprefix(json).removesuffix().strip() return json.loads(text) def main(): rows, failed [], [] files sorted(f for f in os.listdir(PHOTO_DIR) if f.lower().endswith((.jpg, .png))) for idx, name in enumerate(files, 1): try: data ocr_one(os.path.join(PHOTO_DIR, name)) if not data.get(sn): failed.append(name) continue rows.append({序号: idx, **data, 文件: name}) except Exception as e: failed.append(f{name} | {e}) time.sleep(0.3) pd.DataFrame(rows).to_excel(result.xlsx, indexFalse) with open(failed.txt, w) as f: f.write(\n.join(failed)) with open(summary.txt, w) as f: f.write(f成功 {len(rows)} / 失败 {len(failed)} / 总数 {len(files)}) if __name__ __main__: main()几个参数说明max_tokens给 512 够用字段就四个time.sleep(0.3)是防止批量请求触发限流media_type按实际图片格式改png 就写image/png。表头用中文方便直接交付。4. 端到端验证跑通一次并核对结果配置完别急着上 700 张先拿 3 张图验证链路。步骤第一步确认环境变量生效echo $ANTHROPIC_BASE_URL # 期望输出https://taotoken.net/api第二步跑一个最小请求确认 Key 和端点通curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d {model:Kimi-K2.5,max_tokens:64, messages:[{role:user,content:回复OK两个字}]}返回里能看到content字段带文字就说明统一 Key 配置成功。如果返回 401是 Key 问题返回 404是端点路径问题。第三步把 3 张测试图放进photos/运行脚本python ocr_export.py cat summary.txt期望看到成功 3 / 失败 0 / 总数 3打开result.xlsx核对字段是否和照片一致。这一步是「结果可核验」的关键不要只看脚本没报错要人工比对至少一张图的 S/N 是否和照片完全一致。第四步确认无误后再把 700 张全量丢进去。全量跑之前建议先备份photos/目录脚本只读不写但保险起见。想直接在对话里验证模型对某张图的识别效果可以用模型对话入口快速试https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite5. 本篇常见错排查5.1 401 UnauthorizedKey 没读到最常见的原因是环境变量没导出或者 settings.json 里 Key 还是占位符。检查顺序echo $ANTHROPIC_API_KEY是否有值 → settings.json 是否被 Claude Code 正确加载 → Key 是否已过期。注意 Key 只在创建时显示一次复制时别带空格。5.2 模型返回的不是 JSON解析报错多模态模型有时会在 JSON 外面包一层 json 代码块或者加一句「以下是识别结果」。脚本里已经用removeprefix/removesuffix处理了代码块但如果模型加了自然语言前缀json.loads还是会炸。稳妥做法是用正则抠出第一个{到最后一个}import re match re.search(r\{.*\}, text, re.S) data json.loads(match.group()) if match else {}5.3 图片太大导致请求超时手机拍的原图动辄 5MB 以上base64 后更大。建议预处理压缩到长边 1600px 以内from PIL import Image img Image.open(path) img.thumbnail((1600, 1600)) img.save(path, quality85)5.4 批量跑一半被限流表现是部分图片返回 429。加指数退避重试for attempt in range(3): try: return ocr_one(path) except requests.HTTPError as e: if e.response.status_code 429: time.sleep(2 ** attempt) else: raise5.5 Excel 里中文乱码或字段错位pandas.to_excel默认没问题但如果字段名和 dict key 对不上会出现整列 NaN。检查rows.append里的 key 是否和PROMPT里要求的 JSON 字段一致。另外 S/N 这类长数字串Excel 可能自动转科学计数法写表时用dtypestr或加前缀。6. 长期跑批量任务把配置沉淀下来如果你只是偶尔处理几十张图上面这套够用。但如果是持续性的批量任务比如每周都要处理一批扫描件建议做两件事一是把settings.json和task.md放进项目模板新任务直接复制二是把脚本里的模型名、并发数、重试次数抽成配置项方便切换。长期编码和 Agent 类任务用 Coding Plan 会更省心额度和管理都集中https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite接入过程中如果遇到协议对不上的报错先翻接入文档大部分坑都写了https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite最后留一个实用技巧跑全量之前先用ls photos/ | head -5挑 5 张不同角度、不同光照的图做样本测试。硬盘标签有反光、倾斜、模糊的情况样本覆盖到了后面 700 张的失败率会低很多。失败列表failed.txt不要删那是你二次处理的输入针对失败图单独调 prompt 或换模型重跑比全量重来省时间。