别再被官方文档劝退了:用大白话聊聊 AI Skills
Learning plan for skills in cursor
Exported on 2026/2/26 at GMT+8 22:47:43 from Cursor (2.5.20)
User
/opsx-explore 现在我想学习skills在 cursor里面的使用, 请你帮我设计一套学习计划的方案,然后协助我整体都处理完成. 我会写代码,我没有任何Skills的基础.
Cursor
我先帮你梳理一下在 Cursor 里「Skill」相关的官方能力说明,然后基于你的基础(会写代码、零 Skill 经验)给出一个循序渐进的学习+实战计划,后面我们一起把每一步都走完。接下来我会先阅读你本地自带的 create-skill 学习资料,以保证讲解完全贴合 Cursor 的实际用法。
很好,这个主题非常适合用「循序渐进 + 大量实战」来学,而且你会写代码,上手会很快。下面我先给你一个整体学习路线图,然后我们一步步一起做完(在 explore 模式下我不会直接改代码,而是带你思考和设计,等你以后在实现模式再真正落地)。
一、先说清楚:Cursor 里的 Skill 是什么、能帮你干嘛
用一句话概括:
- Skill = 一份给 AI 的“操作手册”
它告诉 AI:“在遇到 X 场景时,用 Y 方法、按 Z 步骤做事,并用特定格式输出。”
典型用途(以后我们都可以练习一遍):
- 规范输出格式
:比如统一 commit message 风格、PR review 模板、需求文档模板。 - 固化工作流
:比如“写脚本前必跑哪些检查”、“review SQL 的 checklist”。 - 内化你的领域经验
:比如你在某业务领域的最佳实践,让 AI 按你习惯做事。 - 团队共享习惯
:项目级 Skill 让所有人用 Cursor 时 AI 行为更一致。
二、为你量身定制的学习路线(从 0 到熟练)
因为你会写代码、但对 Skill 完全是新手,我建议 4 个阶段,每个阶段我们都可以一起完成具体练习:
阶段 1:概念速通(理解核心结构和用法)
目标:
-
知道 Skill 放哪、长什么样、系统何时会自动用到它。
学习内容(我们已经部分看过 create-skill 说明,我帮你提炼重点):
- 存放位置和作用范围
- 个人 Skill
: ~/.cursor/skills/skill-name/(你所有项目通用) - 项目 Skill
: .cursor/skills/skill-name/(跟仓库走,团队共享) - 目录结构长这样:
skill-name/├── SKILL.md # 必需:主文件├── reference.md # 可选:详细说明├── examples.md # 可选:更多示例└── scripts/ # 可选:脚本工具
SKILL.md的基本结构:
---name: your-skill-name # 全小写 + 数字 + 连字符description: 简短说明+何时使用 # 很关键,系统靠它来决定是否用这个 skill---# 标题(给人看的)## Instructions给 AI 的步骤说明 / 规则 / 模板## Examples一些输入/输出示例
如果你愿意,我们可以用几分钟把这个结构用你自己的话再复述一遍,加深记忆。
阶段 2:从 0 写出你的第一个 Skill(超小而实用)
这里我们会一起「设计」而不直接写入文件(保持 explore 模式的要求),等你准备好再在实现模式里创建真实文件。
练习主题建议:写一个统一 commit message 的 Skill
原因:
-
简单、又立刻有用; -
结构清晰,涵盖 Skill 的关键部分(描述、模板、示例、工作流)。
我们在这个阶段要完成的内容:
- 确定 Skill 基本信息
- 名字
:例如 git-commit-helper或commit-message-style - 作用范围
:你希望它是「个人常用」,还是「某个项目共享」? - 写一个高质量的
description - 做什么(WHAT)
:比如“根据 git diff 帮忙生成规范 commit message” - 什么时候用(WHEN)
:比如“当用户提到 commit、提交说明、git diff 时” -
必须说明: - 设计 Instructions 区块
-
commit message 标题格式(如 type(scope): summary) -
body 里要包含哪些信息 -
不同类型(feat/fix/chore/refactor…)如何选择 -
定义: - 设计 Examples 区块
-
几个“输入描述 → 期望 commit message”示例,让 AI 学会风格。
✅ 你现在可以先告诉我:
-
想不想先用「commit message 助手」当第一个 Skill? -
或者你有别的更想固化的工作流(比如“写接口文档”、“写单测”、“review PR”)?
我会根据你选的主题,和你一起把这四点完整写出来。
阶段 3:进阶——为项目/团队定制一个「工作流类」 Skill
当第一个 Skill 写完,你就已经知道「怎么写一个模板/助手」。接下来我们做稍微复杂一点的——把一套多步骤工作流写成 Skill。
推荐 2 个适合作为第二个 Skill 的方向(你可以选一个):
- 选项 A:代码 Review Checklist Skill
-
目标:当你说“帮我 review 这个 PR”时,AI 按你自定义的 checklist 去检查逻辑/安全/风格/测试等。 -
内容:Checklist + 输出格式(严重问题/建议/可选改进)。 - 选项 B:需求/设计文档模板 Skill
-
目标:让 AI 写的需求或设计文档,全部符合你定义的结构(背景/目标/约束/方案/风险…)。 -
内容:Markdown 模板 + 关键要素说明 + 正反例示范。
这个阶段我们会练习:
-
如何在 SKILL.md里写「步骤式工作流」: -
Step 1 分析输入 -
Step 2 按 checklist 检查 -
Step 3 用统一格式输出 -
什么时候把复杂内容拆到 reference.md/examples.md,保持SKILL.md精简。
阶段 4:高级:让 Skill 真正“长到你脑子里”的程度
当你能写出前两个 Skill 后,基本已经会用了。最后是「内化」和「优化」:
可以做的训练:
- 复用 + 抽象
-
发现几个 Skill 中有重复的规则(例如团队代码规范),把它们抽到一个独立 STANDARDS.md,在多个 Skill 里引用。 - 迭代 Skill
-
不是怪 AI,而是回头改 Skill 的描述 / 说明 / 示例。 -
每当你发现 AI 行为不符合预期: - 设计一个“个人工作台”Skill
-
把你日常最常用的一整套操作都写进去(查 log、写调试脚本、写 SQL、review 请求、写文档…),让 AI 成为你的「第二大脑操作手册执行器」。
三、接下来我们怎么一起做(你完全不用自己摸索)
我会这样陪你把整个计划真正走完(在 explore 模式下,我们只「设计文本」,不改文件):
- 现在先完成 阶段 1 + 2 的设计
-
skill 名字、个人/项目级别 -
description 文本 Instructions
内容(规则 + 步骤) Examples
示例(输入描述 → 输出 commit message) -
跟你确认第一个 Skill 的主题(建议:commit message 助手)。 -
带着你一步步确定: -
我会直接给出一份完整的 SKILL.md草案文本,你可以在实现模式时直接复制到文件里用。 - 然后视你精力,再做阶段 3 的第二个 Skill 设计
- 最后教你如何在实际开发中验证 Skill 是否被触发 & 如何迭代
四、请你先做一个小选择,我们就开始实战设计
为了马上动手,我需要你回答两件事(直接中文回答就行):
-
第一个练习 Skill 的主题你更想选哪个?
-
A: commit message助手(根据改动帮你写规范提交说明) -
B:代码 review 助手(根据你习惯给出 review 意见) -
C:需求/设计文档模板助手 -
D:你心里已经有别的想固化的东西(可以简单描述) -
这个 Skill 你希望是:
-
P:个人 Skill(只对你所有项目生效) -
R:项目 Skill(以后用于某个具体仓库,方便团队共享)
你告诉我这两个选择之后,我就和你一起,把这个 Skill 的完整 SKILL.md 草案一步步设计出来。
User
/opsx-explore 我现在有一个场景: 每个月的报销都要提供发票, 有几个问题需要解决: 1、发票重复提交 2、提交了去年的发票 3、要凑足本次报销的金额, 尽量超出的少一点, 这样节约发票 4、发票要按照公司区分开.
Cursor
很好,这个场景非常适合拿来做「第一个实战 Skill / 工作流」,我们可以一边梳理业务逻辑,一边想象将来怎么让 AI 按你的规则自动帮你“算账 + 选票”。
一、先把需求抽象成规则
你现在的目标可以拆成 4 条核心约束(都是对“本次报销用哪些发票”的约束):
- 约束 A:不允许重复票
-
同一张发票(发票号码 / 代码 / 金额+日期+抬头等唯一组合)只能报销一次。 - 约束 B:不允许跨年(或跨会计年度)
-
本月报销只能用「本年」或「某个时间窗口」内的发票。 - 约束 C:金额尽量贴近本次报销额度
-
和 ( \ge ) 目标报销金额; - 超出部分尽量小
(即:最小超额问题,本质是一个“近似背包/子集和”问题)。 -
从候选发票中选择一个子集: - 约束 D:按公司区分
-
不同公司(抬头不同)要分开选票、分开报销。
可以想象你有这样一堆“原始发票池”:
所有历史发票池 ↓ 过滤掉重复的 / 已经用过的 ↓ 过滤掉不在允许日期范围内的 ↓ 按公司分成多个池(公司 A、公司 B、……) ↓ 针对「某次报销」在对应公司的池里选一个子集,金额 ≥ 本次报销金额 且超额最小
二、需要先搞清楚的几个关键问题
这些问题会直接影响我们后面怎么设计数据结构、算法,以及将来怎样写成 Skill 或脚本:
-
“发票重复”的定义
-
你手上有没有唯一的“发票号 + 发票代码”这样的字段? -
你现在有没有维护「已报销发票清单」(比如 Excel/表格/系统导出)? -
“去年的发票”具体规则
-
是严格按「自然年」禁止(2024 年的发票 2025 年一律不能报)? -
还是按「报销当月往前 X 个月」这样的窗口(比如 6 个月内)? -
组合金额的实际量级
-
每个月候选发票大概是 十几张 / 几十张 / 上百张? -
目标金额是单一一个(比如「本次报 5,000」),还是多笔(多次报销单)? -
公司区分的方式
-
是抬头完全不同(公司 A vs 公司 B),报销系统里也是完全独立的单子? -
有没有“同一次报销单内可以混几个公司的发票”这种复杂规则?(看你描述,好像是要彻底分开)
你可以简单回答这 4 点,我们就能更精确地设计后面方案。
三、从“算法/思路”角度大致长什么样
这里先用比较“工程师视角”的方式思考,不写代码,只讲思路:
1. 数据结构(无论是 Excel 还是脚本都可以用)
每张发票至少要有这些字段:
id / 票据唯一标识(发票号+代码)company 公司名/抬头date 开票日期amount 金额(含税/不含税,按你制度来)used 是否已经报销过(true/false)
2. 过滤规则
-
去重 / 去已用:
只保留 used == false 且 id 在“本次提交 + 历史记录”中不重复
-
日期过滤:
只保留 date 在 [允许起始日期, 报销截止日期] 区间内
-
按公司分组:
GroupBy company
3. 金额凑够但不浪费的选择问题
这是典型问题:
从一堆金额中选若干个,使得总和 ≥ target,并且 (sum – target) 最小。
-
理论上是一个变种「子集和 / 背包」问题,可以用: - 小规模:精确搜索 / DP
(几十张以内完全没问题) - 大规模:贪心 + 微调
(先按金额排序,从大到小或从接近目标的组合开始尝试)
我们将来可以写成类似这样的流程(伪流程,不是代码):
-
对候选发票按金额排序(比如从大到小)。 -
先尝试简单组合(单张、两张、三张)的精确穷举。 -
不够时再用 DP/回溯在可接受复杂度内搜索。 -
返回 1–3 个「最优解候选」给你选择(有时你会有业务偏好,比如优先用快到期的发票)。
四、把这套逻辑包装成一个「可复用工作流/Skill」的雏形
等你以后退出 explore、进入实际实现模式时,可以把这套业务流程写成一个类似:
- Skill 名
: invoice-reimbursement-helper - 描述
(description,第三人称): -
「根据用户提供的历史发票数据和本次报销目标金额,过滤重复和过期发票,按公司分组,并为每次报销金额推荐发票组合,使总金额不低于目标且超额尽量小。适用于报销场景、发票组合优化、避免重复报销。」
SKILL.md 的主体可以大概分成:
## 业务规则-
清楚写出 A/B/C/D 四条约束。 ## 工作流-
步骤 1:读取/接收发票列表数据(格式要求) -
步骤 2:过滤重复/已用/过期 -
步骤 3:按公司分组 -
步骤 4:针对每个公司 + 目标金额,挑选组合 -
步骤 5:输出结构化结果(每个组合的发票列表 + 总额 + 超额) ## 示例-
给 3–5 张简化发票示例 + 目标金额 → 展示推荐组合。
以后你在 Cursor 里,把某个月的发票导成一段表格/JSON 丢给 AI,就可以说:
「使用
invoice-reimbursement-helper这个 Skill,帮我算一下本月 X 公司报销 5,000 元的组合。」
AI 就按这个 Skill 里你定义的逻辑一步步执行。
五、下一步我们可以一起做什么?
为了不只是停留在“想法”,我建议我们下一步做两件事(仍然是思维层面,不改文件):
-
把你的具体业务规则说清楚请你简单回答上面那 4 组问题(重复定义、跨年规则、票据数量级、公司区分情况)。
-
我帮你用这些真实规则,写出一份完整的 Skill 草稿结构
-
包括: name/description/ 业务规则 / 工作流 / 输入输出格式示例。 -
这份草稿你以后可以直接复制到 SKILL.md里用。
你先告诉我这些实际情况,我们就用你真实的报销场景,把这个 Skill 的设计版本「从 0 搭好」。
User
/opsx-explore 1、“发票重复”的定义 发票是pdf形式的,pdf里面有唯一的发票号 2、“去年的发票”具体规则 我可以负责输入年的参数,这样不是我输入年的PDF都要摘出来 3、组合金额的实际量级 目标金额永远是单一的 4、公司区分的方式 只有3家公司, 这三家之外的都不要, 这三家内的需要区分开
Cursor
很好,这四点信息把场景限制都补齐了,我们可以把它抽成一个非常清晰的「发票报销组合助手」Skill。下面我先帮你“设计好脑子里的 Skill 草稿”,等你退出 explore、进入实现模式后,几乎可以原样拷到 SKILL.md 里用。
一、先小结一下你这个场景的抽象规则
根据你提供的信息,我用工程师视角再压一遍需求(也方便写成 Skill):
-
发票唯一性
-
发票是 PDF,每张 PDF 里有唯一发票号 → 可以用 invoice_no作为唯一键。 -
一张发票只能报销一次;如果在「历史记录 + 本次准备提交」里出现重复发票号,就要当成重复提交处理。 -
年份规则(可配置)
-
你会在使用时输入一个“允许年份参数”(比如 2024)。 -
所有发票中,只要发票年份 ≠ 这个参数,就全部排除。 -
金额组合
-
子集金额总和 ≥ 目标金额; -
超出的部分(总和 – 目标金额)尽量小(节约发票)。 -
每次报销只有一个目标报销金额(一个数字)。 -
从候选发票集合中选一个子集,使得: -
公司过滤 + 分组
-
只保留你指定的三家公司(白名单),其他公司的发票全部丢弃。 -
在这三家公司内部,要区分开(一家公司一套组合),不能混在一起算。
整体流程可以想象成这样:
所有 PDF 发票 → 解析出结构化数据 ↓过滤掉:不在三家公司 / 年份不符 / 已用 / 重复发票号 ↓按公司分三个池:A 公司池、B 公司池、C 公司池 ↓针对每个公司 + 本次目标金额 在对应池中挑选一个金额 ≥ 目标且超额最小的组合 ↓输出:每家公司用到哪些发票、金额合计和超额
二、把这套逻辑“写成 Skill”的结构设计
下面这段是一个完整的 SKILL.md 草案结构(还不是实现,只是给 AI 的“操作说明书”)。你之后可以在实现模式下新建一个 Skill 目录,比如:
-
个人: ~/.cursor/skills/invoice-reimbursement-helper/ -
或项目: .cursor/skills/invoice-reimbursement-helper/
再把下面这个草案放到 SKILL.md 中使用。
SKILL.md 草稿(思路版)
---name: invoice-reimbursement-helperdescription: 根据发票 PDF 元数据和目标报销金额,过滤重复和跨年发票,仅保留指定公司,并为每家公司推荐金额组合,使总金额不低于目标且超额尽量小。用于报销场景中自动选择合适的发票集合,避免重复报销和浪费发票。---# 发票报销组合助手## 说明本技能用于处理“每月报销需要从一堆 PDF 发票中挑选合适的发票”的场景,目标是:1. 防止**发票重复报销**;2. 自动排除**不在指定年度**的发票;3. 在满足本次报销金额的前提下,**让超出尽量少**,避免浪费发票;4. 只保留指定的几家公司,并且**按公司分开**计算和输出结果。## 输入要求使用本技能前,用户应先把 PDF 发票解析成结构化数据(表格或 JSON),至少包含以下字段:-`invoice_no`: 字符串,发票唯一编号(从 PDF 中提取)-`company`: 字符串,发票抬头对应的公司名称-`date`: 字符串或日期,开票日期(例如 `2024-03-15`)-`amount`: 数值,本次可用于报销的金额-`used`: 布尔值,是否已经报销过(`true`/`false`),没有历史信息时可以统一当作 `false`调用本技能时,需要额外提供:-`allowed_year`: 数值或字符串,例如 `2024`,表示**本次允许的发票年份**-`company_whitelist`: 长度为 3 的公司名称数组,只保留列表中的公司-`target_amount`: 数值,本次报销的目标金额(单一金额)- (可选)`max_candidates`: 数值,返回多少个“接近最优”的候选组合,默认 1推荐的输入形式可以是:- 一段 JSON 数组,外加一段自然语言补充参数,或者- 一张 Markdown 表格 + 文本说明 allowed_year / target_amount / 公司名称。## 业务规则在选择发票组合时,遵循以下规则:1.**公司白名单过滤** - 只保留 `company` 在 `company_whitelist` 内的发票; - 白名单之外的公司一律丢弃,不参与任何组合。2.**年份过滤** - 只保留开票年份等于 `allowed_year` 的发票; - 可以通过解析 `date` 字段获取年份; - 年份不等于 `allowed_year` 的发票一律丢弃。3.**重复发票过滤** - 以 `invoice_no` 作为唯一键; - 若在输入数据中同一个 `invoice_no` 出现多次,仅保留一条(如果金额或日期不同,可以优先保留金额不为 0 且日期最新的一条,按具体数据判断); - 若有历史“已报销发票清单”,则所有 `invoice_no` 出现在历史清单中的发票,都视为已用,直接丢弃。4.**已用发票过滤** - 丢弃所有 `used == true` 的发票。5.**按公司分组** - 过滤后的发票按 `company` 分成多个组; - 每次组合计算在各自公司组内独立进行,不跨公司混合。6.**金额组合目标** - 对每个公司,基于其可用发票集合和 `target_amount`,寻找一个或多个发票子集: - 子集金额总和 `sum >= target_amount`; - 超额 `sum - target_amount` 尽量小; - 在票数和金额规模较小时,可以采用**穷举 / 回溯 / 动态规划**寻找理论最优解; - 在票数较大时,允许采用**启发式/近似算法**(例如贪心 + 小范围调整)来减少计算量; - 对于每个公司,尽量给出 1~`max_candidates` 个接近最优的组合,供用户选择。7.**可用性优先级(可选规则)** - 在多个超额相同的组合中,可按以下优先级进行二次排序: - 优先使用**更早日期**的发票(先用快“过期”的票); - 其次优先使用**张数较少**的组合(简化报销单填写)。## 工作流当用户请求发票报销组合时,遵循以下步骤:1.**解析输入** - 读取用户提供的发票列表和参数: -`allowed_year` -`company_whitelist` -`target_amount` - (可选)`max_candidates` - 如果输入是表格,先将其转为内部结构数组。2.**过滤与清洗** - 过滤掉公司不在白名单的发票; - 过滤掉开票年份 ≠ `allowed_year` 的发票; - 过滤掉 `used == true` 的发票; - 按 `invoice_no` 去重,并丢弃所有已在“历史报销记录”中出现的发票。3.**按公司分组** - 将剩余发票按 `company` 分组; - 对每个公司单独执行后续步骤。4.**为每个公司求解金额组合** - 对某个公司: 1. 如果存在**单张发票**金额 `>= target_amount`,先考虑这些单张方案,选择超额最小的一张作为候选; 2. 对于剩余发票,尝试通过组合多张发票接近 `target_amount`: - 在发票数量较少时,可以穷举 2 张、3 张组合,寻找最优; - 在发票数量较多时,可以先按金额排序,用贪心算法快速得到一个可行解,再在附近进行局部搜索优化; 3. 生成若干个候选组合(最多 `max_candidates` 个),按以下优先级排序: - 超额金额从小到大; - 若超额相同,优先使用发票张数较少的组合; - 若仍相同,优先使用日期更早的发票。5.**生成输出** - 对每个公司,输出: - 公司名称; - 目标金额 `target_amount`; - 每个候选组合的: - 所含发票列表(展示 `invoice_no`、`date`、`amount`); - 组合总金额 `sum`; - 超额金额 `sum - target_amount`; - 使用清晰的 Markdown 结构(表格或分级列表)展示结果。6.**解释与建议** - 在输出组合后,用自然语言简要说明: - 为什么选择这些组合; - 是否有无法达到目标金额的公司(例如发票总额不足时); - 如果存在多个候选组合,说明选择它们的排序依据。## 输出格式示例当用户提供了发票数据和参数后,可以按如下格式输出结果(示意):```markdown# 发票报销组合结果## 公司:COMPANY_A目标金额:5000### 候选组合 1(推荐)- 发票列表: - 发票号 INV-001,日期 2024-03-01,金额 2000 - 发票号 INV-005,日期 2024-03-10,金额 3000- 合计金额:5000- 超额:0### 候选组合 2- 发票列表: - 发票号 INV-002,日期 2024-02-15,金额 1800 - 发票号 INV-006,日期 2024-03-20,金额 3200- 合计金额:5000- 超额:0---## 公司:COMPANY_B目标金额:5000> 可用发票总额为 4200,无法达到目标金额。> 建议:补充发票或调整本次报销目标。
使用示例(对话示例)
用户输入示例:
下面是我 2024 年 3 月的发票列表(已经从 PDF 提取过字段):只保留公司 A/B/C,允许年份 2024,本次报销目标金额是 5000。帮我按公司分别推荐发票组合,尽量让超额最小。
[{"invoice_no":"INV-001","company":"COMPANY_A","date":"2024-03-01","amount":2000,"used":false},{"invoice_no":"INV-002","company":"COMPANY_A","date":"2024-02-15","amount":1800,"used":false}]
期望助手机器人:
-
根据本技能的规则,自动过滤掉: -
公司不在白名单的发票(例如 OTHER_CO); -
年份不等于 2024 的发票(例如 2023 年的 INV-004); -
重复或已用发票; -
按公司分组并给出组合结果。
---### 三、接下来可以怎么继续学习和完善你现在等于是完成了一个**典型 Skill 的业务设计**(没有写代码,只是把你的思路完全标准化了):- 把发票场景抽象成: - 输入结构; - 规则集合; - 工作流步骤; - 输出格式与示例。- 这就是写 Skill 的核心能力:**把你脑子里的“隐性规则”转成明确文字 + 模板**。接下来,你有两个可以选的方向,我都可以陪你走:- **方向 A(偏 Skill 学习)**: 我带你把这份草案精简成真正适合 `SKILL.md` 的版本(控制在 200~300 行内),并再设计 1–2 个更简单的 Skill(比如 commit message 助手),从而完全掌握 Skill 写法。- **方向 B(偏业务落地)**: 当你退出 explore 模式、准备动手实现时,我们可以: - 设计一个小脚本(Python/TS 都行)去从 PDF 批量提取 `invoice_no/amount/date/company`; - 再写另一个脚本去跑「组合金额」算法; - 然后用一个 Skill 把这两个脚本的使用方式串起来,让你每个月基本只需要喂 PDF 就能完成报销选票。你可以先告诉我更倾向 A 还是 B,或者「两个都要,但先从哪个开始」,我就按那个路线继续陪你往下拆。---**User**/opsx-explore 不,我想做到的是,我提供发票文件夹,不是我直接提供整理好的数据, 数据整理也需要skill去做---**Cursor**很好,那我们就把“从发票文件夹开始,一路做到选组合”的**整个链路**都设计进 Skill 里,而不是只从结构化数据开始。下面我会用「架构 + 工作流 + Skill 结构」三个层次来帮你把这件事想清楚(不写代码,只设计)。---### 一、先把你的目标升级成完整流水线你真正想做的是:```text发票文件夹(PDF 若干) ↓[阶段 1:数据整理 Skill 能力] - 找到所有 PDF - 从每个 PDF 中提取:发票号 / 公司 / 日期 / 金额 - 生成统一的结构化清单(表/JSON) ↓[阶段 2:组合计算 Skill 能力] - 过滤年份、三家公司白名单、去重、去已用 ↓ - 针对每家公司 + 本次目标金额,算出「超额最小」的发票组合 ↓最终给你一个「每家公司本次怎么选票」的结果
也就是说,你需要的 不是一个 Skill,而是一条工作流:Skill 里要告诉 AI:
-
遇到“我给你一个文件夹路径”的时候,先怎么把 PDF 变成表(数据整理阶段),再怎么按我们前面说好的规则求组合。
二、整体设计:一个 Skill 里分两个阶段
我建议先做一个 Skill,内部清晰地分成两大块:
阶段 1:从文件夹提取发票数据阶段 2:基于发票数据做组合优化
以后如果你觉得太大,再拆成两个 Skill 也行。
1. 阶段 1:从发票文件夹构造结构化数据
在 SKILL.md 里写清楚 AI 应该怎么做(伪流程):
-
获取路径与参数
invoice_folder_path
:发票 PDF 所在文件夹路径; allowed_year
:允许的发票年份; company_whitelist
:三家公司的名称列表。 -
询问用户或读取用户输入: -
列出 PDF 文件
-
使用环境中的工具(例如在 Cursor 里就是 Glob/ Shell)列出invoice_folder_path下的*.pdf文件; -
忽略非 PDF 文件和子目录里不相关的内容。 -
为“发票解析”准备工具/脚本
- 如果脚本尚未存在
:和用户说明需要先实现该脚本(这一步是以后退出 explore 才会做的实现工作); - 如果脚本已存在
:调用脚本,得到一个包含所有发票字段的 JSON/CSV。 -
推荐使用 Python + pdfplumber或PyMuPDF去解析发票; -
推荐在项目里有一个脚本: scripts/parse_invoice_pdf.py,用法: python scripts/parse_invoice_pdf.py /path/to/pdf_folder/ output.json-
Skill 可以规定一种「推荐实现方式」,比如: -
在 Skill 里写明: -
解析发票字段(逻辑层面说明) Skill 里不写具体代码,但要告诉 AI 要找什么:
Skill 里可以用几段示例 PDF 文本 + 期望字段,强化解析规则。
invoice_no
:从 PDF 中找到“发票号码”字段(可以通过关键字 + 正则); company
:发票抬头对应的公司名称(通常在抬头位置或者“购买方名称”); date
:开票日期(格式统一成 YYYY-MM-DD);amount
:价税合计或总金额(你定一个规则,比如选“价税合计(大写/小写)的小写金额”); used
:初始均为 false,如果你未来有历史报销记录,也可以在脚本里一并打上标签。-
输出结构化清单
-
一行一张发票,包含 invoice_no/company/date/amount/used等字段; -
阶段 1 的目标成果就是前面我们讨论过的那种 JSON/表格: -
并且显式写明:阶段 2 必须基于这个结构化清单来工作。
2. 阶段 2:沿用我们已经设计好的“组合优化”规则
这部分我们其实已经设计得比较完整了,只需要在 Skill 中说明:
-
输入来源:直接来自阶段 1 输出的清单; -
再执行: -
白名单公司过滤; -
年份过滤(用 allowed_year); -
去重 + 去已用; -
按公司分组; -
每个公司单独做「sum ≥ target_amount 且超额最小」的组合搜索。
这里你已经很熟悉,就不重复展开。
三、Skill 结构可以长这样(高层骨架)
我给你一个精简版骨架,方便你脑子里有个「将来 SKILL.md 大致长什么样」的画面:
---name: invoice-reimbursement-from-folderdescription: 从指定文件夹中的 PDF 发票自动提取发票信息,过滤重复和跨年发票,仅保留指定公司,并在给定目标金额下为每家公司推荐金额组合,使超额尽量小。用于从原始发票文件夹到报销组合的一站式流程。---# 发票报销流水线(从文件夹到组合)## 阶段 1:从发票文件夹提取数据### 目标给定一个发票 PDF 文件夹路径,生成结构化发票清单,每行至少包含:- invoice_no- company- date- amount- used(初始可以全部为 false)### 步骤1. 询问或读取: - 发票文件夹路径 `invoice_folder_path` - 允许年份 `allowed_year` - 公司白名单 `company_whitelist`(三个公司名称)2. 列出所有 PDF: - 仅保留扩展名为 `.pdf` 的文件3. 对每个 PDF 提取字段: - invoice_no:根据“发票号码”等关键字解析 - company:根据抬头或“购买方名称”解析 - date:解析开票日期并标准化为 YYYY-MM-DD - amount:解析总金额(例如“价税合计(小写)”) - used:如果没有历史信息,默认为 false4. 若存在项目脚本 `scripts/parse_invoice_pdf.py`: - 优先通过脚本批量处理: - 输入:`invoice_folder_path` - 输出:包含上述字段的 JSON/CSV - 若脚本不存在: - 与用户说明需要先实现该脚本,给出推荐字段和解析规则5. 将解析结果整理成统一的数据结构,供“阶段 2”使用。## 阶段 2:根据目标金额选择发票组合### 目标在阶段 1 的发票清单基础上,对每个公司分别选择发票组合:- 满足:组合金额总和 ≥ target_amount- 超额(总和 - target_amount)尽量小### 规则(这里复用我们前面设计的那套:白名单过滤、年份过滤、去重、去已用、按公司分组、组合搜索……)### 输出(按公司输出候选组合列表、合计金额和超额,格式同前面示例)
这只是骨架,你以后在真正落地时,可以把阶段 2 的“规则 + 输出示例”拷过去补全。
四、这对「学习 Skill」本身有什么帮助?
这个设计其实已经覆盖了 Skill 的几个关键能力:
-
告诉 AI 何时触发这个 Skill—— description 里写得很清楚:当用户给了「发票文件夹 + 目标金额」相关指令时。
-
把大任务拆成阶段/子任务—— 阶段 1 是数据整理,阶段 2 是算法/组合,Skill 会引导 AI一步步走。
-
指导 AI 使用脚本和工具—— Skill 里可以写明:当脚本存在时怎么调用;不存在时先帮助用户创建(这是你以后在非 explore 模式下真正实现的部分)。
五、下一步你想更深入哪一块?
我们现在已经:
-
把纯 PDF 文件夹 → 结构化数据 → 组合选票的整个流程,变成了一份可以写进 Skill 的清晰工作流; -
同时又不涉及具体实现代码,符合 explore 模式。
接下来你可以选一个更想深入的方向:
-
方向 1:继续打磨这个 Skill 的文本把上面的骨架扩展成一份足够精炼但可用的
SKILL.md正式版(控制长度、补充说明、加上 1–2 个完整示例)。 -
方向 2:回到「学习计划」层面用这个报销场景当作你的「第一个大 Skill 项目」,然后我帮你规划接下来几天如何:
-
再做一个小 Skill(如 commit message 助手), -
学会项目级 Skill 和个人 Skill 的配合, -
最后用一个 mini 项目把所有知识串起来。
你更想先做哪个?或者你想我先帮你把这个 invoice-reimbursement-from-folder 的 SKILL.md 版本写到「可以直接复制」的程度(文本设计层面),我们也可以继续往下收紧和精简。
截止到这里大家应该可以看懂Skill能做啥了吧~~
夜雨聆风
