关于 pp-flight-goat
pp-flight-goat 是用于操作 Flight Goat Printing Press CLI 的技能,可查询机票、发现航线、查看里程票和机上 WiFi,并辅助评估航班延误。适用于旅行规划,其中消费者机票搜索等功能无需 API 密钥。
主要功能
- 01Google Flights 机票搜索
- 02低价日期扫描
- 03Kayak 航线发现
- 04FlySoar 价格比较
- 05里程票可用性查询
- 06机上 WiFi 信息
适用场景
- 01比较不同出行计划的票价
- 02查找旅行日期范围内的低价日期
- 03查看里程兑换选项
- 04出行前检查 WiFi 预测
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mvanhorn/ printing-press-library --skill pp-flight-goat安装后在 Claude Code 中输入/pp-flight-goat确认已加载。
详细介绍
Flight Goat — Printing Press 命令行界面
前置条件:安装命令行界面
此技能由 flight-goat-pp-cli 二进制文件驱动。调用此技能中的任何命令之前,必须先确认命令行界面已安装。 如果尚未安装,请先安装:
- 通过 Printing Press 安装程序安装。默认情况下,二进制文件会安装到 macOS/Linux 上的
$HOME/.local/bin,以及 Windows 上的%LOCALAPPDATA%\Programs\PrintingPress\bin:npx -y @mvanhorn/printing-press-library install flight-goat --cli-only - 验证:
flight-goat-pp-cli --version - 确保报告的安装目录位于将调用此技能的 Agent/运行时的
$PATH中。
如果 npx 安装失败(没有 Node、处于离线状态等),请改用直接通过 Go 安装(需要 Go 1.26.9 或更新版本)。此方式会安装到 $GOPATH/bin(默认是 $HOME/go/bin),因此请将该目录添加到 $PATH:
go install github.com/mvanhorn/printing-press-library/library/travel/flight-goat/cmd/flight-goat-pp-cli@latest
如果安装后 --version 报告“command not found”,说明运行时无法在 $PATH 中找到二进制文件目录。验证成功之前,不要继续执行技能命令。
独特功能:无需 API 密钥即可搜索机票价格
主要命令会直接查询面向消费者的票价来源,无需凭据——不要将此命令行界面描述为必须使用 AeroAPI。FlightAware AeroAPI(下文有介绍)是次要的可选功能。
flight-goat-pp-cli flights <origin> <destination> <date>— Google Flights 票价搜索:真实价格、航段和航空公司。使用--return搜索往返行程,使用重复的--segment搜索多城市行程,使用重复的--trip批量探测。flight-goat-pp-cli dates <origin> <destination>— 扫描出行日期范围,查找最低价日期。flight-goat-pp-cli explore <airport>/flight-goat-pp-cli longhaul <airport>— 探索 Kayak 直飞和长途航线。flight-goat-pp-cli soar <origin> <destination> <date>— 通过 FlySoar(Duffel NDC/GDS)提供第二份价格参考,并支持跳转预订。flight-goat-pp-cli award <origin> <destination>— 查询 Seats.aero 奖励机票(里程)可用性:查看不同舱位的里程加税费兑换选项。支持以逗号分隔的机场和--cabin列表。需要SEATS_AERO_API_KEY(符合条件的 Seats.aero Partner API 密钥);商业 API 使用需要获得 Seats.aero 的书面许可。此功能仅供读取。flight-goat-pp-cli wifi flight <flightNumber>/wifi airline <IATA>/wifi airlines/wifi rollouts [IATA]/wifi speed <flight>/wifi airline-speed <IATA>/wifi search <query>— SeatWifi 机上 WiFi 预测、Starlink 部署状态和众包速度报告。无需 API 密钥。 数据来自 https://seatwifi.com 上的公开 JSON。此功能仅供读取。flight-goat-pp-cli assess— 航班延误和改签决策支持。
每个结果中的预订深层链接 booking_urls 均采用搜索所用的 --currency 报价。award 是例外:它提供里程/积分报价,而非现金价格,也不会生成预订深层链接。
批量票价探测:使用 --trip 和 --pace,切勿使用 shell 循环
Google 会按 IP 对票价查询流量进行限速。在 shell 循环中并行调用 flights 会触发 HTTP 429 阻断,持续时间可能超过 15 分钟。请改为在一次调用中使用节奏控制来批量探测:
# Three independent searches, 3s apart, one JSON envelope with per-trip rows
flight-goat-pp-cli flights \
--trip "SEA>DEN@2026-09-14" \
--trip "PDX>DEN@2026-09-15@2026-09-17" \
--trip "SFO>DEN@2026-09-15" \
--pace 3s --currency EUR --agent
--trip 接受 ORIG>DEST@DEPART 或 ORIG>DEST@DEPART@RETURN(语法类别与 --segment 相同),并取代位置参数;所有筛选标志(--currency、--stops、--class、--airlines、--time、--return-time、--passengers)均应用于每次行程。每次行程的结果行会写入响应封装的 results[],其 status 为 ok/error/skipped。
往返行程可以分别限制每段行程的出发时间范围:--time 设置去程时间范围,--return-time 设置返程时间范围(若未设置,则沿用 --time)。两者都采用相同的 H-H 24 小时格式,例如 flight-goat-pp-cli flights SEA HNL 2026-08-01 --return 2026-08-10 --time 6-12 --return-time 17-23 表示去程在早上出发、返程在晚上出发。
往返行程:仅使用 --return 不会返回返程航班选项
仅使用 --return 时,只会显示去程行程。每个行程的 price 已包含 Google 自动选出的“最低价返程”的总价,但不会显示任何返程航班信息(时间、航空公司、时长)——不要将去程列表理解为包含两个方向,也不要认为价格仅针对去程航段。
如需查看并选择实际的返程航班选项,请运行 Google 界面所用的真正两步流程。第 1 步,flight-goat-pp-cli flights LHR BCN 2027-03-01 --return 2027-03-18 --agent 会返回去程选项,其中 flights[0].direction == "outbound"——请记下你想要的航班在列表中的 1 起始位置。第 2 步,flight-goat-pp-cli flights LHR BCN 2027-03-01 --return 2027-03-18 --select-outbound 1 --agent 会返回以该特定去程航班为基础定价的实际返程选项:此时 flights[] 中的 direction == "return",并且返程有独立价格;结果封装对象中的 selected_outbound 会回显与这些返程航班配对的去程航班。
--select-outbound N 使用 1 起始的位置,按第 1 步返回的顺序计数。它必须与 --return(仅限往返行程)一起使用,且不能与 --trip 或 --segment(>=2)组合使用。往返行程的每条去程 Flight 记录还包含 selection_token——该值与 CLI 内部用于构造第 2 步请求的值相同,供自行构建选择流程而不是使用固定索引的调用方使用。
速率限制语义:
- 临时出现的 429 会自动重试(采用 2s/5s/12s 间隔),然后命令才会失败。
- 持续出现 429 时,批处理会提前停止——继续请求会加重 IP 封锁;仍会输出部分结果封装对象,退出代码为 7(速率受限)。
- Google 被封锁期间,
soar和explore/longhaul使用不同后端,因此仍可正常工作;doctor在google_flights下说明了相同约定。
往返最低价日期:dates --round --duration
默认情况下,dates 会扫描单程价格。添加 --round --duration N 可改为扫描往返总价——每一行都是该日出发、N 晚后返程的最低往返组合价格,而不是单独的去程/返程价格对:flight-goat-pp-cli dates SEA HNL --round --duration 7 --sort --agent。--round 必须搭配 --duration,且其值必须大于零。每条结果行都会在 price 旁附带 return_date(departure_date + --duration),其中 price 已是往返总价。
简介
AeroAPI 是一个简单的查询式 API,可让软件开发者访问 FlightAware 的各类航班数据。用户可以获取当前或 历史数据。AeroAPI 是一个 RESTful API,可提供准确且 可供决策使用的航空数据。随着 Foresight™ 的推出,客户 可以访问支撑美国过半数预测航空公司 ETA 的数据。
类别
AeroAPI 分为几个类别,便于查找。
- 航班:摘要信息、计划航线、位置等
- Foresight:通过 FlightAware Foresight™ 增强的航班位置数据
- 机场:机场信息和 FIDS 风格的资源
- 运营方:运营方信息和机队活动资源
- 警报:配置航班警报和发送目的地
- 历史:访问各类端点的历史航班数据
- 其他:航班中断、未来时刻表信息和飞机所有者信息
开发工具
AeroAPI 使用 OpenAPI Spec 3.0 定义,因此可以轻松导入 Postman 等工具。请尝试按照 Postman 的说明 导入 API 规范,开始使用。 导入为集合后,只需在集合的 Authorization 选项卡中填写并保存“Value”字段, 即可发起调用。
AeroAPI OpenAPI 规范位于:
https://flightaware.com/commercial/aeroapi/resources/aeroapi-openapi.yml
我们的开源 AeroApps 项目 提供了一小组服务和示例应用,帮助你快速上手。
Flight Information Display System (FIDS) AeroApp 是一个使用多种语言和 Docker 容器的 多层应用示例。它展示了连接、数据缓存、航班信息展示以及航班地图的应用。
Alerts AeroApp 演示了如何在示例应用中使用 AeroAPI 设置、编辑和接收警报。该应用包含 使用 Docker 的 Python 后端和 React 前端。
我们的 AeroAPI 推送通知测试界面 提供了一种快速、便捷的方式,用于测试通过 AeroAPI 推送发送自定义警报。
命令参考
aircraft — 管理航空器
flight-goat-pp-cli aircraft <type>— 根据 ICAO 航空器型号代码字符串,返回航空器型号信息。
airports — 管理机场
flight-goat-pp-cli airports get— 根据 ICAO 或 LID 机场代码(例如 KLAX、KIAH、O07 等)返回机场信息。flight-goat-pp-cli airports get-all— 返回所有已知机场的 ICAO 标识符。flight-goat-pp-cli airports get-delays-for-all— 返回有延误的机场列表。flight-goat-pp-cli airports get-nearby— 返回指定位置一定距离范围内的机场列表。
alerts — AeroAPI 警报功能可用于配置和接收有关关键航班事件的实时警报。AeroAPI 的警报端点支持自定义警报, 让用户能够选择要接收警报的各类事件/筛选条件。这样一来, 你便可以接收针对特定事件量身定制的警报,例如已提交的飞行计划、 航班起飞(离地和起飞)及航班到达(着陆和进场)等!
要开始使用警报功能,必须先使用 PUT /alerts/endpoint 端点 设置账户级默认 URL,用于接收警报。必须先完成此步骤, 才能配置任何警报。该 URL 将作为备用 URL:如果某个警报没有指定专用的 发送 URL,账户的所有警报都会发送到此 URL。如果在配置警报前未完成此操作, 尝试调用 POST /alerts 端点时将收到 400 错误,并附有提醒你完成此步骤的错误消息。 使用 PUT /alerts/endpoint 端点设置 URL 后, 即可通过 POST /alerts 端点配置警报。你也可以使用 GET /alerts 端点 获取与 AeroAPI 密钥关联的所有当前已配置警报。 GET /alerts 端点还可帮助你轻松获取账户中已配置的特定目标警报的 ID, 随后你可以使用 GET PUT 和 DELETE /alerts/{id} 端点检索、更新和删除特定警报。 配置单个警报时,target_url 字段可以设置为不同于通过 PUT /alerts/endpoint 设置的账户级目标端点的 URL。如果在警报中设置了 target_url 字段,该警报就会发送到指定的 target_url,而不是默认的账户级端点。如果未为警报配置此字段,则警报会发送到默认的账户级端点。设置此字段后,可以轻松地将不同警报发送到不同端点,这对于配置各应用程序的警报,或在无需调整生产环境警报配置的情况下将警报发送到备用开发环境,非常有用。
对于配置的每个警报,都可以设置一个或多个用于发送警报的“事件”。大多数事件会发送一条警报,但 arrival 和 departure 事件都可能发送多条警报(称为捆绑警报)。departure 事件会将起飞(实际离地)警报与已提交飞行计划的警报,以及最多 5 条起飞相关变更警报捆绑发送;这些变更警报可能包括超过 30 分钟的显著起飞延误、登机口变更和机场延误。FlightAware Global 客户还会在起飞警报捆绑中收到 Power on 和 Ready to taxi 警报。arrival 事件会将抵达(实际着陆)警报与最多 5 条已识别的航路变更(包括超过 30 分钟的延误,但不包括备降)捆绑发送。FlightAware Global 客户还会在 arrival 警报捆绑中收到 taxi stop 时间。对于 On/Off,如果设置了捆绑类型和非捆绑类型,而事件可能重叠,则只会发送一条警报。
如果需要更改警报配置,建议使用 PUT /alerts/{id} 端点和唯一警报标识符(id)更新警报,而不是创建另一个警报。这样可以避免发送重复警报;如果这些警报不再受关注,重复通知可能会造成不必要的干扰。
如果需要删除警报,可以使用 DELETE alerts/{id} 端点删除警报,使其不再发送。提醒一下,可以通过 GET /alerts 端点获取特定警报 ID。
flight-goat-pp-cli alerts create— 创建新的 AeroAPI 航班警报。flight-goat-pp-cli alerts delete— 删除指定 ID 的警报flight-goat-pp-cli alerts delete-endpoint— 移除默认账户级 URL;未配置特定 URL 的警报会通过 POST 发送到该 URL。flight-goat-pp-cli alerts get— 返回指定 ID 警报的配置数据。flight-goat-pp-cli alerts get-all— 返回 FlightAware 账户的所有已配置警报(包括通过其他方式配置的警报)flight-goat-pp-cli alerts get-endpoint— 返回通过 AeroAPI 发送的警报所 POST 到的 URL。flight-goat-pp-cli alerts set-endpoint— 更新通过 AeroAPI 发送的警报所 POST 到的默认 URL。flight-goat-pp-cli alerts update— 修改指定 ID 警报的配置。
disruption-counts — 管理中断计数
flight-goat-pp-cli disruption-counts get— 返回指定航空公司或机场在指定时间段内的航班取消/延误次数。flight-goat-pp-cli disruption-counts get-all— 返回所有航空公司或所有机场在指定时间段内的总体航班取消/延误次数。
flights — 管理航班
flight-goat-pp-cli flights get— 返回指定注册号、航班标识或 fa_flight_id 的航班信息状态摘要。flight-goat-pp-cli flights get-by-advanced-search— 根据地理空间搜索参数,返回当前或近期处于飞行状态的航班。flight-goat-pp-cli flights get-by-position-search— 根据地理空间搜索参数,返回航班位置。flight-goat-pp-cli flights get-by-search— 通过匹配多种参数(包括地理空间数据)来搜索处于飞行状态的航班。flight-goat-pp-cli flights get-count-by-search— 完整的搜索查询文档请参阅 /flights/search 端点。
foresight — Foresight 端点可访问 FlightAware 的 Foresight 预测模型和关键事件预测。我们的高级机器学习(ML)模型可识别影响航班的关键因素,从而实时预测未来事件,为提升运营效率并促进空中和地面的更好决策提供前所未有的洞察。要进一步了解 Foresight 的强大功能,请访问 https://www.flightaware.com/commercial/foresight/
这些端点分别对应功能类似的非 Foresight 端点,并在 Foresight 响应中额外包含所有 ML“预测”值。相应的非 Foresight 端点响应中包含一个标志 foresight_predictions_available,可选择将其用作触发条件,按需获取和利用 Foresight 预测并管理成本。Foresight 仅面向 Premium 级别客户提供。如需了解更多信息、价格详情以及启用账户的相关事宜,请联系 [email protected]。
flight-goat-pp-cli foresight get-flight-position-with— 获取航班的当前位置,包括 Foresight 数据flight-goat-pp-cli foresight get-flight-with— 返回指定注册号、航班标识或 fa_flight_id 的航班信息状态摘要flight-goat-pp-cli foresight get-flights-by-advanced-search-with— 根据地理空间搜索参数,返回当前或近期处于飞行状态的航班。
history — 管理历史记录
flight-goat-pp-cli history get-aircraft-last-flight— 根据飞机的注册号,返回其最后一次已知航班的航班信息状态摘要。flight-goat-pp-cli history get-flight— 返回指定注册号、航班标识或 fa_flight_id 的历史航班信息状态摘要。flight-goat-pp-cli history get-flight-map— 返回历史航班的航迹,格式为 Base64 编码的图像。flight-goat-pp-cli history get-flight-route— 返回有关历史航班申报航线的信息,包括坐标和名称flight-goat-pp-cli history get-flight-track— 将历史航班的航迹作为位置数组返回。
operators — 管理运营方
flight-goat-pp-cli operators get— 返回运营方的信息,例如名称、ICAO/IATA 代码、总部所在地等。flight-goat-pp-cli operators get-all— 返回运营方参考信息列表(ICAO/IATA 代码以及用于访问更多信息的 URL)。
schedules — 管理时刻表
flight-goat-pp-cli schedules— 返回航空公司已发布的定期航班。
查找合适的命令
知道要做什么,但不知道该用哪个命令时,可以直接询问 CLI:
flight-goat-pp-cli which "<capability in your own words>"
which 会根据自然语言能力查询,从此 CLI 精选的功能索引中匹配最合适的命令。退出代码 0 表示至少找到一个匹配项;退出代码 2 表示没有可信的匹配项,此时请改用 --help 或使用范围更窄的查询。
身份验证设置
运行 flight-goat-pp-cli auth setup,打印获取密钥的 URL 和步骤(添加 --launch 可打开 URL)。然后设置:
export FLIGHT_GOAT_API_KEY="<your-key>"
如需持久保存凭据,请使用 flight-goat-pp-cli auth set-token <token>。存储的机密信息位于数据目录下的 credentials.toml 中,而不在 config.toml 中。
运行 flight-goat-pp-cli doctor 验证设置。
Agent 模式
在任意命令中添加 --agent。它会展开为:--json --compact --no-input --no-color --yes。
-
可通过管道传输 — JSON 输出到 stdout,错误输出到 stderr
-
可筛选 —
--select保留字段子集。点分隔路径可深入嵌套结构;数组会逐元素遍历。对于冗长 API,这对缩小上下文至关重要:flight-goat-pp-cli airports get mock-value --agent --select id,name,status -
可预览 —
--dry-run显示请求,但不发送 -
支持离线 — 可用时,同步/搜索命令可以使用本地 SQLite 存储
-
非交互式 — 绝不提示输入,每项输入都通过标志传入
-
显式重试 — 仅当已存在的创建操作应视为成功时才使用
--idempotent;仅当删除目标不存在也应视为成功时才使用--ignore-missing
响应封装
从本地存储或 API 读取的命令会将输出封装在来源信息中:
{
"meta": {"source": "live" | "local", "synced_at": "...", "reason": "..."},
"results": <data>
}
解析 .results 获取数据,并查看 .meta.source 以确定数据来自实时来源还是本地来源。仅当 stdout 是终端,且未设置机器格式标志(--json、--csv、--compact、--quiet、--plain、--select)时,才会将易读的 N results (live) 摘要输出到 stderr — 管道/Agent 使用者和指定格式的运行会在 stdout 中获得纯 JSON。
路径和状态
Agent 应将 CLI 的路径解析器视为运行时契约的一部分:
-
单次调用可使用
--home <dir>,也可设置FLIGHT_GOAT_HOME=<dir>,将所有四类路径重定位到同一根目录下。 -
只有在某一特定类别需要使用不同路径时,才使用对应类别的环境变量:
FLIGHT_GOAT_CONFIG_DIR、FLIGHT_GOAT_DATA_DIR、FLIGHT_GOAT_STATE_DIR、FLIGHT_GOAT_CACHE_DIR。 -
解析优先级依次为:对应类别的环境变量、
--home、FLIGHT_GOAT_HOME、XDG(XDG_CONFIG_HOME、XDG_DATA_HOME、XDG_STATE_HOME、XDG_CACHE_HOME),最后是平台默认值。 -
config包含config.toml和配置档案等设置。data包含credentials.toml、data.db、Cookie 和身份验证附属文件。state包含持久化查询、作业和teach.log。cache包含可重新生成的 HTTP/缓存文件。 -
存储的机密信息位于数据目录下的
credentials.toml中。为兼容性,仍会读取旧版config.toml中的机密信息,并在首次写入身份验证信息时将其移出config.toml。 -
运行
flight-goat-pp-cli doctor --fail-on warn,以显示路径和凭据位置警告。对于需要解析后目录的 Agent,agent-context会提供 schema v4 的paths块。 -
对于 MCP,请通过 MCP 主机配置传入重定位设置。MCP 二进制文件不会继承 CLI 标志:
{ "mcpServers": { "flight-goat": { "command": "flight-goat-pp-mcp", "env": { "FLIGHT_GOAT_HOME": "/srv/flight-goat" } } } }
集群优先级:继承的对应类别环境变量会覆盖该类别的显式 --home。使用 FLIGHT_GOAT_HOME 或对应类别的变量作为持久的集群控制项;--home 仅用于单次调用。取消设置环境变量无法撤销重定位;清除 FLIGHT_GOAT_HOME 前,请手动移动文件,否则 doctor 将找不到留在原根目录下的凭据。
自动学习
此 CLI 内置了自动捕获的学习循环。CLI 会自行记录:每次调用都会记入本地日志;若某个标志失败后经过修正重试,会自动推导出一个 flag_alias 候选项;若对没有操作手册的查询类别执行 teach,则会根据会话日志自动合成一个 playbook_candidate。你只需进行判断:先执行 recall,再根据显示的候选项采取行动,使用 teach 记录最终答案,并在发现修正时运行 playbook amend。你无需手动记录失败。
步骤 1:在任何发现操作前运行 recall
针对新的用户问题,在运行 list/search/drill 命令前,先运行:
flight-goat-pp-cli recall "<user's question>" --agent
响应封套:
{
"query": "...",
"normalized": "<normalized form>",
"query_entities": ["..."],
"found": true | false,
"match_score": 0.0,
"results": [
{ "resource_id": "...", "resource_type": "...", "venue": "...",
"confidence": 2, "entity_match": "exact|partial|unknown",
"source": "taught|preseed|pattern", "warnings": ["..."] }
],
"mismatches": [ /* only when --debug-mismatches */ ],
"warnings": [ /* top-level */ ],
"candidates": [
{ "id": 12, "class": "flag_alias | playbook_candidate",
"summary": "...", "sightings": 3, "last_seen": "...",
"rationale": "...",
"next_action": ["<trial command>", "flight-goat-pp-cli learnings confirm 12"] }
],
"playbook": {
"query_family": "...",
"playbook": {
"steps": [ { "cmd": "<command with {slot} substitution>", "purpose": "..." } ],
"entity_slots": ["$ENTITY"],
"expected_tool_calls": 3
},
"slots_resolved": { "$ENTITY": { "token": "<live token>", "canonical": "<canonical>" } },
"notes": "<workarounds + gotchas for this query family>"
},
"notes": "<duplicate surface for non-playbook callers>"
}
空存储短路:如果存储中尚无任何学习内容、Playbook 或候选项(recall 未找到任何内容,且 learnings list 和 learnings candidates 均为空),则本次会话剩余时间内跳过 recall,避免每次查询都产生开销;有内容被教入后,再恢复优先运行 recall。
步骤 2:决策树
按以下顺序读取 candidates、playbook、notes、results[0] 和 warnings:
if Candidates present (warnings include "candidates_present"):
-> candidates are try-then-confirm, never facts. Follow each candidate's
two-step next_action verbatim: run the trial command first, then run
`learnings confirm <id>` only after the trial verified the behavior.
Reject a wrong candidate with `learnings reject <id>`.
-> NEVER re-teach something recall surfaced as a candidate; confirm or
reject that candidate instead of teaching a duplicate.
-> candidates ride alongside playbooks and resource hits, not instead of
them; continue with the branches below after acting on them.
if Playbook present:
-> READ Playbook.notes verbatim FIRST (workarounds + gotchas the CLI surface doesn't expose)
-> replay Playbook.steps in order, substituting Playbook.slots_resolved entries
for the entity slot tokens. If a step's slot is unresolved, fall back to
discovery for that step only.
-> the Playbook's expected_tool_calls is a budget; if you find yourself running
materially more, record the divergence via `flight-goat-pp-cli playbook amend`
at end-of-session.
elif Notes present (no Playbook):
-> read Notes verbatim before any discovery step; they carry known gotchas
for this query family even when no structured choreography exists yet.
elif Found AND Results[0].EntityMatch == "exact" AND Results[0].Confidence >= 2:
-> skip discovery; fetch live data for Results[*].ResourceID in parallel
elif Found AND Results[0].EntityMatch == "partial":
-> candidate hint, NOT a hit; read the resource title to validate before trusting
elif (any row in Mismatches[] when --debug-mismatches was passed):
-> treat as cold start; the stored learning is for a different entity
(different canonical resolved from query_entities)
else: // Found == false, no playbook, no notes
-> cold start; run discovery normally; teach the answer afterward (Step 4).
If the family has no playbook yet, that teach auto-synthesizes a
playbook candidate from this session's journal - you do not need to
record one by hand.
Playbook 和 Notes 与每个资源的处理路径彼此独立。recall 响应可以同时包含 Playbook 和 Results[] 命中项——两者都要使用:Playbook 会告诉你要运行哪种操作流程;资源命中项则会跳过特定步骤。默认跳过 mismatches;只有在调查冷启动异常时才传入 --debug-mismatches。
候选项判断详情:learnings confirm <id> 会在将候选项写入存储前打印其完整内容——请检查打印的内容是否与已验证的行为相符。learnings reject <id> 会将派生签名标记为失效,避免相同候选项再次出现。封套只包含当前值得采取行动的少数候选项;flight-goat-pp-cli learnings candidates 会列出所有未处理的候选项。
优雅降级:如果 learnings confirm 是未知命令,说明你使用的是较旧版本的二进制文件——忽略候选项相关指引,并遵循协议的其余部分。
步骤 3:始终读取 warnings
low_confidence:行存在,但confidence<2。将其视为提示,而不是可跳过发现操作的命中项。resource_not_in_store:本地存储中没有该学习内容指向的资源。匹配验证器无法对实体进行分类——请直接获取资源并重新评估。cross_alias_match(每个结果):该行是在另一个别名下教入的,并通过entity_lookups与实时查询的规范实体匹配(例如,对“USA”的教入内容满足了对“United States”的 recall)。请相信 resource_id。similar_shape_different_entity:<canonical>(顶层):存在结构匹配的行,但其规范实体与实时查询的不同。按冷启动处理;warning 会将冲突的规范实体作为提示,但该行不会提升为 Results。ambiguous_alias(顶层):单个查询实体解析出了多个规范实体(例如,“Cards” → Arizona Cardinals + St. Louis Cardinals)。在确定资源前,结合上下文指出歧义。candidates_present(顶层):封套包含candidates部分。先按照步骤 2 中的候选项分支处理,再进行其他操作。lookup_refresh_available(顶层):查询中的某个实体尚无 lookup 行,但同步数据可能会提供一行。运行flight-goat-pp-cli sync以刷新实体 lookup。- 顶层
no_learnings_for_query_family:该表中没有高于 Jaccard 下限的行。属于纯冷启动。
步骤 4:完成回复后始终执行 teach &
教学是无条件的。解决存储无法回答的查询后,在后台教学最终的资源映射——不设调用次数门槛,也不判断是否「值得」学习。教学是整个循环的锚点:它会为尚无操作手册的类别触发操作手册合成;指向同一实体的不同表述会合并到同一类别中,因此近似重复的教学不会使存储碎片化。完成面向用户的回复后、发送回复前,使用 shell & 执行教学调用,使其立即返回:
flight-goat-pp-cli teach --query "<user's question>" --resource-type <type> --resource <id1> --resource <id2>
# (append shell `&` to background it)
成功时不输出任何内容。错误只会写入已解析状态目录下的 teach.log。教学时选择最具体的资源——如果用户提出了宽泛的问题,而你通过查阅父级记录找到了具体答案,就教学叶子 ID,而不是父级。CLI 使用预置的 entity_lookups 在召回时进行跨别名解析,因此通过一个别名教学(例如「Niners」)会自动满足使用其他别名(例如「49ers」、「San Francisco」)的后续查询。
PII 规则:教学结构性问题时,必须去掉标识符——教学查询或备注中绝不能包含姓名、电子邮件、电话号码、账户 ID 或其他个人标识符。CLI 会扫描教学查询中明显的电子邮件/电话格式并发出警告,但不会阻止;应在教学前去除这些信息,而不是依赖警告。
步骤 5:操作手册——标志可选,自动合成
你不需要判断某次会话是否「值得」编写操作手册:对于尚无操作手册的类别,教学会根据会话日志自动合成一个 playbook_candidate,并由下一次会话通过确认/拒绝来评估。只有在你已掌握值得原样记录的操作流程时,才附加明确的操作手册标志——例如 CLI 未提示的变通方法(被静默丢弃的标志、未记录的参数、分页技巧、载荷注意事项)。优先使用集成式单次调用形式——在同一次 teach 调用中记录资源学习内容和操作手册:
# Common case: record both the resource learning AND the playbook in one call.
flight-goat-pp-cli teach \
--query "<user's question>" \
--resource <id> \
--playbook-file ~/playbooks/<shape>.json \
--playbook-notes-file ~/playbooks/<shape>-notes.md
# (append shell `&` to background it)
# Alternate: playbook-only (no resource to record alongside).
flight-goat-pp-cli teach-playbook \
--query "<user's question>" \
--playbook-file ~/playbooks/<shape>.json \
--notes-file ~/playbooks/<shape>-notes.md
操作手册文件为包含 steps、entity_slots、expected_tool_calls 的 JSON 文件。备注文件为 Markdown 文件,原样记录注意事项。无法使用文件的调用方(仅使用 MCP 的 Agent)可内联传入相同内容:在集成式 teach 形式中使用 --playbook-json 和 --playbook-notes,在 teach-playbook 中使用 --playbook-json 和 --notes。在集成式 teach 形式中,操作手册标志是可选的——如果只进行资源教学,可完全省略。在单独的 teach-playbook 形式中,必须设置操作手册标志和备注标志中的至少一个;两者都为空时会被拒绝。操作手册按结构性查询类别(去除实体后)建立索引,因此,从一个包含实体的查询所教学的流程适用于所有其他同类查询;召回时,slots_resolved 会绑定当前查询的规范值。
如果你在后续召回中找到操作手册,就将其视为事实依据:根据 slots_resolved 的替换结果重放步骤,跳过操作流程已记录的探索过程,并在执行任何步骤之前阅读 notes。
第 6 步:当调试响应指出需要修正时,执行 playbook amend &
如果你的调试协议响应发现了一项笔记或 playbook 应当记录的具体修正——例如变通方法、未记录的端点格式、过时的字段名、观察到的架构漂移、空载荷回退方案——请在生成面向用户的响应之前执行 playbook amend。与 teach 一样,采用即发即忘的方式。
flight-goat-pp-cli playbook amend \
--query "<exact recall query string>" \
--add-note "<your concrete correction>"
# (append shell `&` to background it)
哪些内容值得修正:本次会话中你观察到、能让未来的自己受益的行为。值得修正的示例:
- CLI 接口会静默丢弃或错排某个标志的变通方法。
- 未记录的端点格式(响应包装在
{meta, results}中,载荷嵌套层级比文档声称的更深)。 - 观察到的架构漂移(字段已重命名、索引在不同赛季之间发生变化、API 现在返回小写的类别标签)。
哪些内容不应写入笔记:
- 用户问题的特定年份或实体的答案。这是响应,不是经验总结。
- playbook 已在运行时获取的球队、运动员或行数据。
- 对现有笔记内容的改述。
amend 命令会将带时间戳的标记([amend YYYY-MM-DDTHH:MMZ]: <text>)追加到该系列现有的笔记中。多次 amend 会累积,并保留可见的审计轨迹。如果该系列还没有 playbook,amend 会创建一个仅含笔记的 playbook(因此冷启动时的修正也能记录下来)。
amend 笔记中的 PII 规范
playbook amend 笔记旨在未来版本的 Printing Press 中作为共享知识上传。请勿在笔记中包含可识别用户身份的内容,以便保持上游贡献渠道畅通,避免日后再进行清理:
- 不要嵌入用户文件系统路径、个人 API 密钥或令牌、用户电子邮件地址、用户 GitHub 账号名,或与单个用户关联的具体查询历史。
- 可以包含:端点格式、未记录的字段名、API 注意事项、观察到的架构漂移、CLI 接口的变通方法、可复用的分页或重试策略。
如果某项修正只有结合用户特定的上下文才有意义,就应记入个人笔记,而不是 playbook amend。
衡量反馈循环
flight-goat-pp-cli learnings stats 会根据本地 learn_events 表报告召回命中率、经验传授后的复用率、playbook 解析率,以及候选项确认/拒绝数量。分母尚未建立前,比率为 null;所有数据都保留在本机。使用此命令检查这个 CLI 的反馈循环是否发挥了作用。
禁用学习
- 单条命令使用
--no-learn会同时短路recall和teach写入路径。适用于确定性 Agent 工作流,或不得受累积经验影响的测试。 - 在环境变量中设置
FLIGHT_GOAT_NO_LEARN=true可全局禁用该管道。
Agent 反馈
当你(或 Agent)发现这个 CLI 有问题时,请记录下来:
flight-goat-pp-cli feedback "the --since flag is inclusive but docs say exclusive"
flight-goat-pp-cli feedback --stdin < notes.txt
flight-goat-pp-cli feedback list --json --limit 10
记录会以 feedback.jsonl 的形式存储在解析后的数据目录中。除非设置了 FLIGHT_GOAT_FEEDBACK_ENDPOINT,并且传入 --send 或设置 FLIGHT_GOAT_FEEDBACK_AUTO_SEND=true,否则绝不会发送 POST 请求。默认行为仅在本地保存。
记录让你感到意外的事情,而不是提交错误报告。简短、具体、一行即可:这才是能不断积累价值的内容。
输出交付
每条命令都接受 --deliver <sink>。输出会发送到指定的目标,并可同时输出到 stdout,也可替代 stdout,这样 Agent 无需手动管道即可路由命令结果。支持以下三种目标:
| 目标 | 效果 |
|---|---|
stdout | 默认;仅写入 stdout |
file:<path> | 以原子方式将输出写入 <path>(临时文件 + 重命名) |
webhook:<url> | 将输出正文 POST 到该 URL(使用 --compact 时为 application/json 或 application/x-ndjson) |
遇到未知方案时会拒绝执行,并返回结构化错误,列出支持的方案。Webhook 失败时会返回非零退出码,并在 stderr 中记录 URL 和 HTTP 状态码。
命名配置
配置文件是一组已保存的标志值,可在多次调用中重复使用。如果定时或定期运行的 Agent 每次运行都使用相同的已保存标志,但输入各不相同,请使用配置文件。
flight-goat-pp-cli profile save briefing --json
flight-goat-pp-cli --profile briefing airports get mock-value
flight-goat-pp-cli profile list --json
flight-goat-pp-cli profile show briefing
flight-goat-pp-cli profile delete briefing --yes
显式指定的标志始终优先于配置文件中的值;配置文件中的值优先于默认值。agent-context 会在 available_profiles 下列出所有可用配置文件,以便自省型 Agent 在运行时发现它们。
退出代码
| 代码 | 含义 |
|---|---|
| 0 | 成功 |
| 2 | 用法错误(参数错误) |
| 3 | 未找到资源 |
| 4 | 需要身份验证 |
| 5 | API 错误(上游问题) |
| 7 | 请求过于频繁(等待后重试) |
| 10 | 配置错误 |
参数解析
解析 $ARGUMENTS:
- 为空、
help或--help→ 显示flight-goat-pp-cli --help输出 - 以
install开头 → 以mcp结尾 → 安装 MCP;否则 → 参见上文的先决条件 - 其他任何内容 → 直接使用(作为 CLI 命令执行,并带上
--agent)
MCP 服务安装
- 安装 MCP 服务及其配套 CLI(版本相同)。MCP 服务通过执行
flight-goat-pp-cli来运行每个工具,因此在安装 CLI 之前,每次工具调用都会因“companion CLI binary not found”而失败:
服务会先在自身可执行文件旁查找 CLI,然后查找go install github.com/mvanhorn/printing-press-library/library/travel/flight-goat/cmd/flight-goat-pp-mcp@latest go install github.com/mvanhorn/printing-press-library/library/travel/flight-goat/cmd/flight-goat-pp-cli@latestFLIGHT_GOAT_CLI_PATH,最后查找PATH。如果 CLI 位于其他位置,请在 MCP 宿主的env块中将FLIGHT_GOAT_CLI_PATH设置为其绝对路径。 - 在 Claude Code 中注册:
claude mcp add flight-goat-pp-mcp -- flight-goat-pp-mcp - 验证:
claude mcp list
直接使用
- 检查是否已安装:
which flight-goat-pp-cli如果未找到,请提供安装选项(参见本技能开头的先决条件)。 - 将用户查询与上文“独特功能”和“命令参考”中的最佳命令匹配。
- 使用
--agent标志执行:flight-goat-pp-cli <command> [subcommand] [args] --agent - 如果存在歧义,深入查看子命令帮助:
flight-goat-pp-cli <command> --help。