手冲咖啡.SKILL

Pour-Over Coffee as Agent Skill

每一杯手冲咖啡,都是一次 Skill 的执行。

研磨度、水温、注水手法、断水时机——这些看似随意的参数,在专业咖啡师手里是一套精确的、可重复的、经过成百上千次迭代的程序。AI Agent 的 Skill 也一样:把「凭感觉做事」变成「按配方执行」,把个人经验沉淀为组织能力。

这篇文章本身就是一份 Skill。它的格式遵循 SKILL.md 规范,它的内容是手冲咖啡与 AI Skill 设计之间的深层同构。

Overview

没有配方的咖啡师,每次冲煮都是开盲盒。

没有 Skill 的 AI Agent,每次执行都在重新发明轮子。

两者的困境完全一样:输入不确定、参数不透明、输出不稳定。解决路径也一样: 把隐性知识显性化,把显性知识程序化

手冲咖啡世界里,SCA(精品咖啡协会)用杯测表(Cupping Form)把「好喝」拆解为 10 个可量化维度。AI Agent 的 Skill 框架用 SKILL.md 把「好用的回答」拆解为触发条件、执行步骤、验证清单和常见翻车点。

本质上,它们都是同一个工程范式的产物:

┌─────────────────────────────────────────────────┐
│           Knowledge Codification Loop           │
│                                                 │
│   隐性经验 ──→ 显性配方 ──→ 程序化执行 ──→ 数据反馈 │
│      ↑                                │         │
│      └────────── 迭代优化 ←────────────┘         │
└─────────────────────────────────────────────────┘

When to Use

什么时候该写一份 Skill?用咖啡做判断标准:

  • 你反复做同一件事——每天早晨冲一杯,还是偶尔来一杯?高频 = 值得写
  • 结果不稳定——同样的豆子,今天好喝明天翻车?说明关键参数没有被锁定
  • 要教别人——带新人上手,口头说「差不多」是最差的教学方式
  • 翻过车——被坑过的地方,是最该写进 Common Pitfalls 的

不该写的场景:一次性任务、纯探索性工作、结果无法验证的操作。一杯喝完就扔的速溶,不需要杯测记录。

核心映射

这是整篇文章的脊柱。手冲咖啡的每一个元素,都对应 Skill 设计中的一个核心概念。

手冲咖啡Agent Skill说明
咖啡豆(产地、处理法)原始知识与数据源一切的基础。耶加雪菲和曼特宁需要完全不同的冲法,就像代码审查和数据分析需要完全不同的 Skill
磨豆机(研磨度)信息粒度控制太粗萃取不足(信息不够),太细过萃发苦(信息过载)。研磨度就是 Skill 对上下文的裁剪策略
水温 92-96°C执行参数与上下文温度同一个豆子,88°C 和 96°C 出来的风味截然不同。Agent 的「温度」是它的推理自由度——保守任务低温,创意任务高温
闷蒸(30s 释放 CO₂)Overview 建立上下文不闷蒸直接注水,咖啡粉会翻滚不均匀。不写 Overview 直接执行,Agent 会缺少全局视角
分段注水(3-4 段)分阶段执行步骤一段水冲到底是最粗暴的方式。分阶段注水让每一段都有明确的萃取目标,Skill 的每一步也应该有明确的子目标
滤纸输出过滤与质量把关滤纸挡住细粉和油脂,只让干净的咖啡液通过。Skill 的输出格式约束就是那层滤纸
电子秤(精度 0.1g)可观测性与度量不称量就没有一致性。Skill 的验证清单就是你的电子秤
通道效应(局部穿透)执行偏差、漏步骤水流只走阻力最小的路径,其他区域被绕过。Agent 跳过关键步骤时,就是在发生「通道效应」
杯测记录Verification Checklist喝完记下来,下次对比。没有记录,进步就是幻觉
烘焙师笔记(标注瑕疵)Common Pitfalls「这支豆子浅烘容易夹生」「二爆后降温要快」——每一条都是一次翻车的学费
新豆 Dial-inSkill 调优与迭代每换一支新豆子都要重新找参数。新场景下的 Skill 也需要 Dial-in,不可能开箱即用

冲煮步骤:一杯咖啡的执行生命周期

下面用冲一杯耶加雪菲的完整流程,映射 Skill 从触发到验证的完整生命周期。

第一步:称重——触发条件匹配

咖啡师拿起豆子,看一眼标签:
  - 产地:埃塞俄比亚 耶加雪菲
  - 处理法:水洗
  - 烘焙度:浅中烘
  - 烘焙日期:7 天前

→ 匹配到配方:浅烘水洗耶加,标准参数

Agent 收到一个请求,首先做的是 意图识别与 Skill 匹配

# generated by hugo AI
@dataclass
class SkillTrigger:
    """Skill 的触发条件声明"""
    keywords: list[str]          # 关键词匹配
    context_patterns: list[str]  # 上下文模式匹配
    negative_signals: list[str]  # 排除条件
    
    def matches(self, request: str, context: dict) -> bool:
        # 类似咖啡师看豆子标签——
        # 不是所有豆子都适合手冲,不是所有请求都适合这个 Skill
        if any(neg in request for neg in self.negative_signals):
            return False
        return any(kw in request for kw in self.keywords)

关键洞察:称重不是形式主义。用错了配方,后面每一步都是浪费。Skill 的 When to Usedescription 字段就是你的豆子标签——写不清楚,就会被错误匹配。

第二步:研磨——信息预处理

研磨度决定了咖啡粉颗粒的大小分布,直接影响萃取速率。

太粗(French Press 级) → 萃取不足 → 酸涩、单薄
太细(Espresso 级)     → 过度萃取 → 苦涩、焦味
刚好(中细,如白砂糖)   → 均衡萃取 → 风味清晰

Skill 对信息的处理完全一样:

  • 太粗:只给 Agent 一个模糊的指令「帮我写个方案」,没有背景、没有约束、没有示例。Agent 只能凭默认参数硬猜
  • 太细:塞进去 50 页文档、20 个链接、100 条规则。Agent 上下文溢出,重要信息被淹没
  • 刚好:结构化的上下文,关键约束明确,有 1-2 个示例做锚点
信息粒度光谱:

模糊指令 ←──────────────────────────→ 信息过载
"写个方案"    结构化上下文        50页文档+20个链接
              最佳萃取点
           (白砂糖级研磨)

第三步:闷蒸——Overview 注入

闷蒸是手冲咖啡中最容易被新手忽略,却对最终风味影响最大的步骤。

30 秒的少量注水,让咖啡粉充分吸水膨胀,释放 CO₂。不闷蒸的后果:

  • 咖啡粉中的气体会阻碍水与粉的接触
  • 水流会寻找阻力最小的路径(通道效应)
  • 萃取不均匀,风味模糊

Skill 的 Overview 就是闷蒸。它的职责是:

  1. 建立全局上下文——这个 Skill 解决什么问题?在什么场景下用?
  2. 释放「认知气体」——让 Agent 理解整体目标,避免后续步骤中迷失方向
  3. 防止通道效应——没有 Overview,Agent 会直接跳到看起来最像答案的路径,绕过真正重要的步骤

一份好的 Overview 不超过 3 句话,但能让后续所有步骤的「萃取效率」提升一个量级。

第四步:第一段注水——主流程启动

闷蒸结束后,第一段注水开始。这段水通常占总水量的 40-50%,目标是建立基础萃取。

映射到 Skill:这是 核心执行步骤

注水手法:从中心开始,缓慢画圈向外扩展
映射到 Skill:从最确定的步骤开始,逐步扩展到边界情况

为什么要从中心开始?因为中心区域的咖啡粉最密集,萃取效率最高。同样,Skill 的核心步骤应该从最有把握的路径开始——先解决 80% 的场景,再处理 20% 的边缘。

第五步:分段注水——条件分支

第二段、第三段注水,每一段都有明确的目的:

注水段咖啡目标Skill 映射
第一段建立基础萃取核心流程(happy path)
第二段提升甜感与醇厚度补充细节、增加深度
第三段调整平衡、控制尾韵边界处理、异常兜底
断水避免过度萃取终止条件、防止 over-engineering

分段注水的精髓是 节奏控制。每段之间有间隔,让水有时间渗透。Skill 的步骤之间也需要「呼吸」——给 Agent 留出推理空间,而不是塞满指令。

第六步:断水——终止条件

总水量到了就停,不要「再加一点点」。

过度萃取的咖啡又苦又涩,所有好风味都被坏风味覆盖了。过度执行的 Skill 也一样——做了太多不必要的事情,反而把正确的结果搞砸了。

断水信号(咖啡)          断水信号(Skill)
─────────────          ─────────────
目标水量已达到           验证清单全部通过
萃取时间到达上限          执行时间/步骤数到达上限
咖啡液颜色变浅           输出已经满足要求
                          Agent 开始「发挥创造力」 ← 危险信号

第七步:杯测——验证

冲完之后,喝一口。

这不是客套,这是工程验证。杯测表上的每一个维度都是一项检查:

杯测维度验证问题Skill 验证清单
香气闻起来像这支豆子该有的味道吗?输出格式正确吗?
酸质酸是明亮的还是尖锐的?核心功能实现了吗?
醇厚度Body 是否足够?内容深度够吗?
余韵喝完之后嘴里舒服吗?用户拿到这个结果能直接用吗?
平衡感酸甜苦是否协调?有没有过度执行或遗漏?
干净度有没有杂味?有没有幻觉或多余信息?

没有 Verification Checklist 的 Skill,就像没有杯测记录的咖啡师——冲了一千杯,不知道哪杯好喝。

Common Pitfalls

翻车案例对照。每一条都是学费。

1. 参数写死,不考虑豆子差异

咖啡:用曼特宁的参数(96°C、中粗研磨)冲耶加雪菲。结果:浅烘豆萃取不足,又酸又寡淡。

Skill:把特定项目的路径、命令硬编码到 Skill 里。换个项目就全盘失效。

修正:Skill 应该声明参数范围,而不是固定值。就像好的咖啡配方会说「浅烘 92-94°C,深烘 88-90°C」,而不是「一律 92°C」。

2. 没有闷蒸,直接闷头冲

咖啡:跳过闷蒸,大水直接浇下去。咖啡粉翻滚、通道效应、萃取不均。

Skill:不写 Overview,直接列步骤。Agent 缺少全局视角,只机械执行每一步,不知道为什么要这么做,遇到异常情况无法判断。

修正:Overview 是闷蒸,不是废话。用 2-3 句话告诉 Agent 这个 Skill 的目标、适用场景和核心逻辑。

3. 研磨度不对,信息粒度失控

咖啡:用 Espresso 的极细粉做手冲。滤杯堵塞,水漫过粉层,苦涩到无法入口。

Skill:在 Skill 里塞进太多细节——完整的 API 文档、所有历史决策、每种边缘情况的处理方式。Agent 的上下文窗口被撑满,重要信息反而被淹没。

修正:核心信息放 SKILL.md,详细参考放 references/。就像磨豆机有不同档位,信息也应该按需取用。

4. 通道效应——步骤被跳过

咖啡:注水时只冲中心,边缘的咖啡粉完全没被浸润。水从中心「通道」直接流下去,只萃取了一小部分。

Skill:步骤之间的依赖关系没有明确标注。Agent 觉得某一步「不需要」就跳过了,结果后续步骤因为缺少前置条件而失败。

修正:用编号步骤 + 显式依赖声明。如果 Step 3 依赖 Step 2 的输出,就写清楚「使用 Step 2 的结果作为输入」。

5. 不断水,过度萃取

咖啡:明明目标水量已经到了,觉得「再冲一点更浓」,结果尾段全是苦味和涩味。

Skill:验证清单都通过了,还继续执行「优化」「美化」「增强」。画蛇添足,把好的结果搞砸了。

修正:验证清单全部通过 = 立即停止。Skill 的终止条件和启动条件一样重要。

6. 不记录,不迭代

咖啡:冲完就喝,喝完就忘。下次换一支豆子,又从开盲盒开始。

Skill:写完第一版就再也不看。场景变了、工具更新了、发现新的坑了——Skill 还是老样子,越来越不准。

修正:每次使用 Skill 后,如果发现新坑或更好的做法,立刻 patch。Skill 的生命力在于持续迭代,和咖啡师不断调整配方一样。

Verification Checklist

一份合格的 Skill(一杯合格的咖啡),应该满足:

  • 触发条件明确——不是所有豆子都该用这个配方
  • Overview 清晰——2-3 句话建立全局视角(闷蒸充分)
  • 信息粒度合适——不粗不细,白砂糖级研磨
  • 步骤有序、依赖明确——没有通道效应
  • 有终止条件——到了就停,不过度萃取
  • 验证清单完整——每个维度都有对应的检查项
  • Pitfalls 来自真实翻车——不是想象的,是喝过苦头写下来的
  • 可迭代——留了 patch 的接口,不是一次性配方

One-Shot Recipe:一份完整的手冲 Skill

把上面的所有映射,收束成一份可以直接使用的 Skill。它既是冲一杯耶加雪菲的配方,也是设计任何 Skill 的模板。

---
name: pour-over-yirgacheffe
description: >
  Use when brewing light-roast washed Ethiopian coffee.
  Produces a clean, bright cup with floral and citrus notes.
version: 1.0.0
---
# 手冲耶加雪菲(浅烘水洗)

## Parameters
- 豆量:15g
- 水量:225g(粉水比 1:15)
- 水温:93°C(浅烘偏低,保留花香)
- 研磨度:中细(EK43 刻度 7.5)
- 总时间:2:30 - 3:00

## Steps

1. 称重 & 研磨
   → 确认豆子信息,匹配研磨度

2. 闷蒸(0:00 - 0:30)
   → 注入 30g 水,等待 30s
   → 观察:粉层是否均匀膨胀?有没有干点?

3. 第一段注水(0:30 - 1:00)
   → 中心画圈注水至 120g
   → 目标:建立基础萃取

4. 第二段注水(1:10 - 1:30)
   → 注水至 180g
   → 目标:提升甜感

5. 第三段注水(1:40 - 2:00)
   → 注水至 225g
   → 目标:调整平衡

6. 断水 & 等待滴完
   → 总时间不超过 3:00

## Verification
- [ ] 香气:有明显花香或柑橘调
- [ ] 酸质:明亮、活泼,不尖锐
- [ ] 醇厚度:中等偏轻,干净
- [ ] 余韵:甜感持续,无涩味
- [ ] 总时间:2:30 - 3:00 范围内

## Pitfalls
1. 水温超过 95°C → 花香被烫死,苦味出来
2. 研磨太细 → 流速过慢,过萃
3. 不闷蒸 → 通道效应,萃取不均
4. 第三段注水太猛 → 搅动细粉到滤杯底部,尾段浑浊

这份配方本身就是一份合格的 Skill:有参数声明、有分步骤、有条件判断、有验证清单、有翻车记录。

写在最后

手冲咖啡和 AI Skill 设计,看似风马牛不相及,底层是同一套工程思维:

把不确定性变成可控参数,把个人直觉变成可复制流程,把一次性成功变成持续稳定输出。

咖啡师不会永远用同一个配方——每支新豆子都需要 Dial-in。Skill 也不会永远有效——场景变了就要 patch。真正的专业能力,不是记住一个配方,而是掌握「从零开始调出一杯好咖啡」的方法论。

下次写 Skill 的时候,想象自己在冲一杯咖啡。先看看手里的「豆子」是什么,选对「研磨度」,别忘了「闷蒸」,控制好「注水节奏」,该「断水」就断水,最后认真「杯测」一次。

你的 Agent 会感谢你。就像你的味蕾会感谢一杯认真冲煮的耶加雪菲。


你写 Skill 的时候,有没有遇到过「通道效应」?欢迎在评论区分享你的翻车记录。


See also