说个真实的事。我把 Obsidian 里原本用 Workflow 编排的那套图文写作流程,全部换成了 Skill 方式,一个月后翻了一下 API 的用量报表,Token 成本降了差不多 70%。不是我把写作质量砍了,也不是换了个更便宜的模型,纯粹是把“怎么组织提示词和上下文”这套底层逻辑换了。
这篇就聊聊我做了什么、怎么做到的、以及中间踩过的和 Token 有关的坑。如果你平时也用 Obsidian 写图文内容,或者你的工作流里已经接了各种大模型 API,这篇的思路可以直接抄过去。
先说清楚一个概念。很多人在 Obsidian 里用 Workflow 时,会把整个写作流程串成一个巨大的自动化模板:从读取素材、提炼摘要、生成标题、扩写正文、写配图提示词,到最后的标签推荐全部放在一个流程里跑。这种做法的好处是省心,一个命令全流程走完,但坏处是每一次调用背后都在做一件很亏的事:把所有步骤都用到的和历史步骤产生的上下文,全部重复地塞给模型,Token 消耗随步骤数近似线性上涨。
而 Skill 的思路完全相反。它把写作流程拆成一个个原子化的、可独立调用的技能单元,每个技能只带自己需要的指令和最小化上下文。跑标题生成的时候,只把素材摘要和标题规则传给模型,参数里根本不会出现整篇笔记的内容。就这么一个改变,输入端的 Token 直接从几万掉到了几千。
下面我把具体的数据、配置和坑都展开讲。
1. 为什么 Workflow 在图文写作里那么费 Token
1.1 Workflow 的“全量打包”思维
先聊聊 Workflow 在 Obsidian 里的常见形态。很多人(包括之前的我)会用 Text Generator、QuickAdd 加 Dataview 这套组合,把写作流程做成一个“点一下就跑”的自动化模板。比如我之前做的那个“图文卡片”工作流,大概是这样:
- 读取当前文件夹里所有相关笔记
- 让模型对全部内容做摘要
- 根据摘要生成标题
- 根据摘要加标题扩写正文
- 根据正文生成配图提示词
- 提取标签
这套流程跑起来非常有仪式感,问题也藏得很深。Obsidian 里一个日常笔记文件夹可能随便就是几十篇、上万字符的内容。步骤 1 把这些内容全部读出来,就已经产生了一大笔输入 Token;步骤 2 把全部素材加摘要再传给模型,Token 继续涨;到步骤 4、5 的时候,每一次调用的输入里都包含着上一步甚至上上步的完整输出,上下文越滚越大。
我当时的笔记本里有一批素材笔记,平均每篇大概 8000 到 10000 字符,也就是 12000 到 15000 Token。跑一次完整的图文卡片写作,六个步骤下来,输入端累计消耗接近六万 Token,而真正有用的输出只有标题、正文、提示词、标签这些,加起来大概两三千 Token。也就是说百分之九十以上的 Token 都花在了“把已经传给过模型的内容再传一遍”上面。
1.2 Skill 的原子化设计
后来我开始研究 Obsidian 社区里越来越火的 Skill 概念。Skill 说白了就是把一个具体能力封装成一个独立的配置实体,它长这样:
- 一个描述文件,定义这个 Skill 的名称、用途、使用的模型、温度参数、输出上限
- 一段 system prompt,定义角色和规则
- 一个上下文挂载声明,告诉插件要从笔记里取哪部分内容
- 一段输入模板,把选中的素材和变量拼成最终发给模型的提示词
关键在第三条。Skill 不要求你一次性把整个笔记库都交给模型,而是让你声明“我只需要当前选中的文字”“我只需要当前文件的标签”“我只需要某个块引用指向的那段内容”。调用时,插件只把这些精确定义的片段传给模型。
打个比方,Workflow 像是一个流水线小组,上一环节处理完的所有文件都会装进一个快递箱继续往下传,越传越大;Skill 像是一个工具箱,写标题就从箱子里拿出写标题那把扳手,写正文再换另一把。扳手不会把整个工厂都背在身上。
1.3 一账对比,省在哪一块
我给自己当时那套六步图文写作流程重新设计了一套对应的 Skill,然后做了个 Token 账本对比。按素材库约 1.5 万 Token 计算:
| 环节 | Workflow 输入 Token | Skill 输入 Token |
|---|---|---|
| 素材摘要 | 15000(整库读取) | 3000(仅当前选中片段) |
| 标题生成 | 16000(素材+摘要) | 1000(仅摘要) |
| 正文扩写 | 16100(素材+摘要+标题) | 4000(摘要+关键引用片段) |
| 配图提示词 | 16100(素材+摘要+标题+正文) | 2000(正文片段) |
| 标签提取 | 16000(全量上下文) | 800(摘要) |
| 累计输入 | 约 79200 | 约 10800 |
输出端其实省不了多少,因为该写的字还是那些字,真正省下来的是输入端反复传递的那部分冗余。输入端从接近 8 万降到一万出头,整体算下来 Token 成本大概降了七成。我后来看 API 后台的真实报表,比例和这个估算基本吻合。
2. 动手落地:在 Obsidian 里把写作流程改造成 Skill
2.1 环境准备和插件选型
改造之前需要先确认自己的 Obsidian 版本和插件生态。我用的版本是 1.5 以上,社区里支持 Skill 概念的插件目前主要有几款:Text Generator 是我最初用的,模板体系很成熟,但 Skill 语义偏弱;Copilot for Obsidian 更新速度很快,支持 Agent 模式和自定义 Skill;BMO Chatbot 也支持类似的自定义指令体系。我最终主力用的是 Copilot,因为它对 Skill 的上下文挂载声明比较明确,可以指定当前文件、当前选区、特定标签或块引用。
安装插件只需要在社区插件里搜名字,装好后在设置面板里配置 API 服务商。如果你的模型服务是 OpenAI 兼容标准,只需要填 Base URL、API Key、模型名。有一点值得提醒:Obsidian 插件里很多参数选项在不同插件里字段名不一样,比如有的叫 prompt template,有的叫 prompt_template,但核心逻辑一致,照着插件文档微调即可,不要死磕字段名称。
2.2 Skill 文件结构拆解
Skill 的核心是一个 Markdown 文件,头部用 YAML 声明元信息,正文放 system prompt 和输入模板。我用的结构大概是这样的:
--- name: webnote-writer description: 根据当前选中素材,生成一篇 300 字左右的图文卡片正文 model: gpt-4o-mini temperature: 0.7 max_tokens: 900 context: - current_file.cursorText - current_file.metadata.tags --- 你是一名擅长科技笔记整理的写作助手。请基于用户提供的素材片段创作一篇图文卡片。要求: 1. 开头第一句直接点明主题,不要铺垫。 2. 中间部分给出 2 到 3 个可操作要点。 3. 结尾加一句个人经验,不强扯结论。 4. 全文控制在 280 到 350 字,禁止输出与主题无关的补充说明。 素材片段: {{context.current_file.cursorText}} 标签: {{context.current_file.metadata.tags}}这里几个参数我解释一下。model 选择直接影响成本和输出质量,摘要、标签这类简单任务用 mini 档足够,正文创作建议用标准档,后面我会专门说。temperature 控制随机性,创意类任务调到 0.7 以上,提炼类任务调到 0.3 左右。max_tokens 是很容易被忽略但极其重要的参数,它会限制输出长度,避免模型在一句话上发挥成一篇小作文,这点我踩过坑,后面详细写。
context 这个字段是 Skill 省 Token 的灵魂。它决定插件从当前笔记里取哪些内容传给模型。我用了两个变量:cursorText 代表你在笔记里选中的文字,metadata.tags 代表当前文件的标签。这样即使你的笔记正文有几万字,实际传给模型的也只有你框选出来的那一小段,Token 消耗从根源上被控制住了。
2.3 一套可直接抄作业的图文写作四件套 Skill
我把自己那套六步 Workflow 精简成了四个 Skill,覆盖图文写作最核心的环节。整理素材部分我改用人工选中文字的方式替代全库读取,效率反而更高,因为你自己最清楚哪段素材值得被摘录。
第一个是素材摘要,负责把选中的大段素材整理成结构化的摘要。我用的配置是 model 用 mini 档、temperature 设 0.3、max_tokens 设 400。摘要的目的是提炼要点,不需要太强的创意发挥,低温能保证输出稳定地忠实于原文,不添油加醋。
第二个是标题生成。这个环节我故意用了比较高的 temperature 0.9,让模型多发散一些候选,然后挑一个最舒服的。max_tokens 设 80 就够,因为标题就那么几个字,输出太长反而说明标题不精炼。标题 Skill 的 system prompt 里我加了一条规则:禁止超长标题,禁止用“惊了”“绝了”这类流量词的标题党套路,要的是技术文章那种克制的表达。
第三个是正文扩写。这是图文写作里最吃 Token 的环节,也是 Skill 省钱最明显的环节。我的做法是:先用素材摘要 Skill 把笔记里的相关内容压缩成几百字的摘要,然后把摘要和选中的原文片段一起传给正文 Skill。正文 Skill 的 model 用 gpt-4o 或同等级标准模型,temperature 设 0.7,max_tokens 根据你要的成稿长度设 900 到 1500。这个环节不要追求一次成文,重点是把内容写扎实,后面可以再用润色 Skill 过一遍。
第四个是配图提示词。很多人在这里会犯一个错误:把整篇正文都丢给模型,让它去理解全文再写提示词。其实配一个高质量的中生代真实感提示词,只需要正文开头一两段和整体风格说明就够了。我把配图提示词 Skill 设为只接收选中正文片段,model 用 mini 档,temperature 0.6,max_tokens 设 200。配图提示词写的是内容描述、主体、环境、光影、风格,不需要理解全文逻辑。
标签生成这个步骤我也是独立成一个 Skill,输入只要摘要那几百字,temperature 0.3,max_tokens 60,把标签控制在 3 到 5 个。这么做之后,这一环节的输入 Token 从原先的一万六左右降到了几百。
2.4 从 Workflow 迁移到 Skill 的操作步骤
迁移过程没有想象中复杂,我按下面五步走完,大概花了一个下午加一个晚上调参数:
- 把我 Workflow 里每个步骤拆出来,列成一张表,明确每一步的输入是什么、输出是什么。这一步是纯人工盘点,顺带清理掉之前模板里那些冗余的提示词。
- 判断每个步骤真正需要哪些上下文。比如标签生成只需要摘要,正文扩写需要摘要加关键素材片段,配图提示词只需要正文开头。能用选区的用选区,能用标签的用标签,能用块引用的用块引用,尽量避免使用“整篇笔记全文”这样的范围。
- 为每一步建一个 Skill 文件,把原来的提示词按 system 和输入模板分层重写。原来一条 300 字的通用提示词可能被拆成 150 字 system 加 100 字输入模板,精简之后反而更聚焦。
- 在插件里测试每个 Skill,方法是在笔记里选中一小段文字,然后从命令面板里调用对应 Skill,看输出是否符合预期。第一步调用时把 debug 输出打开,确认实际发送的请求体里只有我选中的片段,没有偷偷塞进整个文件。
- 用 API 服务商后台的用量报表做前后对比。我观察了一周后看到每天的 Token 用量曲线明显下移,然后才放心把旧 Workflow 彻底停用。
3. Token 降本的三个关键技术手段
3.1 上下文裁剪:只给模型当前需要的片段
很多人在 Obsidian 里用 AI 写作时有一个思维惯性:总觉得模型知道的越多,写出来的东西越靠谱。但实测下来,这个想法在图文写作场景并不成立。模型不是搜索引擎,不会因为给了它十篇笔记就写得更好;相反,上下文里塞入大量无关内容时,模型会倾向于平均分配注意力,反而稀释了真正重要素材的权重,输出结果常常变得更平庸。
所以我做的第一件事就是裁剪上下文。在 Obsidian 里,有三招特别好用。第一招是使用块引用。我的素材笔记里,每段重要内容都单独成块,块与块之间用空行隔开,这样在引用某一段时可以直接用^块ID拉取,插件只把那一段传给模型。第二招是标签锚定。我会给素材笔记打上分主题标签,Skill 的 context 里声明current_file.metadata.tags,让模型只看到标签,而不是看到整篇内容。第三招,也是最推荐的一招,是把长笔记拆成原子卡片。这其实是一种笔记方法上的调整,每张卡片只讲一个主题,几百字到一千字封顶。这样一来,任何 Skill 选中一张卡片,上下文天然就是克制的。
裁剪上下文带来另一个好处:响应速度明显变快。以前六步 Workflow 跑一遍可能要一分钟往上,现在每个 Skill 基本都是几秒出结果。这在写作时的体验差异非常明显,等待时间短了,流程切得更顺,反而不容易在等结果时刷手机走神。
3.2 输入重写:在提示词层面对抗 Token 膨胀
上下文裁剪是从数据来源上控制量,输入重写则是从提示词层面进一步压缩。我重写提示词时遵循三条原则。
第一条,system prompt 只写角色和规则,不写素材。素材一律放到输入模板的变量里,这样同一个 Skill 可以反复使用,主体提示词不会随着素材变化而改动。第二条,在 system prompt 里显式声明“只依据提供的素材片段作答,忽略一切无关信息”。这句话看似简单,但实际效果非常好,它会抑制模型在输出里加入外部知识,减少那些正确的废话,变相降低了输出 Token。第三条,给 Skill 打磨精炼的输出格式。比如摘要 Skill 的 system prompt 里写“用三条要点概括,每条不超过 40 字”,比如配图提示词 Skill 里写“输出一段可直接用于生成模型的提示词,不超过 120 个英文词”,格式约束越具体,模型越不会绕弯子。
举一个特别典型的例子。我之前的 Workflow 提示词里有一句“请你成为一名专业的科技写作编辑,结合你的知识,以图文并茂的形式完成一篇适合公众号发布的文章”。这句话看着没毛病,但它会诱导模型在正文里展开很多百科式的背景介绍,这些内容几乎全部是模型“硬补”的,不是素材里有的,Token 就这么白白花掉。我改成“基于用户提供的素材创作原创短文,不得补充素材以外的背景知识”之后,正文篇幅缩短了将近三分之一,而且内容更扎实,全是素材里的干货。
3.3 参数和模型选择:不同环节用不同配置
Token 降本第三个手段是精细化地选择模型和参数。我把图文写作相关的任务按复杂程度分成三档。
| Skill 类型 | 推荐模型 | temperature | max_tokens | 说明 |
|---|---|---|---|---|
| 素材摘要 | mini 档 | 0.3 | 400 | 稳定优先,忠实原意 |
| 标题生成 | mini 档或标准档 | 0.9 | 80 | 发撒灵感,高温度 |
| 正文扩写 | 标准档 | 0.7 | 900-1500 | 写作质量优先 |
| 配图提示词 | mini 档 | 0.6 | 200 | 只需理解局部片段 |
| 标签提取 | mini 档 | 0.3 | 60 | 简单分类任务 |
我实测下来,同一个图文写作流程,如果所有步骤都用标准模型,成本是 mini 档的 3 到 5 倍,但质量提升主要体现在正文那个环节,摘要、标签、提示词这几个环节用 mini 档完全感觉不出差距。所以我现在只有正文扩写和润色用标准档,其他全都跑 mini 档。
max_tokens 这个参数一定要认真设置。我最初配的 Skill 里没有限制它,结果有一次调用正文 Skill,模型大概觉得素材太少,直接给我扩写了接近 4000 Token 的输出,字数超了不说,内容还差。后来我每个 Skill 都设了上限,正文控制在 1200 以内,标题控制在 80 以内。相当于给模型的才能装了个笼子,它反而会在笼子里认真干活,不会放飞。
4. 实操中遇到的 Token 报错与排查实录
4.1 先分清两类 Token
跟 Obsidian 用户聊天时发现,大家对“Token”这个词的理解经常混在一起,导致排查报错时走弯路。这里必须先明确两种完全不同的 Token。
第一种是 LLM API 的计费 Token,就是模型输入和输出内容的计量单位,直接决定你的账单。这类报错一般是额度不足、模型不存在、请求体超过上下文长度等。第二种是鉴权 Token,也就是你在调用 API 时携带的访问凭证、登录态、刷新令牌之类的。这类报错一般表现为 refresh 失败、exchange failed、403 之类的状态码。在 Obsidian 插件里遇到“Token 失效”提示时,先看清楚是哪种,别一上来就充钱包。
4.2 常见报错速查表
我整理了一张速查表,覆盖了近期在 Obsidian 生态里高频出现的 Token 相关报错和对应处理方法:
| 报错现象 | 大概率原因 | 处理办法 |
|---|---|---|
| token exchange failed: token endpoint returned 403 forbidden | 授权服务端拒绝凭证交换,多为 API Key 权限变更或账号地区设置与 API 服务不匹配 | 检查账号信息里的地区设置和 API Key 权限,联系服务商支持确认可用区域 |
| sign-in could not be completed, token exchange failed | 第三方登录凭证交换失败,回调地址或客户端 ID 不匹配 | 核对应用回调 URL、Client ID 和密钥 |
| your access token could not be refreshed | refresh token 过期或被服务器撤销 | 登出重新登录,生成新 refresh token |
| 调用模型接口提示 insufficient quota | 账号额度用完或试用期结束 | 检查 API 账单、额度配置,充值或换绑 |
| 当前链接下载文件时获取 token 为空,code 403 | 下载接口需要携带 token 参数或登录态 | 检查请求头和 Cookie,重新获取下载链接 |
| 社区插件主题下载提示无法安装 | 插件源下载失败,多与网络策略有关 | 换用离线安装方式,手动下载插件包放入对应目录 |
| git 操作提示 token 错误或 403 | 本地仓库用的令牌过期或权限不足 | 重新生成令牌,检查 remote 地址是否带令牌 |
4.3 我自己踩过的三个坑
第一个坑是提示词太长。我早期把所有写作规则都堆在提示词里,一篇模板写了五百多字,每次调用都要把整段提示词发给模型,复盘时发现这部分消耗比素材本身还大。后来我强制自己做减法:凡是模型不好好遵守的规则,一律删;凡是可以在输出格式里约定的,直接写进格式里。提示词从五百字压到一百五,效果不但没变差,反而更可控。
第二个坑是没有限制 max_tokens,正面遭遇过一次输出失控。那次我在测试“标题生成”Skill 时忘了设上限,结果模型用标准模型的创造力给我写了四个候选标题加三段解释,总共一千多 Token。对标题生成这个任务来说,这些解释完全没用。从那以后我对每个 Skill 都做了输出上限约束,这对控制成本的作用立竿见影。
第三个坑是把 context 字段理解错了。我一开始以为设置 context 之后,插件只把声明的内容传给模型。后来翻日志发现某个插件的默认设置里,“currentFile”这个变量会自动注入整篇笔记的完整内容,而我的 Skill 声明了一批变量,它们都被追加到同一份上下文中,实际传给模型的还是整篇笔记加选中片段,Token 并没有降下来。排查之后我把 Skill 里没用的变量全部清掉,只保留 cursorText,请求体从一万多 Token 降到了三千以内。这个坑说明一个道理:看日志、看实际请求体永远是排查 Token 消耗最直接的方法,别只看配置界面。
5. 最后再分享一个小技巧
在你准备动手改造之前,有一个值得先做的小操作:给现有所有 Skill 的 system prompt 统一加上一句“禁止输出与主题无关的补充说明”。这句话是我在一次偶然改提示词时加上的,后来发现它对 Token 成本的影响比预想大很多。模型默认会习惯性地在回答末尾补一些“总结”“建议”“延伸阅读”之类的内容,图文写作场景里这些几乎全是不必要的输出,每篇废掉两三百 Token,一个月累积下来也不少。加上这句之后,输出干净了,成本也轻了一截。
我现在维护着一个自己的 Skill 库,几个核心的图文写作 Skill 已经稳定用了两个多月,期间只做了细微的参数调整。Obsidian 社区里现在也出现了很多垂直领域的 Skill,比如论文写作辅助、GIS 空间分析、AI 漫剧脚本甚至游戏战斗数值策划,这说明大家已经开始把“技能”当成可以独立打磨、反复复用、随时拼接的模块。这套方式后续还可以和你现有的自动化流程结合,把它当作 Workflow 里的最小执行单元来调用,省 Token 和灵活度可以兼得。如果你也在 Obsidian 里折腾 AI 写作,不妨从拆解自己的 Workflow 开始,大概率会发现省 Token 的空间远比想象中大。