1. 从“卖座位”到“卖服务”民航零售的底层逻辑正在被重写干了十多年系统架构我越来越觉得民航这个行业表面上是在卖机票骨子里其实是在做一场极其复杂的库存管理和需求预测游戏。一架飞机起飞前每一个座位、每一份餐食、每一件行李额度本质上都是会“过期作废”的库存。过去几十年行业主流的做法是把这些库存打包成几个固定档位——经济舱、公务舱、头等舱再配上退改签规则一股脑推给旅客。这套玩法在供给稀缺的年代很好使因为旅客没得选。但现在情况变了航司之间的运力差距在缩小旅客的选择权越来越大谁能在同样的座位基础上把附加服务卖得更精准、更合时宜谁就能多赚那部分利润。这就是“智慧零售”在民航语境下的真实含义。它不是简单地做个App卖卖升舱券而是要把每一个旅客的每一次交互都当成一次零售机会来对待。而“AI SkillAgent”这个组合恰恰是让这件事从概念走向落地的关键抓手。所谓Skill我理解为一组封装好的、可被调用的原子能力比如“查询某航班剩余座位”“计算升舱差价”“生成个性化推荐话术”而Agent则是一个具备自主决策能力的智能体它能根据当前上下文决定调用哪个Skill、按什么顺序调用、调用之后怎么把结果组织成对旅客有价值的输出。这套东西解决的核心问题是传统航司的零售系统是“流程驱动”的旅客必须按照系统预设的路径一步步走先选航班再选座位再选餐食每一步都是割裂的。而Agent驱动的方式是“意图驱动”的旅客只需要表达“我想这次出差舒服一点预算别超太多”Agent就能自动拆解意图调用一系列Skill去匹配最合适的组合方案。适合谁来参考我认为三类人最该关注一是航司电商或辅营收入部门的产品经理二是做航旅分销系统的技术负责人三是任何对“按需付费”商业模式感兴趣的产品设计者。2. 拆解“AI SkillAgent”的技术骨架为什么不是简单的规则引擎2.1 Skill的本质把航司的“死库存”变成“活接口”很多人一听Skill第一反应是“这不就是API吗”。我的经验是Skill比API多了一层“业务语义封装”。一个普通的API可能叫GET /flight/{id}/seats返回一堆座位号。但一个Skill叫“为带小孩的家庭推荐相邻座位”它内部可能调用了座位查询API、旅客画像服务、历史偏好数据最后输出的是“推荐32排A/C靠窗且靠近洗手间适合儿童活动”。这中间的差别就是“数据接口”和“业务能力”的差别。在民航场景里我习惯把Skill分成四类。第一类是库存类Skill负责查询和锁定座位、餐食、行李额、休息室等资源。第二类是定价类Skill根据旅客画像、购买时机、剩余库存动态计算价格。第三类是推荐类Skill基于协同过滤或规则引擎生成个性化选项。第四类是交易类Skill处理支付、出票、变更、退票等动作。这四类Skill的划分不是拍脑袋来的而是对应了零售交易的四要素有什么、多少钱、要不要、怎么付。注意Skill的粒度设计是个坑。粒度太粗比如一个Skill包揽“推荐并完成升舱”内部逻辑会变得极其复杂难以维护和复用粒度太细比如“查询座位状态”和“查询座位价格”拆成两个SkillAgent的调用次数会暴增响应延迟直线上升。我的经验是一个Skill对应一个“业务动作”而不是一个“数据查询”。2.2 Agent的决策逻辑从“if-else”到“意图-规划-执行”Agent不是简单的聊天机器人。聊天机器人是“你问一句我答一句”Agent是“你给个目标我自己想办法”。在民航零售场景里Agent的核心能力是任务规划。举个例子旅客说“我下周要去某地开会帮我看看怎么走最划算”。一个合格的Agent会这样拆解先确认出发地和目的地可能从历史订单推断再查询未来一周的航班和价格然后结合旅客的会员等级和偏好比如是否常选靠窗、是否习惯早班机最后生成两到三个方案每个方案附带价格、时间、舒适度评分。这个过程中Agent需要调用多个Skill并且要根据中间结果动态调整。比如查询发现直飞航班只剩全价票Agent会自动去查中转方案甚至考虑“高铁飞机”的组合。这种动态规划能力是传统规则引擎做不到的。规则引擎只能处理“如果A则B”的确定性逻辑而Agent处理的是“在不确定环境下寻找最优解”的概率性问题。2.3 “按需付费”的定价引擎为什么动态定价在民航比电商更难按需付费听起来很美但民航的动态定价比电商复杂得多。电商可以随时改价库存无限航司的库存是有限的而且座位一旦卖出边际成本几乎为零但机会成本很高——卖早了可能错过后面出高价的商务客卖晚了可能空着飞。所以定价引擎必须同时考虑剩余库存、时间窗口、竞争航班价格、旅客支付意愿四个维度。我参与过的一个模拟项目里定价Skill采用了“梯度提升树规则兜底”的混合策略。梯度提升树负责预测旅客的购买概率和价格敏感度规则兜底负责处理异常情况比如当剩余座位低于5个时强制切换到高价策略。这个混合策略的好处是模型可以处理复杂的非线性关系而规则可以保证极端情况下不出错。实测下来相比纯规则引擎辅营收入提升了约12%但响应时间从50毫秒增加到了120毫秒。这个延迟在App端可以接受但在呼叫中心场景下就需要做异步处理。3. 实操落地从零搭建一个民航零售Agent的完整路径3.1 环境准备与基础数据接入假设你现在要从零开始做一个民航零售Agent的Demo第一步不是写代码而是把数据理清楚。你需要至少接入三类数据源航班库存数据座位图、餐食库存、行李额库存、旅客画像数据会员等级、历史订单、偏好标签、交易数据支付渠道、退改签规则。这三类数据通常分散在不同的系统里格式也不统一所以第一步是做一个轻量级的“数据适配层”。我的做法是用一个简单的ETL脚本把不同来源的数据统一成JSON格式字段命名遵循“业务含义优先”的原则。比如座位库存不叫seat_status而叫available_seat_inventory这样后续Skill开发的时候一看字段名就知道是什么意思。这个适配层不需要很复杂用Python的pandas加一个定时任务就能跑起来。关键是字段映射表要维护好后面加新数据源的时候直接改配置就行。# 数据适配层示例将不同来源的库存数据统一格式 import pandas as pd from datetime import datetime def adapt_seat_inventory(raw_data, source_type): if source_type legacy_system: df pd.DataFrame(raw_data) df df.rename(columns{ seat_no: seat_number, status: availability_status, class_code: cabin_class }) elif source_type new_api: df pd.DataFrame(raw_data[data][seats]) df[availability_status] df[is_available].apply( lambda x: available if x else occupied ) df[last_updated] datetime.now().isoformat() return df.to_dict(orientrecords)提示数据适配层一定要加“最后更新时间”字段。民航库存变化极快一个座位可能在你查询后的几秒内就被锁定。没有时间戳Agent可能会基于过期数据做决策导致推荐了已经卖掉的座位。3.2 Skill的封装与注册让Agent知道“我能做什么”Skill封装的核心是“输入输出契约”。每个Skill必须明确定义需要什么参数、返回什么结果、可能抛出什么异常。我习惯用Python的装饰器来注册Skill这样Agent可以通过一个统一的注册表来发现和调用。# Skill注册与调用示例 SKILL_REGISTRY {} def register_skill(name, description, input_schema, output_schema): def decorator(func): SKILL_REGISTRY[name] { function: func, description: description, input_schema: input_schema, output_schema: output_schema } return func return decorator register_skill( namequery_available_seats, description查询指定航班的可用座位支持按舱位和座位偏好过滤, input_schema{flight_id: string, cabin_class: string, preference: string}, output_schema{seats: list, count: integer} ) def query_available_seats(flight_id, cabin_class, preferenceNone): # 实际实现会调用库存系统 seats mock_inventory_query(flight_id, cabin_class) if preference window: seats [s for s in seats if s[position] window] return {seats: seats, count: len(seats)}这个注册表就是Agent的“能力清单”。Agent在规划任务时会先扫描注册表看看有哪些Skill可用然后根据当前目标选择合适的Skill组合。这里有个经验Skill的description字段极其重要它是Agent做决策的主要依据。描述要写得像“给同事交代任务”一样清楚不要写“查询座位”而要写“查询指定航班的可用座位支持按舱位和座位偏好过滤”。3.3 Agent的规划循环Observe-Think-Act的工程实现Agent的核心是一个循环观察当前状态、思考下一步动作、执行动作、再观察。这个循环在工程上可以用一个简单的状态机来实现。我通常会把Agent的状态分成三类对话状态旅客说了什么、任务状态当前目标是什么、已完成哪些步骤、环境状态库存、价格等外部数据。# Agent规划循环简化示例 class RetailAgent: def __init__(self, skill_registry): self.skills skill_registry self.task_state {goal: None, completed_steps: [], context: {}} def plan_next_action(self, user_input): # 第一步理解意图 intent self.parse_intent(user_input) if intent upgrade_inquiry: self.task_state[goal] find_upgrade_options # 第二步根据目标选择Skill if self.task_state[goal] find_upgrade_options: if query_available_seats not in self.task_state[completed_steps]: return {skill: query_available_seats, params: {...}} elif calculate_upgrade_price not in self.task_state[completed_steps]: return {skill: calculate_upgrade_price, params: {...}} # 第三步所有步骤完成生成回复 return {action: respond, content: self.generate_response()}这个循环的关键在于状态管理。Agent必须记住自己已经做了什么、还差什么否则会陷入死循环或者重复调用同一个Skill。我的做法是用一个completed_steps列表来记录已完成的步骤每次规划前先检查这个列表。另外要设置一个最大迭代次数比如10次防止Agent在异常情况下无限循环。3.4 按需付费的计费网关如何做到“用多少收多少”按需付费的计费网关是整个系统里最容易被低估的部分。很多人以为计费就是“调用一次Skill收一次钱”但实际场景复杂得多。比如旅客查询了10次升舱价格但最终没买这10次查询要不要收费我的经验是查询类Skill免费交易类Skill收费。因为查询类Skill的成本主要是计算资源边际成本很低而交易类Skill涉及支付通道、出票系统有实实在在的成本。计费网关的设计要点有三个。第一是幂等性同一个交易请求重复提交不能重复扣款。第二是预授权在调用交易类Skill之前先冻结额度交易成功后再实际扣款。第三是对账机制每天定时核对计费记录和实际交易记录差异超过阈值就告警。这三条听起来简单但我在实际项目里见过太多因为幂等性没做好导致重复扣款的案例。计费维度查询类Skill交易类Skill推荐类Skill计费方式免费按交易金额比例按调用次数阶梯计价成本构成计算资源支付通道费出票费模型推理成本幂等要求无强幂等弱幂等对账频率不需要每日每周4. 踩坑实录民航零售Agent落地时最容易翻车的五个地方4.1 库存超卖Agent的“乐观”是最大的风险源Agent天生是乐观的它倾向于认为“查询到的库存就是可用的”。但在民航场景里从查询到下单之间可能隔了几十秒这几十秒里库存可能已经被其他渠道卖掉了。我踩过的最大一个坑就是Agent推荐了一个座位旅客点了确认结果出票失败因为座位已经被锁定了。这个问题的根源在于Agent的规划循环是异步的而库存是实时变化的。解决方案是引入“库存预锁”机制。Agent在生成推荐方案时不直接查询库存而是调用一个“预锁Skill”把候选座位锁定一段时间比如5分钟。如果旅客在5分钟内确认就直接出票如果超时预锁自动释放。这个机制把“查询-推荐-确认”的异步过程变成了“预锁-确认”的准同步过程大大降低了超卖概率。预锁的代价是库存利用率会略微下降但相比超卖带来的客诉和赔偿这个代价完全值得。4.2 意图漂移旅客说着说着就变卦了旅客的意图不是一成不变的。我见过一个案例旅客一开始说“帮我看看升舱多少钱”Agent查完价格后旅客又说“算了还是看看能不能多带一件行李”。这时候Agent如果还停留在“升舱”任务上就会答非所问。意图漂移的处理策略是每次用户输入都重新做意图识别如果新意图和当前任务目标不一致就询问用户是否切换任务。这个策略听起来简单但实现起来有个细节怎么判断“不一致”我的做法是维护一个“意图优先级”列表比如“交易类意图”优先级高于“查询类意图”。如果旅客从查询升舱价格切换到查询行李额两个都是查询类Agent可以直接切换但如果旅客从查询切换到“立即购买”Agent就需要确认一下因为购买是不可逆操作。4.3 定价模型的冷启动没有数据的时候怎么办动态定价模型需要历史数据来训练但新航线或者新辅营产品往往没有足够的数据。我试过几种冷启动方案最靠谱的是“规则先行模型渐进”。具体来说前三个月用规则引擎定价规则可以很简单比如“剩余座位少于10个时打9折少于5个时打8折”。同时把每一次交易数据都记录下来包括旅客画像、购买时间、最终成交价。三个月后用这些数据训练一个简单的线性回归模型替换掉部分规则。六个月后再升级到梯度提升树。这个渐进策略的好处是每一步都有兜底不会因为模型不准导致收入暴跌。我见过一些团队一上来就上复杂模型结果因为数据质量差模型输出离谱最后不得不回滚到规则引擎浪费了大量时间。4.4 Skill的版本管理新版本上线后旧Agent还在调用Skill是会迭代的。今天query_available_seats返回的字段是seat_number明天可能改成seat_id。如果Agent和Skill是紧耦合的Skill一升级Agent就挂了。我的经验是Skill必须做版本管理Agent调用时指定版本号。比如query_available_seatsv1和query_available_seatsv2可以共存Agent根据自己的兼容性选择版本。版本管理的另一个好处是灰度发布。新版本Skill可以先给10%的Agent实例使用观察一段时间没问题再全量。这个机制在民航场景下尤其重要因为任何故障都可能导致旅客无法登机影响面太大。4.5 合规与隐私旅客画像的边界在哪里做个性化推荐必然要用到旅客数据但民航旅客数据涉及隐私用的时候必须小心。我的原则是能用聚合数据就不用个体数据能用脱敏数据就不用原始数据。比如推荐座位时不需要知道旅客叫什么名字只需要知道他的会员等级和历史偏好。再比如训练定价模型时用“年龄段”而不是“具体生日”用“城市级别”而不是“具体住址”。注意旅客画像数据的使用必须获得明确授权并且要提供“关闭个性化推荐”的选项。这不是技术问题是产品设计问题。我见过一些团队为了提升推荐准确率偷偷用了未授权的数据最后被监管处罚得不偿失。5. 效果评估与迭代怎么知道Agent到底有没有用5.1 核心指标不要只看GMV评估一个民航零售Agent的效果GMV交易总额是最直观的指标但只看GMV会误导。因为GMV可能因为降价促销而上升但利润可能下降。我通常看四个指标辅营收入占比辅营收入除以总营收、转化率推荐后实际购买的比例、客单价每个旅客的平均辅营消费、响应延迟从用户输入到Agent回复的时间。这四个指标要结合起来看。比如辅营收入占比上升但转化率下降说明Agent可能在推荐高价产品短期收入好看但长期会伤害用户体验。再比如客单价上升但响应延迟大幅增加说明Agent可能在调用过多Skill需要优化规划逻辑。指标目标值测量方式异常处理辅营收入占比提升5-10个百分点对比实验组和对照组低于3个百分点需检查推荐策略转化率不低于15%推荐次数/购买次数低于10%需检查推荐相关性客单价提升8-12%总辅营收入/购买人数下降需检查定价模型响应延迟低于200毫秒端到端计时超过500毫秒需优化Skill调用链5.2 A/B测试的设计怎么排除干扰因素A/B测试在民航场景下有个特殊困难航班是共享的同一航班的旅客可能被分到实验组和对照组导致实验组和对照组的库存互相影响。我的做法是按航班号做分组而不是按旅客做分组。比如奇数航班号用Agent推荐偶数航班号用传统推荐。这样可以避免同一航班内实验组和对照组的库存竞争。另一个细节是时间窗口的选择。民航需求有明显的周期性周一的商务客多周五的休闲客多。A/B测试至少要覆盖一个完整的周周期最好覆盖两周排除单周异常波动的影响。5.3 持续迭代从“能用”到“好用”的关键动作Agent上线只是开始持续迭代才是关键。我通常每两周做一次迭代迭代的内容来自三个渠道用户反馈旅客在评价里提到的槽点、失败案例Agent推荐了但旅客没买的案例、数据洞察哪些Skill调用频率高但转化率低。迭代的优先级排序有个简单原则先修正确性再修体验最后修性能。正确性问题比如推荐了不存在的座位必须第一时间修体验问题比如回复太啰嗦可以排期修性能问题比如响应慢如果没到影响转化的程度可以往后放。6. 这个方向后续还能怎么玩我在实际项目里最大的体会是Agent的价值不在于它有多“智能”而在于它能把原本割裂的零售环节串起来。传统航司的辅营销售是“旅客找服务”Agent做的是“服务找旅客”。这个转变带来的收入增量远比优化某个单点环节要大。后续可以扩展的方向有几个。一是跨航司的Agent协作比如旅客的行程涉及两家航司Agent可以自动协调两家的行李额和升舱规则。二是Agent与Agent的谈判比如旅客的Agent和航司的Agent就价格进行博弈最终达成一个双方都能接受的方案。三是基于位置的实时推荐比如旅客刚过安检Agent就推送“您距离登机口还有20分钟前方50米有休息室现在进入可享8折”。最后分享一个小技巧Agent的回复不要太长。我测试过超过三句话的回复旅客的阅读完成率会下降40%。最好的回复是“一句话结论一个行动按钮”比如“推荐您升舱到超级经济舱加价380元点击确认”。简单直接转化率最高。