智能差旅
本技能使用 hose-ai-assistant 连接器(中文名称:“合思商旅”),用于查询企业实时机票、酒店、火车票及详情。
开始前必须读取 references/mcp-tools.md。该文件是本技能唯一的 MCP 工具接口契约,集中维护工具用途、参数、返回值、错误码和示例;调用 MCP 前必须以该文件为准,不得自行猜测工具字段。MCP 工具参数、返回值和接口行为升级时,只需维护该参考文件;只有新增或移除工具时才需要同步 frontmatter 的 allowed-tools 授权列表。
技能概要
根据用户意图选择对应工具:
| 技能名称 | 用途 | MCP Tool |
|---|---|---|
| 登录状态查询 | 查询当前用户、默认企业和登录是否有效 | ai_trip_current_user |
| 短信验证码发送 | 已注册用户直接发送;未注册用户由服务端注册并绑定默认企业后发送登录验证码 | ai_trip_send_sms |
| 短信登录 | 使用手机号和验证码完成登录;对注册或绑定流程做幂等兜底 | ai_trip_login_sms |
| 机票查询 | 按航线、日期、时间、直飞、舱等、航司和价格查询航班 | ai_trip_search_flights |
| 航班详情 | 查询指定航班的实时舱位和价格详情 | ai_trip_get_flight_detail |
| 酒店查询 | 按城市、入住日期、含早、设施、可取消和价格查询酒店基础信息 | ai_trip_search_hotels |
| 酒店详情 | 查询指定酒店的实时房型、价格和退改信息 | ai_trip_get_hotel_detail |
| 火车票查询 | 按车站、日期、时间、车次、车型、席别和价格查询直达车次 | ai_trip_search_trains |
| 车次详情 | 查询指定车次的实时座席和价格详情 | ai_trip_get_train_detail |
用户说“查机票/航班”“查酒店/房型”“查火车/车次”时,分别使用对应的列表查询工具;用户明确指定某个航班、酒店或车次,或要求查看舱位、房型、座席时,改用对应详情工具。当前 MCP 未注册差旅政策工具,用户询问公司差旅标准时应明确说明当前连接器暂不支持,不得调用不存在的政策工具。
本技能只支持查询和详情读取,不预订、不占座、不支付、不创建订单、不规划行程、不处理客服支持。机票、酒店、火车和详情的业务数据只依据 MCP 统一返回中的 structuredContent.data 作答。地点代码、日期和资源标识不确定时先向用户确认,不补全或编造供应商未返回的信息。
地点编码
- 酒店和火车的城市参数使用六位行政区划代码;直辖市使用供应商可查询的市辖区代码,例如天津使用
120100,不要使用120000。北京、上海、重庆也遵循同一规则,不能把直辖市代码直接替代市辖区代码。 - 火车车站参数使用铁路电报码,不是机场三字码。常用示例:上海
SHH、杭州HGH、天津TJP、天津西TXP、塘沽TGP。 - 以上示例只用于识别编码类型;如果用户提供的城市或车站不在已知示例中,先确认供应商代码,不自行猜测。
调用流程
- 先收集目标工具的必填参数;缺少参数时只询问缺失项。日期统一使用
YYYY-MM-DD,相对日期换算后向用户明确具体日期。 - 本轮首次调用受保护的业务工具前,按“凭证管理”读取
~/.workbuddy/mcp.json中的凭证,并调用一次ai_trip_current_user验证当前用户和默认企业;同一轮后续调用不重复检查,除非发生重新登录、凭证更新或收到AUTH_REQUIRED、AUTH_EXPIRED、COMPANY_ACCESS_DENIED。短信登录流程例外:ai_trip_send_sms允许未登录调用,不得因current_user未登录而阻断短信发送。 - 返回
AUTHENTICATED后调用对应的机票、酒店、火车或详情工具;用户指定资源或要求查看舱位、房型、座席时,优先透传搜索结果中的标识和上下文。 - 同一轮对同一资源类型只发起一次列表搜索。不得为了覆盖全天、扩大结果集或模拟分页,自动把一次查询拆成多个时间窗口或重复调用同一个搜索工具;用户明确指定时间范围时,将该范围作为一次调用的筛选条件。
- 列表结果默认按每页 20 条向用户展示。当前搜索工具只提供
limit,不提供page、pageSize或游标参数;机票底层FlightSearchWebRequest/Ticket和直达火车底层QueryRequest/QueryResponse也没有分页字段。首次搜索可按工具允许的limit获取一次结果,然后只展示前 20 条,并在当前对话中保留本次返回的结果用于后续翻页。 - 用户说“下一页”“再看 20 条”等时,优先从本次搜索已返回但尚未展示的结果中取下一页,不再次调用同一个搜索工具,也不重新拆分时间窗口。只有用户改变路线、日期或筛选条件时才发起新的列表搜索。
- 若已返回结果不足下一页,或
supplierTruncated=true表示供应商结果已被截断,应如实说明当前结果集没有更多可展示数据;不得通过重复搜索或修改时间窗口伪造下一页。 - 查询成功后只依据
data简洁呈现结果;无结果、字段缺失或工具失败时如实说明,不估算或补全。
搜索结果数量默认值
搜索工具的结果数量由后端统一设置和校验;skill 的展示页大小固定为 20,不把多个时间窗口当作分页。首次查询为支持对话内翻页,使用对应工具的最大 limit 作为单次获取上限:
| 工具 | skill 展示页大小 | 单次获取上限 |
|---|---|---|
ai_trip_search_flights |
20 | 50 |
ai_trip_search_hotels |
20 | 20 |
ai_trip_search_trains |
20 | 100 |
用户未指定数量时,按上表传入单次获取上限并展示前 20 条;用户明确要求更少结果时可传入对应数量,但少于 20 条时不能承诺后续页面。当前 MCP 没有服务端页码,skill 只能对同一次工具返回的结果做对话内翻页,不能跨请求恢复已截断的供应商结果。不要把火车 /combined/train 的 pageIndex 误用于当前直达搜索,也不要为机票或直达火车新增底层不存在的分页参数。
短信登录
- 询问中国大陆手机号,并在调用
ai_trip_send_sms前说明会发送真实短信、取得用户确认。 - 短信发送成功后只展示掩码手机号,再询问验证码并调用
ai_trip_login_sms。 - 验证码仅用于本次登录,不复述、不记录、不写入文件。
ai_trip_send_sms直接调用 CSC 登录短信接口:已注册用户发送成功后结束;如果 CSC 明确返回“账号不可用”,服务端才由管理员通过basics/user/save创建并绑定默认企业,然后重试发送验证码。skill 不直接调用basics/user/save,也不向用户索取工号或邮箱。ai_trip_login_sms返回AUTHENTICATED后保存凭证、重新加载连接器、调用ai_trip_current_user验证,再恢复原查询。已注册但尚未绑定默认企业的老用户,在验证码校验成功后由服务端携带原用户 ID 完成一次绑定;已绑定用户不重复绑定。若返回BINDING_REQUIRED、login_handle或required_profile_fields,当前 MCP 没有资料补全工具,不得自行拼接或调用不存在的工具。
短信登录的账号分支
ai_trip_send_sms不调用getCompanyListByMobile,也不在老用户发送短信前查询或绑定企业。短信接口成功表示手机号可以继续登录;仅当短信接口明确返回账号不可用时,才进入新用户user/save注册绑定并重试发送。- 验证码校验成功后,
ai_trip_login_sms根据 CSC 登录结果判断默认企业成员关系:已绑定时直接换取 Token;老用户未绑定时复用原userId绑定一次;新用户账号不存在时创建默认企业成员。 - 验证码错误或过期仍立即返回登录错误;不得用历史数据或推算结果替代真实查询。
凭证管理
- 唯一凭证字段是
~/.workbuddy/mcp.json中的mcpServers.hose-ai-assistant.headers.Authorization。不从环境变量、项目文件、连接器缓存、对话历史或其他位置读取或写入凭证。 - 已知坑:凭证写入/更新后,已连接的 MCP 连接器会话不会自动携带新的 Authorization 头(工具调用仍返回
AUTH_REQUIRED),即使完成信任也需要重新建立连接器会话才可能生效。凭证从~/.workbuddy/mcp.json读取,不得出现在命令行参数或日志中;凭证变更后重新加载或建立连接器会话,再调用ai_trip_current_user验证。 - 判定顺序(避免多余短信):若 MCP 工具
ai_trip_current_user返回AUTH_REQUIRED,但~/.workbuddy/mcp.json中Authorization是格式正确的非空Bearer <token>,先不要发起短信登录;按上一条重新加载或建立连接器会话,再重新调用ai_trip_current_user验证。重新调用返回AUTHENTICATED即说明凭证有效、只是旧连接器会话未携带新头部;只有重新调用仍返回AUTH_REQUIRED/AUTH_EXPIRED/AUTH_FORMAT_INVALID时才进入短信登录流程。不得使用未定义的脚本或 HTTP 直连方式绕过 MCP 工具。 - 使用结构化 JSON 解析和更新,只修改上述字段并保留其他配置;文件、对象或字段不存在,JSON 无法解析,或字段不是非空的
Bearer <token>时,均视为未登录。 - 保存登录凭证前取得用户确认;优先保存
authorization_header,仅返回access_token时组装为Bearer <access_token>。 - 使用同目录临时文件原子替换,沿用原文件权限,不把凭证放入命令行参数、日志或标准输出,临时文件不得遗留。写入后让连接器重新加载并用
ai_trip_current_user验证。 - 对话、日志和错误信息只能报告凭证“已配置”“缺失”“格式错误”或“已失效”,不得展示、复述或导出
Authorization、access_token、authorization_header或管理员凭证。 - 若当前 Server 尚未信任,在连接器管理页通过“自定义连接器”找到
hose-ai-assistant并执行信任;已信任的 Server 续期时无需重复信任。