用 oh-my-opencode 写一个 word转pdf skill:从 docx 到 PDF 的可复制配置 1. 从 docx 到 PDF 的真实痛点为什么需要一个 word转pdf skill日常办公里把 Word 文档转成 PDF 是个高频动作。合同、周报、简历、论文初稿几乎每个环节都会遇到「发出去别乱版」的需求。手动操作很简单打开 Word另存为 PDF选个路径点确定。但一旦文档数量上来或者需要批量处理、定时处理、在自动化流程里处理手动点鼠标就成了瓶颈。我遇到的具体场景是这样的手头有一批 docx 文件需要统一转成 PDF 后归档文件名要保持一致转换失败的要能重试最好还能在命令行里一条指令跑完。用 LibreOffice 的soffice --headless --convert-to pdf可以做到但每次都要记参数、处理路径、判断退出码写脚本又容易在字体、页边距、表格换行这些细节上翻车。这时候oh-my-opencode的 skill 机制就派上用场了。Skill 本质上是一个包含指令的文件夹它告诉大模型如何处理特定任务或工作流。你可以把它理解成给 AI 助手装了一个「插件」当你说「把这个 docx 转成 PDF」时它知道该调用什么命令、该检查什么依赖、失败了该怎么重试。docx-to-pdf-converter这个 skill 的目标很明确输入一个或多个 docx 文件路径输出对应的 PDF 文件中间自动处理依赖检查、路径解析、转换执行和失败重试。它适合谁适合经常和文档打交道、又不想每次都手动点「另存为」的人适合想把文档转换接进自动化流程的开发者也适合刚开始接触 opencode skill 机制、想找一个完整可跟做案例的小白。这篇文章会带你从零搭一个可用的docx-to-pdf-converterskill包括目录结构、配置片段、调用示例以及用一份样例 docx 验证转换结果和失败重试。最后还会说明怎么把 endpoint 改到 TaoToken 的统一 Key/API 通道让整个流程走一个入口。2. TaoToken 前置准备统一 Key 与 API 通道接入在开始写 skill 之前先把模型调用通道准备好。oh-my-opencode在执行 skill 时如果需要调用大模型来解析指令或生成中间内容会走一个 endpoint。默认情况下你可能用的是某个厂商的直连地址但如果你希望统一管理 Key、方便切换模型、或者让多个工具共用一个通道可以把 endpoint 改到 TaoToken。TaoToken 的官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数保持干净。你需要先拿到一个 API Key。进入控制台创建 Key 的路径是https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。创建好之后把 Key 保存到一个环境变量里比如TAOTOKEN_API_KEY。这样做的目的是避免把 Key 硬编码到配置文件里减少泄露风险。接下来是模型 ID 的选择。如果你只是做文档转换这类任务不需要特别强的推理能力选一个响应快、成本低的模型就行。具体模型 ID 可以在模型对话页面查看https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。选好之后记下来后面配置里要用。如果你打算长期用 opencode 做编码或 Agent 类任务可以了解一下 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。它适合需要频繁调用模型、又希望控制成本的场景。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 里面有不同工具的配置示例。Claude Code 相关的接入说明在 https://taotoken.net/claudecode?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 如果你同时用 Claude Code可以参考。这里要强调一点TaoToken 是一个统一的 API 通道不是所谓的「中转」或「代理」。它的作用是让你用一个 Key 访问多个模型简化配置管理。你在配置时只需要填 Base URL、Key 和 Model ID 这三件套不需要额外的网络工具。准备好这些之后就可以开始写 skill 了。下面先看目录结构。3. 可复制配置skill 目录结构与 settings 片段oh-my-opencode的 skill 默认放在~/.config/opencode/skills目录下。每个 skill 是一个独立的文件夹文件夹名就是 skill 名。对于docx-to-pdf-converter目录结构建议这样组织~/.config/opencode/skills/ └── docx-to-pdf-converter/ ├── SKILL.md ├── config.toml └── scripts/ └── convert.shSKILL.md是 skill 的核心描述文件告诉模型这个 skill 是做什么的、输入输出是什么、依赖哪些命令。config.toml存放配置比如 endpoint、模型 ID、重试次数。scripts/convert.sh是实际执行转换的脚本把 LibreOffice 的调用封装起来。先写SKILL.md。内容要清晰让模型能理解任务边界# docx-to-pdf-converter ## 功能 将 docx 文件转换为 PDF 文件支持单个文件和批量转换。 ## 输入 - 一个或多个 docx 文件路径 - 可选输出目录默认与源文件同目录 ## 输出 - 与源文件同名的 PDF 文件 - 转换结果报告成功/失败列表 ## 依赖 - LibreOfficesoffice 命令 - bash ## 调用方式 用户说「把 xxx.docx 转成 PDF」时触发。然后是config.toml。这里把 endpoint 指向 TaoToken 的 API 地址Key 从环境变量读取模型 ID 填你在模型对话页面选好的那个[model] base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model_id your-model-id-here [conversion] retry_times 3 retry_delay_seconds 2 output_dir [libreoffice] binary soffice timeout_seconds 120注意base_url写的是https://taotoken.net/api后面不加任何 UTM 参数。api_key_env指向环境变量名而不是 Key 本身。model_id需要你替换成实际选用的模型 ID。接下来是scripts/convert.sh。这个脚本负责实际转换包含依赖检查、路径解析、转换执行和失败重试#!/usr/bin/env bash set -euo pipefail SOFFICE_BIN${SOFFICE_BIN:-soffice} RETRY_TIMES${RETRY_TIMES:-3} RETRY_DELAY${RETRY_DELAY:-2} OUTPUT_DIR${OUTPUT_DIR:-} if ! command -v $SOFFICE_BIN /dev/null 21; then echo ERROR: soffice not found. Please install LibreOffice. 2 exit 1 fi convert_one() { local input$1 local outdir$2 local attempt1 while [ $attempt -le $RETRY_TIMES ]; do if $SOFFICE_BIN --headless --convert-to pdf --outdir $outdir $input /dev/null 21; then echo OK: $input return 0 fi echo RETRY $attempt/$RETRY_TIMES: $input 2 attempt$((attempt 1)) sleep $RETRY_DELAY done echo FAIL: $input 2 return 1 } for f in $; do if [ ! -f $f ]; then echo SKIP: $f (not found) 2 continue fi dir${OUTPUT_DIR:-$(dirname $f)} convert_one $f $dir done这个脚本做了几件事检查soffice是否存在对每个输入文件尝试转换失败后等待 2 秒重试最多 3 次输出成功或失败的状态。OUTPUT_DIR为空时默认输出到源文件所在目录。把这三个文件放好之后skill 就基本可用了。接下来验证一下。4. 验证请求与成功结果用样例 docx 跑通转换先准备一份样例 docx。你可以用 Word 或 LibreOffice 新建一个随便写点内容比如标题、一段文字、一个表格保存为demo.docx。放到一个测试目录里比如~/Downloads/demo.docx。然后确认环境变量已经设置export TAOTOKEN_API_KEY你的Key接着在 opencode 里触发 skill。你可以直接输入类似这样的指令ulw 将 ~/Downloads/demo.docx 转换为 demo.pdfulw是触发 skill 的关键词后面跟自然语言描述。opencode 会读取docx-to-pdf-converter的SKILL.md理解任务然后调用scripts/convert.sh执行转换。如果一切正常你会在~/Downloads目录下看到demo.pdf。用 PDF 阅读器打开检查内容是否和 docx 一致文字有没有乱码、表格有没有错位、页边距是否正常。也可以直接在命令行里测试脚本不经过 opencodebash ~/.config/opencode/skills/docx-to-pdf-converter/scripts/convert.sh ~/Downloads/demo.docx输出应该是OK: /Users/yourname/Downloads/demo.docx然后检查生成的 PDFls -lh ~/Downloads/demo.pdf file ~/Downloads/demo.pdffile命令应该输出类似PDF document, version 1.6的信息说明文件格式正确。如果转换成功你可以再试一个批量场景。准备多个 docx 文件放在同一个目录下bash ~/.config/opencode/skills/docx-to-pdf-converter/scripts/convert.sh ~/Downloads/a.docx ~/Downloads/b.docx ~/Downloads/c.docx脚本会依次处理每个文件输出每个的成功或失败状态。这样你就能看到批量转换的效果。验证通过之后说明 skill 的核心功能已经跑通了。接下来看看常见的报错和排查方法。5. 常见错排查401、local proxy failed、reading choices 与 OAuth在实际使用中可能会遇到几类典型报错。下面逐一分析原因和解决办法。401 Unauthorized这个报错通常出现在模型调用环节。原因可能是TAOTOKEN_API_KEY没有设置或者设置的值不对。检查方法echo $TAOTOKEN_API_KEY如果输出为空说明环境变量没生效。可以在~/.bashrc或~/.zshrc里加上export TAOTOKEN_API_KEY你的Key然后source一下。如果输出有值但还是 401检查 Key 是否过期或被删除可以到控制台重新创建一个https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。local proxy failed这个报错通常和网络配置有关。如果你之前配置过某些网络工具可能会干扰到正常的 API 请求。解决办法是检查环境变量里有没有HTTP_PROXY、HTTPS_PROXY之类的设置env | grep -i proxy如果有临时取消unset HTTP_PROXY HTTPS_PROXY然后重新执行转换。TaoToken 的 API 地址是直接可访问的不需要额外的网络工具。reading choices 报错这个报错一般出现在模型返回格式不符合预期时。可能的原因是model_id填错了或者模型不支持当前的调用方式。检查config.toml里的model_id是否和模型对话页面显示的一致。如果不确定可以换一个模型试试。OAuth 相关报错如果你用的是 Claude Code 或其他需要 OAuth 的工具可能会遇到 token 过期的问题。这时候需要重新走一遍授权流程。具体步骤参考接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果你同时用 Claude Code可以看 https://taotoken.net/claudecode?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 里的说明。soffice not found这个报错说明 LibreOffice 没有安装或者soffice不在 PATH 里。macOS 上可以用 Homebrew 安装brew install --cask libreofficeLinux 上用包管理器sudo apt install libreoffice安装后确认which soffice如果路径不对可以在config.toml里把binary改成绝对路径。转换后 PDF 内容异常如果 PDF 打开后文字乱码或排版错乱通常是字体问题。LibreOffice 在 headless 模式下可能找不到某些字体。解决办法是在系统里安装对应字体或者在 docx 里使用常见字体如 Arial、Times New Roman。另外复杂的表格和图文混排也可能导致转换偏差建议先用简单文档测试。排查完这些常见问题skill 的稳定性就差不多了。最后说一下怎么把整个流程的 endpoint 统一到 TaoToken。6. 语义一致 CTA把 endpoint 统一到 TaoToken前面配置里已经把base_url指向了https://taotoken.net/apiKey 从TAOTOKEN_API_KEY读取模型 ID 在config.toml里指定。这样做的目的是让docx-to-pdf-converterskill 的模型调用走一个统一通道方便管理。如果你还有其他工具或脚本需要调用模型也可以统一用同一个 Key 和 Base URL。这样你只需要维护一个 Key切换模型时改model_id就行不用每个工具单独配置。需要创建或管理 Key 的话入口在这里https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 里面有不同场景的配置示例。想先试试模型对话效果可以到 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。长期做编码或 Agent 任务的话Coding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。整个流程跑下来你会发现 skill 的价值在于把重复动作封装成可复用的指令。docx-to-pdf-converter只是一个例子你可以按同样的结构写其他 skill比如图片压缩、Markdown 转 HTML、批量重命名。关键是把输入输出定义清楚把依赖和重试逻辑写进脚本然后让 opencode 负责理解自然语言指令并触发执行。最后提醒一点config.toml里的model_id记得替换成实际值TAOTOKEN_API_KEY记得设置到环境变量里。这两步做完skill 就能稳定运行了。