BeanWhisperer — Espresso Profile Generator
Generate and deploy espresso profiles for GaggiMate Pro on a Rancilio Silvia. Based on Lance Hedrick's espresso methodology.
Machine Setup
- - Machine: Rancilio Silvia with GaggiMate Pro (pressure transducer + flow profiling)
- Host:
gaggimate.local — WebSocket at ws://gaggimate.local/ws (override with GAGGIMATE_HOST env var) - Scale: Bluetooth scale connected (volumetric targets reliable)
- Baskets: 18g and 20g available
- Temp offset: 5°C configured in GaggiMate (profile temps = desired brew temp)
Methodology: Lance Hedrick's Approach
Read references/lance-hedrick-methodology.md for the full framework. Key principles:
- 1. Pressure is a red herring — balance > 9 bar. 2-4 bar shots win competitions.
- Ratio is #1 extraction lever — extend ratio before going finer.
- Coarser is default direction — more even flow, less channeling.
- Temperature: lower than you think — default 90°C, rarely above 93-94.
- Heavily processed = gentle — low temp, coarser, moderate ratio.
- Aged coffee = accept low pressure — don't go finer to compensate.
Workflow: New Bean → Profile
1. Identify the Bean
Photo: Extract bean name, roaster, origin, roast level, processing method, tasting notes.
Name: Search web for origin, roast, process, flavor notes.
2. Search Discord Community
Always check the community first. A battle-tested profile tweaked for this bean is the best starting point.
CODEBLOCK0
Download the best candidate and evaluate it against the bean's characteristics. Then decide:
- - Good fit: Tweak the community profile — adjust temp, ratio, dose, or stop conditions to match this specific bean. Always tweak; never push a community profile unmodified (every bean is different).
- No good fit (nothing relevant, or you're confident you can do better for this bean): Skip to step 3 and generate from scratch.
3. Gather Parameters (ask if not provided)
- - Basket size: 18g or 20g (auto-recommend based on roast)
- Ratio: Auto per Lance's rules (light=1:2.8, medium=1:2.2, dark=1:1.7)
- Style: espresso, ristretto, lungo, milk drink, allongé
- Freshness: fresh (<4wk), rested (4-8wk), aged (>8wk)
4. Generate or Tweak Profile
If tweaking a community profile (from step 2):
Modify the downloaded JSON directly — adjust temperature, phases[].pump.pressure, phases[].pump.flow, ratio (volumetric target values), or dose. Use the Lance Hedrick methodology to decide what to change for this specific bean. Save the modified profile to /tmp/profile.json.
If generating fresh (no good Discord match):
Static mode (default — fast, deterministic, schema-compliant):
CODEBLOCK1
LLM mode (for edge cases, unusual beans, taste-based iteration):
Read references/barista-persona.md and adopt the Lance Hedrick persona defined in the system prompt section. Reason about the bean as that persona, decide parameters, then pass to the static generator for valid JSON. Always explain the "why" behind every choice using the sour-sweet-bitter framework. For post-shot iteration, stay in persona and adjust based on taste feedback.
5. Review with User
Present: strategy, phases, temperature, dose/ratio, expected shot time, expected pressure. Explain WHY this strategy suits their bean using the sour-sweet-bitter framework. Be honest about trade-offs. If based on a community profile, credit the original author.
6. Deploy to Machine
python3 scripts/gaggimate-ws.py push /tmp/profile.json
Saves + favorites + selects in one step. Requires
pip3 install websockets.
7. Post-Shot Iteration (LLM mode)
If user reports taste feedback ("it was sour", "bitter finish", "too thin"):
- - Sour → extend ratio 5g, DON'T go finer first
- Bitter/dry → reduce ratio or recommend coarser grind
- Sour + bitter (channeling) → go COARSER (counterintuitive!)
- Thin/watery → slightly finer, or switch from turbo to lever
- Generate adjusted profile and push
Strategy Selection (Lance's Framework)
| Roast | Process | Freshness | Strategy | Pressure | Time |
|---|
| Light | Washed | Fresh | Bloom | 6-7 bar | 25-30s |
| Light |
Natural | Fresh | Turbo | 2-6 bar | 15-20s |
| Light | Any | Aged | Turbo | 2-4 bar | 15-20s |
| Med-Light | Washed (African) | Fresh | Bloom | 6-7 bar | 25-30s |
| Med-Light | Washed (other) | Fresh | Lever | 8-9→6 bar | 30-40s |
| Medium | Any | Fresh | Lever | 9→6 bar | 30-40s |
| Med-Dark | Any | Fresh | Declining | 9→5.5 bar | 25-35s |
| Dark | Any | Fresh | Declining | 9→5.5 bar | 20-25s |
| Any | Anaerobic/Co-ferment | Any | Turbo | 3-6 bar | 15-20s |
Profile Management
CODEBLOCK3
Edge Cases
- - Machine offline: If
gaggimate-ws.py fails with a connection error, tell the user to check that GaggiMate is powered on and reachable at the configured host. Suggest saving the profile JSON locally and pushing later. - Invalid/unclear bean photo: If the photo is unreadable or not clearly a coffee bag, ask the user to provide bean details manually (roast, origin, process).
- No Bluetooth scale connected: Volumetric stop conditions (
targets.type: "volumetric") require a scale. If the user has no scale, switch to time-based stops by removing volumetric targets and relying on phase duration values instead. - GaggiMate Standard (not Pro): If the user has GaggiMate Standard (no pressure transducer), generate
"type": "standard" profiles with only temperature and time — no pressure/flow phases.
References
- - Lance Hedrick methodology:
references/lance-hedrick-methodology.md — full framework with temp/ratio/pressure rules - LLM barista persona:
references/barista-persona.md — system prompt for LLM-driven profile generation - Espresso knowledge base:
references/espresso-knowledge.md — origin/process/strategy details - Profile JSON schema: INLINECODE17
- WebSocket API: INLINECODE18
Discord Profile Research
The GaggiMate Discord has a #profiles channel where users share JSON profiles (like the Sir Lancelot's Lever profile Lance imported in his video). Use discord-profiles.py to search, browse, and download community profiles.
Requires: DISCORD_TOKEN env var (bot token with access to GaggiMate Discord guild 951416527721230336).
CODEBLOCK4
Discord → Machine Workflow
- 1. Search/recommend profiles matching the user's bean
- Download the best candidates
- Present them with descriptions
- User picks one → optionally modify (temp, ratio, stop conditions) for their specific bean
- Push modified profile to machine via INLINECODE22
When to Generate Fresh Instead of Tweaking Discord
Discord search (step 2) is always the first action. Only generate from scratch when:
- - No community profiles match the bean type
- The bean is unusual enough that a community profile would need so many changes it's easier to start fresh
- You're confident the generator will produce a better result for this specific bean
- The user explicitly asks for a custom profile
BeanWhisperer — 浓缩咖啡参数生成器
为Rancilio Silvia上的GaggiMate Pro生成并部署浓缩咖啡参数。基于Lance Hedrick的浓缩咖啡方法论。
机器设置
- - 机器: 配备GaggiMate Pro的Rancilio Silvia(压力传感器+流量曲线控制)
- 主机: gaggimate.local — WebSocket地址 ws://gaggimate.local/ws(可通过GAGGIMATE_HOST环境变量覆盖)
- 秤: 已连接蓝牙秤(体积目标值可靠)
- 粉碗: 18g和20g可用
- 温度偏移: GaggiMate中配置为5°C(参数温度 = 目标冲泡温度)
方法论:Lance Hedrick的方法
阅读 references/lance-hedrick-methodology.md 了解完整框架。关键原则:
- 1. 压力是干扰项 — 平衡 > 9巴。2-4巴的萃取在比赛中获胜。
- 粉液比是首要萃取杠杆 — 先延长粉液比,再调细研磨。
- 粗研磨是默认方向 — 水流更均匀,通道效应更少。
- 温度:比你想象的低 — 默认90°C,很少超过93-94°C。
- 重度处理 = 温和萃取 — 低温、粗研磨、适中粉液比。
- 陈豆 = 接受低压 — 不要通过调细研磨来补偿。
工作流程:新豆 → 参数
1. 识别咖啡豆
照片: 提取咖啡豆名称、烘焙商、产地、烘焙度、处理法、风味描述。
名称: 搜索网络获取产地、烘焙度、处理法、风味信息。
2. 搜索Discord社区
始终先检查社区。针对该豆种调整过的经过实战检验的参数是最佳起点。
bash
python3 scripts/discord-profiles.py recommend <烘焙度> [<产地>]
python3 scripts/discord-profiles.py search <策略或关键词>
下载最佳候选参数,并根据咖啡豆特性进行评估。然后决定:
- - 匹配良好: 调整社区参数 — 针对该特定豆种调整温度、粉液比、粉量或停止条件。始终进行调整;切勿直接使用未修改的社区参数(每种豆子都不同)。
- 无匹配(无相关参数,或你有信心能为该豆种做得更好): 跳至第3步,从头生成。
3. 收集参数(如未提供则询问)
- - 粉碗尺寸: 18g或20g(根据烘焙度自动推荐)
- 粉液比: 根据Lance规则自动设定(浅烘=1:2.8,中烘=1:2.2,深烘=1:1.7)
- 风格: 浓缩、短萃取、长萃取、奶咖、慢速萃取
- 新鲜度: 新鲜(<4周)、适中(4-8周)、陈豆(>8周)
4. 生成或调整参数
如果调整社区参数(来自第2步):
直接修改下载的JSON — 调整temperature、phases[].pump.pressure、phases[].pump.flow、粉液比(体积目标值)或粉量。使用Lance Hedrick方法论决定针对该特定豆种需要更改的内容。将修改后的参数保存到/tmp/profile.json。
如果从头生成(Discord无匹配):
静态模式(默认 — 快速、确定性、符合模式):
bash
python3 scripts/generate-profile.py \
--label 咖啡豆名称 \
--roast <烘焙度> --origin <产地> --process <处理法> \
--dose <克数> --ratio <粉液比> --temp <温度> \
--strategy \
--style \
--freshness \
--output /tmp/profile.json
LLM模式(适用于边缘情况、特殊豆种、基于品味的迭代):
阅读 references/barista-persona.md,采用系统提示部分定义的Lance Hedrick角色。以该角色身份推理咖啡豆特性,决定参数,然后传递给静态生成器生成有效JSON。始终使用酸-甜-苦框架解释每个选择背后的原因。对于萃取后的迭代,保持角色身份,根据口感反馈进行调整。
5. 与用户复核
展示:策略、阶段、温度、粉量/粉液比、预期萃取时间、预期压力。使用酸-甜-苦框架解释为什么该策略适合他们的豆种。诚实地说明权衡取舍。如果基于社区参数,需注明原作者。
6. 部署到机器
bash
python3 scripts/gaggimate-ws.py push /tmp/profile.json
一步完成保存+收藏+选择。需要 pip3 install websockets。
7. 萃取后迭代(LLM模式)
如果用户反馈口感问题(太酸、苦尾、太淡):
- - 酸 → 延长粉液比5g,不要先调细研磨
- 苦/干涩 → 缩短粉液比或建议调粗研磨
- 酸+苦(通道效应)→ 调粗研磨(反直觉!)
- 淡/水感 → 略微调细,或从turbo切换为lever
- 生成调整后的参数并推送
策略选择(Lance的框架)
| 烘焙度 | 处理法 | 新鲜度 | 策略 | 压力 | 时间 |
|---|
| 浅烘 | 水洗 | 新鲜 | Bloom | 6-7巴 | 25-30秒 |
| 浅烘 |
日晒 | 新鲜 | Turbo | 2-6巴 | 15-20秒 |
| 浅烘 | 任意 | 陈豆 | Turbo | 2-4巴 | 15-20秒 |
| 中浅烘 | 水洗(非洲) | 新鲜 | Bloom | 6-7巴 | 25-30秒 |
| 中浅烘 | 水洗(其他) | 新鲜 | Lever | 8-9→6巴 | 30-40秒 |
| 中烘 | 任意 | 新鲜 | Lever | 9→6巴 | 30-40秒 |
| 中深烘 | 任意 | 新鲜 | Declining | 9→5.5巴 | 25-35秒 |
| 深烘 | 任意 | 新鲜 | Declining | 9→5.5巴 | 20-25秒 |
| 任意 | 厌氧/共发酵 | 任意 | Turbo | 3-6巴 | 15-20秒 |
参数管理
bash
python3 scripts/gaggimate-ws.py list # 显示所有参数
python3 scripts/gaggimate-ws.py get
# 导出参数JSON
python3 scripts/gaggimate-ws.py save profile.json # 上传但不选择
python3 scripts/gaggimate-ws.py delete # 删除参数
python3 scripts/gaggimate-ws.py push profile.json # 保存+收藏+选择
边缘情况
- - 机器离线: 如果 gaggimate-ws.py 因连接错误失败,告知用户检查GaggiMate是否已开机且可在配置的主机地址访问。建议将参数JSON保存在本地,稍后推送。
- 无效/不清晰的咖啡豆照片: 如果照片无法识别或明显不是咖啡袋,要求用户手动提供咖啡豆详细信息(烘焙度、产地、处理法)。
- 未连接蓝牙秤: 体积停止条件(targets.type: volumetric)需要秤。如果用户没有秤,通过移除体积目标值并依赖阶段duration值,切换为基于时间的停止条件。
- GaggiMate Standard(非Pro版): 如果用户使用GaggiMate Standard(无压力传感器),生成type: standard类型的参数,仅包含温度和时间 — 无压力/流量阶段。
参考资料
- - Lance Hedrick方法论: references/lance-hedrick-methodology.md — 包含温度/粉液比/压力规则的完整框架
- LLM咖啡师角色: references/barista-persona.md — 用于LLM驱动参数生成的系统提示
- 浓缩咖啡知识库: references/espresso-knowledge.md — 产地/处理法/策略详情
- 参数JSON模式: references/profile-schema.json
- WebSocket API: references/websocket-api.md
Discord参数研究
GaggiMate Discord有一个#profiles频道,用户在此分享JSON参数(如Lance在其视频中导入的Sir Lancelots Lever参数)。使用discord-profiles.py搜索、浏览和下载社区参数。