
干了几年跨境电商运营最让我崩溃的事情不是选品没爆单而是每天早上一睁眼要在 Shopee、亚马逊、TikTok Shop 三个后台来回切换手动导出订单、核库存、查漏发货。有一次刚好赶上大促后的退货潮TikTok Shop 那边有两笔待发货订单在后台列表第二页躺着我没翻到最后超时被平台罚款还吃了差评。就是那一次之后我决定把 Agent Skills 这套能力真正落到多平台订单处理上。这个实战项目我前后跑了三周从需求拆解到流程搭建再到稳定运行中间踩了不少坑。标题里说的「完结无密」没有别的玄机意思是整套流程我已经完整跑通配置、代码、踩坑记录都整理在下面不需要再去翻什么隐藏资料直接照着做就行。1. 为什么多平台订单场景最适合做 Agent Skills 的第一个实战很多人第一次接触 Agent Skills 的时候第一反应是让它写文案、做翻译、当客服自动回复。这些方向没有错但作为练手项目来说它们都有一个共同的问题判断标准太模糊。文案写得好不好是主观的翻译地不地道也是主观的你很难判断 AI 是否真的做好了。但订单抓取不一样订单数对不对、字段全不全、有没有遗漏这些都是客观标准跑没跑通一目了然。多平台订单场景还有另一个好处它天然就是一个多技能协作问题。每个平台的对接方式不同有的开放 API有的只能用网页端登录导出有的需要签名认证有的只需要 Token。如果你把所有这些逻辑都塞给一个大模型去自由发挥它大概率会一本正经地编造一个不存在的接口。但如果你把它拆成一个个独立的技能——Shopee 抓取技能、亚马逊抓取技能、TikTok 抓取技能、数据汇总技能——每个技能各自管好自己那一摊再由 Agent 负责调度编排整个系统就变得非常可控。这就是 Agent Skills 和普通 Prompt 工程的最大区别。普通 Prompt 是把所有指令堆在一个对话里指望大模型理解你的所有意图。Agent Skills 则是把能力模块化每段逻辑有明确的输入输出边界Agent 按需加载对应技能就像组装乐高积木一样。我在选型的时候也考虑过直接用脚本写死整个流程不用 Agent。但后来发现一个问题平台接口变了、字段调整了、某个平台临时需要加一个筛选条件脚本写死就得改代码重新部署。用 Agent Skills 的方式平台相关的逻辑被封装成独立技能调用入口是自然语言描述改起来灵活很多。而且订单之外的其他业务——比如售后工单、库存同步、价格监控——以后都可以复用这同一套技能体系扩展性好得多。1.1 做这个项目前我对 Agent Skills 的理解还停留在概念层说实话在看各种 Agent Skills 的介绍文章的时候我一直觉得这东西有点玄乎。网上那些教程大多停留在「什么是技能」「怎么定义一个技能」的演示层面很少有文章讲清楚一个技能到底长什么样、Agent 是怎么决定调用哪个技能的、多个技能之间怎么协作、出错之后怎么收敛。当时我脑子里最大的疑问是我是不是要把所有业务逻辑都写成让大模型「理解」的自然语言后来实际做下来才明白Agent Skills 的最佳实践恰恰是反过来的——能用代码解决的逻辑就用代码解决技能定义SKILL.md只负责描述「这个技能是干什么的、什么时候调用、输入输出是什么」。大模型负责判断和调度具体的脏活累活交给脚本去执行。这个认知转变非常重要直接影响了我后面的整个架构设计。所以在这篇实战记录里我尽量把概念层面的东西压缩把精力放在真正可复现的工程细节上。你不需要成为一个 AI 专家只要会一点 Python能看懂 JSON 结构就能把这套东西跑起来。2. 从模型到工作流Agent Skills 的落地形态拆解在进入实操之前先花点篇幅把 Agent Skills 的落地形态讲清楚。这不是浪费时间因为我发现很多人最后做出来的东西不像 Agent Skills更像一个普通的函数调用问题就出在没理解这个概念的层次关系。2.1 模型永远是底座技能是模型和外界的桥梁Agent 本身是一个大语言模型它很聪明但它是「无手无脚」的。它可以理解你的问题但它无法自己去访问平台 API、无法操作数据库、无法调用 Excel 脚本。Agent Skills 要解决的就是这件事——给模型装上一套可以组合、可以复用的「双手」。一个标准的技能通常包含两部分SKILL.md技能说明书。用自然语言描述这个技能的用途、适用场景、参数定义、输出格式让大模型理解「什么时候该用它」。可执行脚本真正干活的代码。大模型读取说明书后生成调用参数并执行脚本把脚本返回结果纳入自己的推理过程。这有点像你雇了一个很聪明的助理。他不会用你们的内部系统但你给他一本操作手册告诉他「遇到这种情况就翻到第几页照着做」。Agent 就是那个助理SKILL.md 就是操作手册可执行脚本就是手册背后对应的那套标准流程。2.2 技能、任务、工作流三者不是一回事我最初犯的一个错误是把这三者混为一谈。技能是一个能力单元它只负责完成一件具体的事任务是一个业务目标比如「把四个平台的订单合并成一张报表」工作流则是任务的执行路径——先做什么、再做什么、遇到异常怎么办、要不要人工确认。用订单抓取来举例理解概念例子特点技能shopee_fetch_orders封装了 Shopee 平台的接口调用逻辑输入日期范围输出订单列表任务抓取今天的全部订单需要根据用户指令动态决定调哪些技能工作流每天 9 点自动执行抓取-汇总-推送有固定的执行顺序、计时触发、失败重试机制我在项目里用的编排平台是 Workbuddy它还有个关键作用是把 Agent 的决策过程固化下来。比如用户说「帮我看下今天有哪些待发货订单」Agent 会先判断这个请求需要调用店铺的订单技能、可能需要访问库存数据、还需要生成汇总报告。然后按照工作流里定义的顺序依次触发对应技能。值得注意的是Agent Skills 并不是让大模型每次都在对话里临时决定所有事。固定流程用工作流定义灵活分支用技能覆盖这是 Agent 类应用工程化的核心思路。2.3 为什么说要给「技能」留出稳定的输入输出契约后来我在实践中总结出最宝贵的一条经验技能之间不要直接互相调用更不要让技能去读另一个技能的内部变量。所有数据交换都通过统一的输入输出契约来完成。比如抓取技能输出的订单数据不要直接传给汇总技能而是先落成标准 JSON 文件。这样每个技能都可以独立测试出了错也能快速定位是哪个环节的问题。后面我把统一数据结构这件事当作最重要的工作来做它直接决定了整套系统的稳定性和扩展性。3. 需求拆解订单抓取到底涉及哪些环节很多人觉得订单抓取就是「调接口拿数据」这个想法会让你在一开始就跑偏。我花了整整一个周末梳理需求最后列出来的完整链路比想象中长得多。3.1 数据获取的前置条件每个平台要打通数据前置条件完全不同。有的平台需要先申请开发者权限有的需要配置 IP 白名单有的需要做加密签名。我只说我遇到的情况具体以你手上的平台为准平台 A有开放 API但需要先通过企业资质认证认证通过后分配 API Key 和 Secret接口调用还需要对参数做 HMAC 签名。平台 B没有完整的开放 API或者说第三方 API 权限申请周期太长短期内只能用网页登录态抓取。平台 C有现成的第三方库官方维护可以直接调用但频率限制很严格。不同的前置条件直接决定了适配器的实现方式。第一个要确认的事情不是写代码而是确认数据通道能不能打通。这一步最少留出一周时间因为企业资质审核往往不是当天能完成的。3.2 取数、清洗、映射、汇总拿到原始数据只是开始。不同平台的订单结构差异非常大字段名、状态枚举、金额格式都不一样。拿「订单状态」举例A 平台叫order_status值是UNPAID、PROCESSING、SHIPPEDB 平台叫fulfillment_status值是pending、fulfilledC 平台的待发货状态藏在嵌套的子节点里。如果不对这些字段做统一映射后面所有统计分析都会出错。我定义的统一订单模型至少包含这些核心字段{ platform: shopee, order_id: SH20250601001, status: paid, created_at: 2025-06-01T10:30:00Z, items: [ { sku: SKU-A1001, name: 便携保温杯 500ml, quantity: 2, unit_price: 12.5, currency: USD } ], total_amount: 28.7, buyer_note: , shipping_address: { country: US, state: CA, city: Los Angeles, detail: xxx street No.9 }, raw_data: {} }这里的raw_data字段我特意保留了平台的原始返回方便日后排查问题。很多新手在清洗数据的时候习惯性地只取需要的字段把原始数据丢掉。但一旦发现某个字段映射错了没有原始数据就很难追溯。3.3 异常检测是人肉盯盘时代的刚需多平台订单最麻烦的是异常订单。比如买家已经取消但平台状态没更新、支付失败但订单挂了三天、地址不完整导致无法发货。以前人肉盯盘全靠经验去发现这些异常。现在技能化之后我把异常规则写进了汇总逻辑由系统自动打标。我用到的异常规则不算复杂但对于一个每天几百单的小团队来说非常实用订单创建超过 24 小时仍未支付自动标记为「待确认」状态为paid但地址信息不完整标记为「地址异常」同一买家短时间大量下单且地址不同标记为「风险订单」进入人工审核平台状态与物流状态矛盾比如已标记发货但没有运单号标记为「履约异常」这些规则在 Agent Skills 里实现起来并不难无非是在统一数据结构上做几层过滤判断但效果立竿见影。以前靠人工在几个后台里翻来翻去现在每天早上的工作变成了只看一张汇总表。4. 完整搭建流程六步走通多平台订单自动化这块是整个项目最核心的部分我会把每一步都讲清楚包括代码里面容易出错的地方。整个搭建过程我大约花了三个周末第一个周末搭框架第二个周末接平台第三个周末调异常和跑稳定性测试。4.1 第一步把所有平台账号和凭证集中到一个安全配置里这一步听起来很简单但问题很多。多平台意味着多套凭证有的平台是 API Key Secret有的平台是 Token还有的是需要定时刷新的临时凭证。我一开始把它们散落在不同的环境变量里结果有一次刷新 Token 后忘记更新配置第二天整个自动化就挂了。后来我把所有凭证集中到一个 config 文件里用环境变量引用关键信息结构大概长这样platforms: shopee: api_key: ${SHOPEE_API_KEY} api_secret: ${SHOPEE_API_SECRET} partner_id: ${SHOPEE_PARTNER_ID} shop_id: ${SHOPEE_SHOP_ID} endpoint: https://partner.shopeemobile.com amazon: access_key: ${AMAZON_ACCESS_KEY} secret_key: ${AMAZON_SECRET_KEY} role_arn: ${AMAZON_ROLE_ARN} endpoint: https://sellingpartnerapi-na.amazon.com tiktok: api_key: ${TIKTOK_API_KEY} api_secret: ${TIKTOK_API_SECRET} shop_cipher: ${TIKTOK_SHOP_CIPHER} endpoint: https://open-api.tiktokglobalshop.com这里有几个我在实际中踩过的坑凭证不要硬编码在代码里否则代码仓库一泄露所有平台账号都跟着出事。有些平台的 API 凭证是由主账号生成的子账号调用会被拒绝。配置之前先确认每个 Key 的权限范围。尽量留一个「测试凭证」和「生产凭证」的切换开关方便在开发阶段反复调试不会影响线上数据。4.2 第二步把每个平台的抓取逻辑封装成独立技能这是 Agent Skills 最核心的部分。每个技能对应一个平台技能目录结构我是按照官方的推荐方式来布局的skills/ ├── shopee_fetch_orders/ │ ├── SKILL.md │ ├── fetch_orders.py │ └── requirements.txt ├── amazon_fetch_orders/ │ ├── SKILL.md │ ├── fetch_orders.py │ └── requirements.txt ├── tiktok_fetch_orders/ │ ├── SKILL.md │ ├── fetch_orders.py │ └── requirements.txt └── merge_order_report/ ├── SKILL.md ├── merge.py └── templates/ └── report_template.htmlSKILL.md 的写法是决定 Agent 能不能正确调用技能的关键。我第一次写得太抽象Agent 根本不知道这个技能什么时候该用后面按照下面这个模板重新写了一次效果立刻不一样--- name: shopee_fetch_orders description: 从 Shopee 店铺后台拉取订单列表。当用户需要查询、汇总、分析 Shopee 平台订单时使用。 input: date_from: type: string format: YYYY-MM-DD required: true description: 起始日期含当天 date_to: type: string format: YYYY-MM-DD required: true description: 结束日期含当天 status: type: string enum: [ALL, UNPAID, PAID, SHIPPED, CANCELLED] required: false default: ALL output: type: json description: 订单列表每个订单符合统一订单模型写 SKILL.md 有一个技巧description 里一定要写清楚「什么时候用」不要只写「这个技能做什么」。比如「当用户需要查询、汇总、分析 Shopee 平台订单时使用」这句话就是告诉 Agent 触发条件。你给的信息越明确Agent 误判率越低。4.3 第三步实现平台适配器把不同的返回结果拉齐每个平台的接口返回结构都不一样适配器的作用是把它们统一成我前面提到的订单模型。我以其中一个平台为例展示适配器的核心逻辑为保护平台接口细节以下代码是简化示意实际对接时以平台官方文档为准# adapters/base.py class BasePlatformAdapter: def __init__(self, config: dict): self.config config def fetch_orders(self, date_from: str, date_to: str, status: str ALL): raise NotImplementedError def normalize(self, raw_order: dict) - dict: raise NotImplementedError # adapters/demo_adapter.py import requests import time import hashlib import hmac from .base import BasePlatformAdapter class DemoPlatformAdapter(BasePlatformAdapter): def fetch_orders(self, date_from: str, date_to: str, status: str ALL): # 1. 构造签名参数 timestamp str(int(time.time())) params { shop_id: self.config[shop_id], timestamp: timestamp, date_from: date_from, date_to: date_to, status: status, page_size: 100, } sign_string .join(f{k}{v} for k, v in sorted(params.items())) params[sign] hmac.new( self.config[api_secret].encode(), sign_string.encode(), hashlib.sha256, ).hexdigest() # 2. 请求订单接口 resp requests.get( f{self.config[endpoint]}/orders, paramsparams, headers{Authorization: fBearer {self.config[api_key]}}, timeout15, ) resp.raise_for_status() # 3. 解析并统一字段 orders resp.json().get(data, {}).get(orders, []) return [self.normalize(item) for item in orders] def normalize(self, raw_order: dict) - dict: return { platform: demo, order_id: raw_order.get(order_sn) or raw_order.get(id), status: self._convert_status(raw_order.get(order_status)), created_at: raw_order.get(create_time), items: self._extract_items(raw_order.get(item_list, [])), total_amount: float(raw_order.get(total_amount, 0)), currency: raw_order.get(currency, USD), raw_data: raw_order, } def _convert_status(self, raw_status): mapping { 0: UNPAID, 1: PAID, 2: SHIPPED, 3: CANCELLED, } return mapping.get(raw_status, UNKNOWN) def _extract_items(self, item_list): items [] for item in item_list: items.append({ sku: item.get(item_sku), name: item.get(item_name), quantity: int(item.get(quantity, 0)), unit_price: float(item.get(price, 0)), currency: item.get(currency, USD), }) return items这一步是整个项目工作量最大的地方每个平台都要单独写一套适配器。我的经验是先把一个平台完整跑通再复制结构去适配第二个平台千万不要同时开三个平台的开发。因为第一个平台踩过的坑签名算法、分页策略、字段映射会在后面每个平台里重复出现先完整走通一遍流程后面就是机械复制改字段名了。4.4 第四步实现汇总逻辑与异常检测汇总逻辑本身不难难的是让它足够「通用」。我选择把汇总做成一个独立技能输入是所有平台的统一订单 JSON输出是 HTML 报表和 CSV 文件。核心思路是先按平台分类再合并同一天、同一状态的订单计算汇总指标。异常检测放在汇总之前因为异常订单需要单独标记不应该混入正常统计。汇报生成这块我最后选择了 HTML 模板的方式。原因很简单运营同事和我自己看报表的习惯不一样HTML 可以内联 CSS在手机上看排版不乱也能直接截图发到群里。4.5 第五步接入 Agent 调度与工作流定时执行技能都封装好了剩下的问题是谁来调度它们我的方案是分两层。第一层是 Agent 对话入口适合临时查询用户直接说「把这两天 TikTok 的订单情况拉出来」Agent 解析出意图平台tiktok、时间近两天、目标订单列表然后调用对应的技能。第二层是固定工作流每天早上 9 点由调度器触发按照固定顺序自动执行抓取所有平台订单 → 清洗合并 → 生成报表 → 推送到企业微信/钉钉机器人。Workbuddy 在这里的角色就是把我写的这些技能按业务规则串成可监控、可重试的自动化工作流。它本身并不是什么魔法核心价值在于把「什么时候触发、哪个技能在前哪个在后、失败怎么办」这些流程节点管理起来同时保留每次运行的日志。日志这个东西前期看不出价值等出了问题你才知道它救命。4.6 第六步告警机制——没有告警的自动化就是定时炸弹自动化最怕什么最怕它「安静地出错」。程序跑了但抓的是空数据因为没有告警你根本不知道直到下午才发现今天完全没处理订单。我加了三种告警数据量为 0 告警某平台返回订单数为 0需要人工确认是平台休息日还是接口异常。接口异常告警调用返回 5xx 错误码、超时、签名失败。这种通常是平台侧问题或者凭证过期需要人介入。汇总偏差告警昨日订单金额与近 7 日均值偏差超过 50%提示运营重点核查。告警通道用的是企业微信群机器人通过 webhook 推送配置简单、免维护。后来我又加了短信告警接口仅在接口异常时才触发因为短信会产生费用没必要每条消息都发。5. 一个完整的技能调用示例从用户问到结果输出为了让你直观感受 Agent Skills 在工作流里的表现我把一个真实的调用过程简化后贴出来。用户输入帮我看下昨天各平台的待发货订单汇总成一张表。Agent 解析后的执行计划识别意图查询多个平台的待发货订单生成汇总表。判断需要调用的技能shopee_fetch_orders、amazon_fetch_orders、tiktok_fetch_orders、merge_order_report。确定时间范围昨天 00:00 到 24:00。确定订单状态SHIPPED之外的所有已支付订单实际业务中待发货 已支付未发货。Agent 依次调用技能得到三个 JSON 文件。汇总技能的伪逻辑如下def merge_order_report(order_files, output_dir): all_orders [] for file in order_files: with open(file, r, encodingutf-8) as f: orders json.load(f) all_orders.extend(orders) pending_ship [ order for order in all_orders if order[status] paid and not order[raw_data].get(tracking_number) ] report { total_orders: len(all_orders), pending_ship_count: len(pending_ship), pending_ship_orders: pending_ship, platform_breakdown: { platform: sum(1 for o in all_orders if o[platform] platform) for platform in set(o[platform] for o in all_orders) }, } # 生成 HTML CSV # ... return report最后推送出来的报表长这样平台昨日订单数待发货异常订单Shopee4751地址异常亚马逊1220TikTok3581风险订单整个过程从用户在群里发消息到收到报表推送大约需要 1 分 40 秒。这个耗时主要是等待平台接口响应Agent 本身的决策开销其实在 5 秒以内。6. 实测踩坑记录这些问题我不希望你再走一遍这个项目让我重新认识了「看教程全会一上手就废」这句话。下面几个问题是我实际运行期间遇到的基本都属于文档里不会写、但是真实环境一定会碰到的类型。6.1 平台接口频率限制导致的全链路超时第一次跑完整流程的时候我在测试环境调通了所有平台但上线当天就收到告警所有平台的调用都超时了。排查过程让我印象深刻先看日志发现每个平台的请求都卡在resp.raise_for_status()之前。手动用 curl 请求同样的接口发现响应正常。回到代码检查才发现是我的请求队列里积压了大量并发请求触发了平台的频率限制。原因是测试环境数据量小每次只拉几十条订单并发无压力。生产环境第一次跑的是近 30 天的全量数据分页请求瞬间高并发平台直接限制了我的调用频率。解决办法是在每个适配器里加了全局限流器用简单的令牌桶算法控制每个平台的请求速度同时把全量历史数据抓取改成「首次手动跑 后续增量跑」的策略。6.2 状态字段的「语义漂移」这是我个人认为最隐蔽的坑。不同平台对订单状态的定义不一样甚至同一个平台在不同 API 版本下也不一样。举一个例子平台 A 有一个状态叫COMPLETED我一开始想当然地把它映射成「已完成」。后来核对物流信息才发现这个状态在平台 A 的语义里其实是「买家已确认收货订单完成」在平台 B 的同类状态下订单可能还在运输途中。这种字段的「语义漂移」是数据聚合类应用最容易出错、也最难过早发现的问题。它不会报错数据都能跑通但统计口径是错的。我的建议是状态映射表一定要找该平台实际的业务运营同学确认一遍不要只凭接口文档猜。6.3 Token 定时刷新导致的静默失败某平台的接口凭证有效期只有 15 天过期后自动刷新逻辑有个边界 bug——当刷新请求本身超时代码会直接抛异常但外层 catch 只捕获了数据请求的异常没有捕获刷新异常。结果就是每天早上 9 点工作流准时开跑但 9 点 03 分就静默失败然后一直等到第二天早上才发现问题。这个坑让我意识到告警不仅要覆盖「数据异常」还要覆盖「流程没有正常完成」。我后来在调度器里加了一个「心跳检查」如果工作流在 10 分钟内没有正常结束强制推送一条告警。6.4 页面结构变化导致的网页端爬取失效前面提到有一个平台因为没有现成的开放 API 权限我用了网页登录态抓取的方式过渡。这个方法最大的问题是前端页面只要一改版选择器就全部失效。前后三个月我修了两次选择器。最后一次我索性换了个思路能申请 API 权限的都优先申请 API实在不行的再考虑网页端抓取而且网页端抓取只做兜底不做主路径。现在回头看当初为了赶进度选择网页抓取反而在后面花掉了更多时间维护。7. 上线跑了一个月实际效果、成本与后续扩展最后说说这个项目上线之后的表现以及我基于这个实战对 Agent Skills 后续方向的一些判断。效率方面的提升是实打实的。以前每天早上的订单处理流程大约要一个半小时登录三个后台、导出、清洗、整理到表格现在变成全自动早上只需要打开报表扫一眼异常项。每周五我还会跑一次周报生成技能自动汇总本周各平台的销售数据这个以前需要两个小时来做。成本方面主要开销是自动化工作流的运行费用每个月大概几十美元级别加上偶尔用到的模型推理费用Agent 调度决策这部分消耗并不多整体成本远低于招一个运营助理来干这些重复活。这里有一点建议能写死逻辑的地方不要用模型推理只有「意图识别」和「任务拆分」这两个环节值得让模型参与。如果每一个字段映射都要模型来思考Token 费用会直线上升响应时间也会变得不可接受。后续扩展方向我目前已经在做两件事一是把技能从「订单抓取」扩展到「售后工单处理」。思路完全复用现有的架构新增工单类技能接入客服平台的工单接口由 Agent 自动分类、打标、回复常见问题复杂工单转人工。二是把多平台的商品信息同步做成技能。现在上架新品要在不同平台重复填一遍信息用 Agent Skills 之后只需要维护一份商品主数据由技能自动分发适配到各平台。最后分享一个我在这个项目里最大的感受Agent Skills 真正的门槛不在技术而在你能不能把业务拆成边界清晰、职责单一的技能单元。拆得好AI 会帮你做很多事拆得烂AI 反而会把你的流程变得不可控。多花点时间在需求梳理和契约设计上后面你会感谢自己。