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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。注意 API 地址后面不加 UTM 参数,保持干净。
你需要先拿到一个 API Key。进入控制台创建 Key 的路径是:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。创建好之后,把 Key 保存到一个环境变量里,比如TAOTOKEN_API_KEY。这样做的目的是避免把 Key 硬编码到配置文件里,减少泄露风险。
接下来是模型 ID 的选择。如果你只是做文档转换这类任务,不需要特别强的推理能力,选一个响应快、成本低的模型就行。具体模型 ID 可以在模型对话页面查看:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。选好之后记下来,后面配置里要用。
如果你打算长期用 opencode 做编码或 Agent 类任务,可以了解一下 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。它适合需要频繁调用模型、又希望控制成本的场景。
接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite ,里面有不同工具的配置示例。Claude Code 相关的接入说明在 https://taotoken.net/claudecode?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite ,如果你同时用 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 文件 - 转换结果报告(成功/失败列表) ## 依赖 - LibreOffice(soffice 命令) - 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 2>&1; then echo "ERROR: soffice not found. Please install LibreOffice." >&2 exit 1 fi convert_one() { local input="$1" local outdir="$2" local attempt=1 while [ "$attempt" -le "$RETRY_TIMES" ]; do if "$SOFFICE_BIN" --headless --convert-to pdf --outdir "$outdir" "$input" >/dev/null 2>&1; 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 一致:文字有没有乱码、表格有没有错位、页边距是否正常。
也可以直接在命令行里测试脚本,不经过 opencode:
bash ~/.config/opencode/skills/docx-to-pdf-converter/scripts/convert.sh ~/Downloads/demo.docx输出应该是:
OK: /Users/yourname/Downloads/demo.docx然后检查生成的 PDF:
ls -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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。
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_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。如果你同时用 Claude Code,可以看 https://taotoken.net/claudecode?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 里的说明。
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/api,Key 从TAOTOKEN_API_KEY读取,模型 ID 在config.toml里指定。这样做的目的是让docx-to-pdf-converterskill 的模型调用走一个统一通道,方便管理。
如果你还有其他工具或脚本需要调用模型,也可以统一用同一个 Key 和 Base URL。这样你只需要维护一个 Key,切换模型时改model_id就行,不用每个工具单独配置。
需要创建或管理 Key 的话,入口在这里:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite ,里面有不同场景的配置示例。想先试试模型对话效果,可以到 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。长期做编码或 Agent 任务的话,Coding Plan 在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 。
整个流程跑下来,你会发现 skill 的价值在于把重复动作封装成可复用的指令。docx-to-pdf-converter只是一个例子,你可以按同样的结构写其他 skill,比如图片压缩、Markdown 转 HTML、批量重命名。关键是把输入输出定义清楚,把依赖和重试逻辑写进脚本,然后让 opencode 负责理解自然语言指令并触发执行。
最后提醒一点:config.toml里的model_id记得替换成实际值,TAOTOKEN_API_KEY记得设置到环境变量里。这两步做完,skill 就能稳定运行了。