下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-8oiv8bfc--dw-business-assistant.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-8oiv8bfc/dw-business-assistant。Use when an external agent needs 大为导师端课程与会员查询、经营分析、CRM 洞察、售卡升卡、门店商品管理,或通过员工确认授权执行同步业务操作。
阅读全文 (展开查看完整说明)
概述
适用范围
使用本 Skill 查询授权范围内的课程、会员、课程卡、导师、订单、经营数据、CRM 客户与门店商品,或执行课程事务、售卡升卡和商品上下架操作。所有受保护请求只使用员工确认后签发的 Active Ticket;正常使用时不要读取数据库、调用旧 AI Agent 接口或依赖 backend 源码。
本 Skill 是唯一发布和安装单元。使用 --auth-package BUSINESS_INSIGHTS|CRM_INSIGHTS|CARD_SALES|STORE_MANAGEMENT 为对应领域发起员工确认;同一包内脚本私密复用 Ticket,不向用户展示。
课程生命周期规则仍由现有业务 Service 负责。本 Skill 只按接口返回的 state、actions 和状态字段判断下一步,不在本地复制生命周期规则。
快速开始
在 backend 仓库根目录运行:
python external-skills/dw-business-assistant/scripts/query_course_data.py领域能力路由
先使用 query_course_data.py --action auth-start --auth-package <功能包> 和 --action auth-wait 完成员工授权,再按业务领域调用下列包内脚本。不要要求用户提供 Ticket;Agent 只在进程间私密传递 Active Ticket。
| 业务领域 | 功能包 | 脚本 | 详细规则 |
|---|---|---|---|
| 课程、会员、课程卡和十三个同步操作 | 按动作选择 | scripts/query_course_data.py | references/api.md |
| 经营数据、导师收入和转化分析 | BUSINESS_INSIGHTS | scripts/business_insights.py | references/business-insights.md |
| CRM 线索、续费会员、跟进记录和 AI 新增跟进 | CRM_INSIGHTS | 查询用 scripts/crm_insights.py;新增用 scripts/query_course_data.py | references/crm-insights.md |
| 会员卡订单、售卡、转卡和升卡 | CARD_SALES | scripts/card_sales.py | references/card-sales.md |
| 门店商品查询、上架和下架 | STORE_MANAGEMENT | scripts/store_management.py | references/store-management.md |
处理对应领域请求前必须读取相应 reference;公共授权、敏感字段、候选消歧、警告展示、显式确认和幂等规则仍以本文件为准。
升卡订单金额与支付语义
处理 CARD_SALES 升卡时,严格按管理端字段语义传参,不得根据商品价格或原订单实付自行推导差价:
- 订单价格(请求和返回字段
orderAmount):升阶完成后新会员卡订单的价格,对应管理端totalPrice。它不是本次待支付金额,与是否补差价相互独立。 - 补差价金额(请求字段
priceDifferenceAmount,报价和支付意图返回字段priceDifference):本次用户实际需要支付的差价,对应管理端payPrice。只用这个金额判断是否进入支付流程,不得用orderAmount、目标商品价格或原订单实付替代或重新计算。 - 总课次(请求及报价字段
totalClassHours):仅升阶目标为正式课次卡时可选。用户明确指定时原样传递1..1000000的整数;未指定时省略,由后端使用目标卡商品默认课次。目标为时间卡时不得传该字段。 - 有效期(请求及报价字段
validityDays):用户明确指定时原样传递1..36500的整数;未指定时省略,由后端使用目标卡商品默认有效期,不得沿用源卡剩余有效期。 - 原订单实付(返回字段
oldPaidAmount):仅用于说明原会员卡订单历史支付情况,不参与 Skill 的差价计算。 - 支付方式(支付意图请求字段
paymentChannel):仅在补差价金额大于 0 时选择。当前实际可用值为WECHAT;补差价为 0 时不得询问、选择或传递支付方式。 - 补差价支付二维码(返回字段
paymentQrCodeUrl):选择WECHAT并创建支付意图后生成的微信 Native 支付二维码,提供给操作人员支付补差价。它不是授权二维码,也不代表已经支付。
按补差价金额路由:priceDifferenceAmount=0 时调用 upgrade-zero-price,请求同时传 orderAmount 和固定为 0 的 priceDifferenceAmount,展示预览并等待用户明确确认,不创建支付意图;priceDifferenceAmount>0 时先调用 paid-upgrade-quote,报价确认后再选择支付方式并调用 paid-upgrade-create。
升阶前先从正式卡候选列表确认目标类型。课次卡可按用户要求传 totalClassHours,时间卡必须省略;报价或零差价预览返回的最终课次和有效期才是确认时展示的准确信息。不要自行添加契约未声明字段。
例如用户说“订单价格 999,不补差价”时,必须理解为 orderAmount=999、priceDifferenceAmount=0,走零差价确认流程,不询问支付方式、不生成支付二维码。不得把 999 当作补差价或待支付金额。
默认配置:
- Backend:
https://testlearningadmin.jkcspace.com/prod-api - Web:
https://testlearningadmin.jkcspace.com - 查询 scene:
SKILL_COURSE_QUERY - 默认 action:
course-data - 默认课程时间范围:
Asia/Shanghai时区的本周一 00:00 至下周一 00:00 - 授权 action:
auth-start、auth-wait、revoke-ticket
本 Skill 零配置、开箱即用。Agent 不询问用户任何 Client ID/Key/Secret,也不要求设置环境变量或可信客户端凭证。
发布包可包含 config/runtime-config.json,用于写入 local、test 或 prod 的公开 Backend/Web 地址。地址优先级固定为:显式 --backend-base-url / --web-base-url > 包内运行时配置 > 源码开发环境变量 > 上述源码默认测试地址。源码目录没有包内配置时仍可直接运行;环境化配置不改变授权、确认、幂等或业务规则。
本地 E2E 可直接增加 --backend-base-url http://localhost:8118 --web-base-url http://localhost 运行,无需额外 Skill 配置或可信凭证。这是精确的 localhost:80 loopback 入口,不代表接受任意 HTTP、其他主机、IP 或自定义端口。
缺少有效 Ticket 时,auth-start 创建或恢复 NEW、EXTEND、REPLACE 授权会话并立即返回“大为同学管理后台”授权链接和“大为导师端”扫码二维码,不在 CLI 内展示或等待,也不自动打开“大为同学管理后台”。直接运行查询、写操作或操作组时如果发现缺少权限,也只创建或复用相同 pending、返回 authorization_pending 后退出;完成授权后重跑原 action。
所有 Agent 必须使用 auth-start 和 auth-wait 两阶段授权。宿主之间的唯一区别是二维码的展示方式;授权会话、pending、等待和 Ticket 激活协议完全相同。
EXTEND 和 REPLACE 会话绑定原授权账号,展示授权入口时必须提醒用户使用原授权账号,不得更换账号。若授权页返回 SESSION_NOT_FOUND,这可能是打开页面时更换了登录账号;提示用户切回原授权账号后重试。确需更换账号时,必须重新发起授权,不得继续等待当前 pending。
用户明确指定授权有效期时,Agent 必须识别分钟、小时或天,并精确换算为整数分钟,通过 --requested-validity-minutes <分钟> 传给 auth-start 或会自动发起授权的原 action;例如“授权 7 天”必须传 --requested-validity-minutes 10080。用户未指定时使用默认 1440 分钟(24 小时)。允许范围为最短 10 分钟、最长 43200 分钟(30 天);超出范围时提示用户调整,不得静默截断或改写。requestedValidityMinutes 控制授权成功后的 Ticket 有效期;创建响应的 expiresAt 是本次授权链接和二维码的授权截止时间,当前由服务端设置为 10 分钟,两者含义不同。已有有效 Active Ticket 时,用户只有明确要求修改授权有效期才使用 --force-auth 发起 REPLACE;不要为了沿用默认值重复授权。
Agent 在写意图明确后立即运行 auth-start,不得先执行与授权无关的澄清和文件读取;WorkBuddy 还不得先创建 TaskCreate 任务。auth-start 返回“大为同学管理后台”链接和“大为导师端”二维码后立即退出:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-start --auth-package COURSE_SCHEDULING --auth-package CARD_CONSUMPTION
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-start --auth-package COURSE_SCHEDULING --requested-validity-minutes 10080Agent 必须把 CLI 返回的 authorizationUrl 原样作为可点击链接写入用户可见消息,并展示 mediaItems 中的授权二维码。expiresAt 必须进入用户可见消息,作为授权请求的有效期并明确标为“授权截止时间”;授权截止时间不得省略。授权链接和二维码都已实际展示,才能运行 auth-wait,不等待用户回复“已完成”:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-wait --poll-timeout-seconds 90所有宿主都必须先把授权链接和二维码实际展示给用户,再运行 auth-wait,展示与等待不得并行。CLI 返回 authorizationUrlDisplayRequired=true、authorizationQrDisplayRequired=true、authorizationExpiresAtDisplayRequired=true 和 nextActionBlockedUntil=authorization-link-and-qr-presented 时,将其视为硬前置条件。WorkBuddy 使用 present_files 时,present_files 与 auth-wait 不得出现在同一模型响应或并行工具批次中;只有返回结果的 previewed 明确包含目标二维码的 localPath,才算二维码展示成功。status=completed 或成功文案本身不能证明展示成功;previewed=[] 时立即结束当前轮次,让二维码在任务完成后作为任务产物展示,并且不得声称“二维码已展示”。不要用“同时展示并等待”等表述触发并行调用。
如果授权链接和二维码任一没有实际展示,Agent 不得调用 auth-wait,也不得在授权入口不完整时循环等待。CLI 的 authorizationEntryUnavailableAction=end-turn 表示此时必须立即结束当前轮次并保留原 pending,不新建授权会话、不清理二维码、不调用 revoke-ticket。结束当前轮次前,用户消息必须展示授权链接和授权截止时间,并保留二维码为任务产物,二维码由宿主在任务结束后展示;同时明确提醒用户完成授权后在当前会话回复“已授权”。用户在当前会话回复“已授权”后,下一轮先执行 auth-wait 恢复同一 pending,成功后再重跑原业务 action。不得要求用户切换或新建会话,也不得在用户回复前反复调用 auth-wait。
只有用户明确表示已经完成授权时,当前会话的下一轮才可直接调用 auth-wait;这是授权入口展示前置条件的唯一例外。如果用户在当前会话只说“继续”或没有确认已经授权,Agent 不得调用 auth-wait;必须先运行 auth-start 恢复同一 pending 并重新展示授权入口,仍无法展示时再次结束当前轮次。CLI 的 currentConversationResumeRequiresUserAuthorization=true 是硬条件,不能把普通跟进消息当作已经授权。
超过授权截止时间后不得直接调用 auth-wait;必须重新运行 auth-start,由 CLI 按过期规则清理旧 pending 并创建或恢复有效授权申请,再按上述规则展示授权入口。
遇到 AUTH_POLL_TIMEOUT 时,必须重新展示同一 pending 的授权链接、二维码和授权截止时间;确认链接与二维码都实际可见后,再重试同一 pending 的 auth-wait。AUTH_POLL_TIMEOUT 后重新展示失败时,立即结束当前轮次并保留 pending,不得进入入口不完整的轮询循环。不得新建授权会话,也不得调用 revoke-ticket。auth-wait 从本地 pending 恢复原申请权限,不接受 --auth-package。
私密 pending 保存 sessionCode、pollToken、authorizationUrl、qrCodeUrl、本地 qrCodePath、有效期、申请项和 installation 上下文。复用 pending 时重新展示同一“大为同学管理后台”链接、“大为导师端”二维码和授权截止时间;确认链接与二维码都已实际展示后,再在新的模型步骤中单独运行 auth-wait。网络错误、timeout 和未确认终态保留 pending;确认拒绝、会话过期或不可确认时清理 pending 和临时二维码;成功激活后由正式 Ticket 原子替换 pending。
脚本在用户私有缓存目录生成稳定随机的 installationId,该值只用于关联同一安装,不作为认证证明,也不出现在公开输出中。设备信息只读取 os、osVersion、architecture、deviceType;不得读取 hostname、用户名、IP、MAC、网卡或硬件序列号。
使用规则
- 只使用查询接口返回的
storeHandle、memberHandle、cardHandle、teacherHandle、coursePlanHandle、courseOrderHandle等公开 handle,禁止猜测或传递内部 ID。 - 权限范围由确认授权的员工和 Ticket 校验结果决定;不要自行指定或扩大公司、门店、员工或角色范围。
- 纯查询、
course-data和未带--auth-package的auth-start只申请SKILL_COURSE_QUERY / READ。 - Agent 必须先识别用户最终意图。最终意图包含写操作时,必须在任何前置查询之前运行
auth-start --auth-package <功能包>申请对应完整功能包;授权完成后再查询写操作所需的公开 handle。不得因为第一步是查询而先申请只读权限。 --auth-package可重复,一次申请多个权限包。同时申请COURSE_SCHEDULING与CARD_CONSUMPTION时只创建一次授权会话,只确认一次。- 直接执行写动作时,Skill 也会自动申请该动作所属的完整功能包;同包后续动作复用 Ticket,不再重复授权。首次使用另一个功能包时,通过一次
EXTEND增加该包。
固定功能包:
| 功能包 | 动作 |
|---|---|
COURSE_SCHEDULING | schedule-course、reschedule-course、delete-course |
CARD_CONSUMPTION | consume-card、change-card-consumption、mark-single-buy-absent |
COURSE_FEEDBACK | submit-feedback、update-feedback |
BUSINESS_INSIGHTS | 经营数据、导师收入和转化只读查询 |
CRM_INSIGHTS | CRM 客户与跟进记录查询、AI 新增跟进 |
CARD_SALES | 会员卡订单查询、create-card-order、transfer-card、upgrade-card-zero-price 和付费升卡 |
STORE_MANAGEMENT | 门店商品查询、set-store-product-status |
每个功能包都包含 SKILL_COURSE_QUERY / READ 和表中动作对应的 WRITE scene。确认页仍逐项展示具体 scene;功能包名称不参与服务端权限裁决。多项 Ticket 只能整张撤销,不能在同一张 Ticket 内单独撤销一个功能包。
NEW 与 REPLACE 的创建响应必须与请求严格相等。EXTEND 的目标允许包含旧权限,但必须包含本次所有请求权限;accessBits 使用按位包含校验。
例如,用户要求排课和扣卡时,第一条授权命令可同时申请两个功能包:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-start --auth-package COURSE_SCHEDULING --auth-package CARD_CONSUMPTION- Backend 写接口同步返回结果;Skill 根据本地确认策略选择预览后暂停或直接提交。执行成功时公开
operation、affectedResources、state、actions、idempotencyReplay和requestId。 - 每次写请求必须提供稳定的
--idempotency-key。同一业务意图重试时复用原值;不同业务意图使用不同值。 - 排课、改排课、删除排课、扣卡、修改扣卡、提交反馈、修改反馈分别调用既有业务 Service,不在 Skill 中实现业务规则。
- 新建普通排课时初始带学员可使用
schedule-course.memberSelections;单次买排课不得携带初始学员。给已有排课添加、移除或替换学员使用增量reschedule-course.memberChanges,仍属于SKILL_COURSE_RESCHEDULE。不得删除原排课再重建,也不得因此申请SKILL_COURSE_DELETE权限。 - 已有课程学员变更前,Skill 按
coursePlanHandle查询课程计划并读取courseType与actions.modifyMembers。普通课程在未开始、进行中或已结束时均可管理学员;SINGLE_BUY单次买课程不可修改学员。 - 删除学员必须在
memberChanges.remove传查询返回的courseOrderHandle。Skill 会查询课程订单预检;consumeStatus=CONSUMED的订单公开拒绝,已结束课程中UNCONSUMED的订单仍可删除。服务端会再次校验,不能绕过。 - 添加学员先用
course-cards查询课程适用卡,正式卡、体验卡均可选,不要求存在正式会员关系。在memberChanges.add传cardHandle,或传memberHandle由预览推荐卡;同时传两者时必须属于同一学员。禁止使用内部 ID。 - 预览默认卡顺序:显式选择 > 最近已扣卡课程所用且仍可用的卡 > 最早到期的可用卡。展示预览中的学员、卡名、来源和课时;用户改选后重新预览。确认执行绑定预览选卡,卡不可用时重新预览,不静默换卡。
- 未扣卡记录换卡使用
memberChanges.update,每项传courseOrderHandle与cardHandle;保留原课程订单,仅改预约卡项。已扣卡记录使用change-card-consumption。编辑现有记录时默认沿用当前卡。 - 添加学员返回
COURSE_MEMBER_ALREADY_EXISTS、MEMBER_NO_BOOKABLE_CARD、CARD_NOT_FOUND、CARD_MEMBER_MISMATCH、CARD_STORE_MISMATCH、CARD_UNAVAILABLE、CARD_CATEGORY_MISMATCH、CARD_EXPIRED、CARD_BALANCE_INSUFFICIENT等已登记 reasonCode 时,直接展示服务端返回的安全message,不要自行猜测原因或修复方式。未知BUSINESS_RULE_REJECTED只说明具体原因未公开,并展示requestId便于排查。 - 学员变更写成功后,Skill 按
coursePlanHandle回读course-orders。CLI JSON 保留verification.memberHandles供 Agent 内部核对;用户可见结果摘要只使用会员姓名、人数和变更状态等业务信息描述回验结论。回验失败不抹掉已成功写入的结果;CLI JSON 保留verification.status=WRITE_SUCCEEDED_VERIFICATION_FAILED,用户只看到写入成功但回验未完成的业务说明,不输出 Ticket 或底层异常。 - 反馈只允许提交和修改,不允许删除。不要构造或寻找反馈删除动作。
- 两个反馈 scene 只用于接口路由、授权配置、幂等作用域和审计,不构成基于反馈当前状态的强隔离。调用前先根据只读查询返回的
actions选择提交或修改入口;服务端沿用现有反馈变更 Service,不校验当前是否已有反馈。 - 绑定已有课程的扣卡或反馈前,先查询课程计划或课程订单,并遵循接口返回的可操作状态。
- 处理缺课结算时,只使用
course-orders返回的结构化orderKind与actions.markAbsent分流:CARD普通订单继续走consume-card;SINGLE_BUY且actions.markAbsent.allowed=true时走mark-single-buy-absent。不得根据课程名称、价格、cardHandle或自然语言猜测订单类型。 - 单次买课程计划显示“待标记缺课”时,表示仍需完成订单级结算,不得写成“无需扣卡”或“无需结算”。单次买不使用
consume-card扣会员卡;应查询关联的SINGLE_BUY订单,并仅在actions.markAbsent.allowed=true时调用mark-single-buy-absent。单次买反馈与订单结算状态相互独立:只按结构化动作分流,actions.submitFeedback.allowed=true时提交反馈,actions.updateFeedback.allowed=true时修改反馈;不得因订单是单次买、已标记缺课或未核销而显示“无需反馈”。 - 导师给课程添加学员时,接口中的
expectedCardClassHours表示本次预计扣卡课时,也是本次预计占用的预约课时,统一按可约课时 = max(剩余课时 - 已预约课时, 0)判断。新增学员或换卡时,可约课时不足会返回公开业务拒绝;已有学员沿用原卡只修改排课课时时不做该容量校验。schedule/reschedule 的 preview 使用非锁定快照,同一卡在本次请求内累计判断;preview 成功不会预留可约课时,execute 会在事务锁内重新校验。专属卡仍需品类匹配,通用卡不校验品类。 - 实际扣卡的有效期按
Asia/Shanghai自然日判断:课程日期不晚于到期日期即可,到期当天仍可用于当天课程,不与当前执行扣卡时间比较;实际扣卡校验中expireTime为空不因有效期阻断。选卡使用course-cards返回的当前课程候选,门店、品类、核销、余额和当天次数由服务端校验,不根据卡名自行推断可用性。 - 扣卡返回
CARD_NOT_VERIFIED等已登记的稳定扣卡 reasonCode 时,直接向用户展示服务端返回的安全message,不要根据卡名或自然语言猜测原因。未知BUSINESS_RULE_REJECTED只说明具体原因未公开,并展示requestId便于排查。 - 查询课程时,先识别用户表达的时间范围。用户明确“今天”“本周”、具体日期或日期范围时,必须换算为
Asia/Shanghai时区的明确起止时间并通过--start-from、--start-to或timeWindow传入;显式范围始终覆盖默认值。用户未表达时间范围时,才使用本周一 00:00 至下周一 00:00 的默认范围。 - 用户可见回答中的“今日”“本周”或具体日期范围必须根据本次实际请求时间窗生成。
course-data读取输出中的request.startFrom、request.startTo,course-plans读取request.body.timeWindow;不得把今日数据描述为本周数据,也不得把其他实际窗口描述成用户原始表达。 - “待扣卡课程”只包含课程计划输出中
consumeActionable=true的项目。该值由公开接口的actions.consume.allowed归一化得到;未开始、上课中、已取消或其他不可扣卡课程不得进入待扣卡列表。 - 不输出 Ticket、poll token、exchange receipt、installationId、完整手机号、内部 grant/公司/门店/员工 ID 或底层异常;完整
sessionCode只允许存在于服务端生成并展示给用户的“大为同学管理后台”授权链接中。
用户展示
handle 是 CLI 结构化结果和 Agent 内部使用的操作引用。Agent 可以用 handle 关联候选对象、构造后续请求、恢复 pending 和执行回验,但用户可见的自然语言、Markdown 表格、候选列表、确认摘要、结果摘要和错误说明不得展示 handle,也不得把包含 handle 的原始 JSON 直接转发给用户。
回答优先展示名称、label、门店、课程、会员、卡类型、手机号脱敏尾号、日期、时间、课时、剩余次数和状态。同名对象先用这些业务字段消歧,仍无法区分时使用仅在当前候选列表有效的临时序号;用户选择后,Agent 在内部使用对应 handle,不回显序号与 handle 的映射。
缺少可读字段时先执行已有查询补充上下文。仍无法获得名称时,使用“所选课程”“该会员卡”“这条课程记录”等上下文描述,不得以展示 handle 作为兜底。确认摘要使用名称、时间、状态和具体业务变化描述将要执行的操作。
课程名称和课程状态必须分别展示。课程名称缺失且无法通过已有查询补充时统一显示“该课程”,不得使用“上课中”“未开始”“已结束”等 displayStatus 状态文案代替课程名称。
课程列表按“课程内容、品类、日期、时间、导师、场地、学员、状态”的顺序组织信息;字段存在时必须展示,字段不存在时省略,不得只展示时间、学员数和状态。课程订单或反馈列表同样展示已有的课程名称。反馈正文 feedbackContent 非空时必须完整展示为业务数据,正文为空时省略;图片单独显示数量或是否有图,不得声称外部接口不返回反馈正文。
课程订单或授权展示中的 mediaItems 由 Agent 消费。反馈图片的宿主展示优先级固定为图片 -> 富媒体卡片 -> 本地文件链接 -> Windows 资源管理器。支持图片时直接贴图;宿主不支持图片但支持卡片时使用富媒体卡片且不下载。只有宿主图片和卡片能力都不可用时,才以 --action course-orders --materialize-images 重查反馈图片;不得默认下载反馈图片。物化失败时保留反馈正文和其他可展示媒体,不得因单张图片失败而隐藏反馈正文。
在 WorkBuddy 中,只要宿主提供 present_files,反馈图片就必须先转为本地文件再展示:遇到 REMOTE_ONLY 时,以 --action course-orders --materialize-images 重查并静默下载。调用 present_files 时,files 只能传入所有 LOCAL_READY 项的 localPath 绝对路径;不得把 remoteUrl、HTTP URL 或 HTTPS URL 传给 present_files。cwd 传绝对工作目录,explanation 传不含路径的简短说明;多张反馈图片保持原顺序,再在一次调用中提交。反馈图片调用 present_files 后,只有 previewed 明确包含所有目标的 localPath 才算成功。即使图片位于工作区外,localPath 绝对路径也必须原样传入。宿主提供 present_files 时不得调用 explorer.exe 降级,也不得用 Read、普通文件读取、任务输出或聊天正文中的路径代替展示;调用成功后不再向用户展示裸路径。本段规则只适用于反馈图片;授权二维码使用下述独立降级流程。
授权二维码使用独立降级流程,不得调用 explorer.exe、Start-Process 或任何命令打开 Windows 资源管理器。降级时必须在用户消息中给出授权链接、二维码和授权截止时间,然后立即结束当前轮次,并提醒用户授权后在当前会话回复“已授权”;不得继续调用工具、尝试定位本地文件或进入 auth-wait。二维码无法在处理中预览时,保留为任务结束后展示的任务产物,不向用户显示裸路径。CLI 返回 authorizationExplorerForbidden=true 和 authorizationFallbackAction=present-link-and-qr-then-end-turn 时必须按此流程执行。
反馈图片在宿主未提供 present_files 时,允许按本地文件链接到资源管理器的顺序降级。可点击的本地文件链接可用时,链接可见文字必须是 displayName,链接目标使用 localPath。不得向用户展示裸 URL 或裸路径,也不得把命令本身展示给用户。Windows 文件链接不可用时,Agent 在本地调用 explorer.exe /select,<absolute-path>,对用户只回复“已在资源管理器中定位图片”。
mediaItems 中 AUTHORIZATION_QR 是授权二维码,remoteUrl 固定为 null;FEEDBACK_IMAGE 是课程反馈图片。它们的字段、状态和按需物化语义见 references/api.md。
例如,同名会员候选可展示为“1. 张三,手机号尾号 1234,成人次卡,剩余 8 课时”;不得展示为“张三(member_handle_001 / card_handle_001)”。结果摘要使用业务字段说明成功、失败或回验状态。错误说明只展示公开错误码、可读消息和建议动作,不粘贴包含 handle 的异常或原始结果。
“大为同学管理后台”授权链接是服务端生成的完整入口,允许原样展示;不得拆解或单独讲解链接中的会话参数。
查询动作
先通过查询拿到写操作所需的公开 handle。例如:
- 课程添加学员、排课换卡和扣卡选卡统一用
course-cards,不要先用正式会员搜索限制候选。已有课程传coursePlanHandle;新课程传storeHandle、categoryHandle、startTime、classHours。可按nameKeyword、mobileTail4或memberHandle筛选。查询按学员分页,一页包含这些学员的所有可用卡。 - 编辑卡项额外传
courseOrderHandle;扣卡和修改扣卡加purpose=CONSUMPTION,排课默认BOOKING。使用返回的courseCard_...原样传递,不拼接或推导卡来源;cardSource=FORMAL|EXPERIENCE仅用于展示。旧card_...仍只代表正式卡。 - 按返回的
recommended和recommendationReason展示默认卡,用户可以改选其他候选;编辑时若当前卡已不可用、没有推荐项,不自动替换为另一张卡。bookableClassHours=null表示时间卡不按课时计算可约余额,不代表 0 课时或无限次可用。分页的size、total按学员计数,items数量可能大于size。 - 使用
members-search查询正式会员,结果包含正常、预警和流失会员;体验卡线索不在本期范围内。 memberType直接沿用“大为导师端”会员分类:NORMAL(正常会员)、WARNING(预警会员)、LOST(流失会员)。流失会员仍可返回memberHandle;卡片是否可用以member-cards的结果为准。- 处理
member-cards时只按接口返回的cardScope判断品类:cardScope=GENERAL表示通用卡,任何课程品类都可预约,不校验categoryHandle;cardScope=CATEGORY表示专属卡,只有categoryHandle与课程品类匹配时才可使用。不要根据cardName、课程名称或自然语言语义推断是否通用卡;cardType只表示计次/体验/时间等卡类型,不表示通用范围。 members-search和teachers的姓名查询参数统一为nameKeyword。CLI 兼容旧输入keyword、keyWord,但发往 OpenAPI 的请求只使用nameKeyword;多个名称字段同时出现时直接提示参数冲突,不重新授权或重复确认。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action course-plans --payload-json '{"timeWindow":{"startTime":"2026-07-12T00:00:00+08:00","endTime":"2026-07-13T00:00:00+08:00"}}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action members-search --payload-json '{"nameKeyword":"spade5"}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action teachers --payload-json '{"nameKeyword":"王导师"}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action member-cards --payload-json '{"memberHandle":"member_handle_001","usableOnly":true}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action course-orders --payload-json '{"coursePlanHandle":"course_plan_handle_001"}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action course-cards --payload-json '{"coursePlanHandle":"course_plan_handle_001","nameKeyword":"小明","purpose":"BOOKING"}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action course-cards --payload-json '{"coursePlanHandle":"course_plan_handle_001","courseOrderHandle":"course_order_handle_001","purpose":"CONSUMPTION"}'
python external-skills/dw-business-assistant/scripts/query_course_data.py --action course-operation-feasibility --payload-json '{"operation":"RESCHEDULE","coursePlanHandle":"course_plan_handle_001","startTime":"2026-07-13T10:00:00+08:00"}'course-orders 的 cardSource 是课程学员实际使用卡来源的唯一依据:EXPERIENCE_CARD 时在学员姓名后标注“体验卡”,MEMBER_CARD 不增加标签。体验卡课程订单不返回 cardHandle。不得根据卡名、cardHandle 是否存在或自然语言语义推断体验卡;members-search 和 member-cards 仍不读取体验卡订单。
支持的查询 action 以脚本 schema 为准,包括课程基础数据、课程计划、会员课程卡、课程订单和排课可行性预检。读取 references/api.md 查看接口字段和状态返回约定。
首次体验示例
首次使用且用户没有具体业务目标时,先申请只读的课程查询权限,以 Asia/Shanghai 当天 00:00 至次日 00:00 查询并分三组展示:
- 今天课程
- 待扣卡课程:只依据接口返回的
consumeActionable或actions.consume.allowed - 待反馈课程:只依据接口返回的结构化反馈 action
某一组没有数据时明确显示“暂无”。首次体验不执行写操作,也不申请写操作确认。展示后可提示用户继续用自然语言提出业务目标,例如:
- “排一节明天早上8点的课”
- “为某位学员扣卡”
- “提交一条课程反馈”
Agent 从自然语言提取时间和筛选条件,先申请最终意图所需的完整功能包,再使用规范字段查询缺失信息。业务信息不足时只追问真正缺失的内容,不要求用户提供 handle、内部 ID 或 OpenAPI 参数名。
写操作确认与恢复
十三个 Backend 同步写接口都使用显式模式:PREVIEW 只生成零副作用预览,禁止携带预览令牌;EXECUTE_DIRECT 直接提交,禁止携带预览令牌;EXECUTE_CONFIRMED 必须携带本次预览令牌提交。服务端不证明真人确认;服务端不接收 Skill 本地策略,只校验模式、令牌、授权、幂等和业务规则。
CONSUME_CARD、CHANGE_CARD_CONSUMPTION、MARK_SINGLE_BUY_ABSENT、CREATE_CARD_ORDER、TRANSFER_CARD、UPGRADE_CARD_ZERO_PRICE、SET_STORE_PRODUCT_STATUS、CREATE_CRM_FOLLOW_RECORD 是内置必须确认项。其余五项默认使用 EXECUTE_DIRECT。本地策略可以追加必须确认项,只能收紧策略,不能移除八个内置项:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action confirmation-policy-require --policy-operation delete-course单项扣卡命令会返回 WAITING_OPERATION_CONFIRMATION 和公开 pendingId 后退出,不会展示或记录 preview token:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action consume-card --payload-json '{"courseOrderHandle":"course_order_handle_001","cardHandle":"courseCard_handle_001","classHours":1}' --idempotency-key consume-1扣卡确认依次展示:学员、课程、课程时间、课程卡、核销状态(使用 verificationStatusLabel 中文标签)、课程卡状态(使用 cardStatusLabel 中文标签)、实际剩余课时(remainingClassHours)、本次预计扣除课时(classHours)、有效期(expireTime)和全部 warnings。warnings 不表示预览失败,不阻断预览,最终执行仍会重新校验并可能被业务规则拒绝。无论中文 label 是否存在,Agent 都不得将 PENDING、DEPLETED、DISABLED 等内部枚举展示给用户;中文 label 缺失时使用“状态暂不可用”等不暴露枚举的中文兜底。
存在 warnings 时,确认消息必须明确提供“继续执行”和“更换课程卡”。用户选择“继续执行”后,用当前 pendingId 执行 --decision confirm;用户选择“更换课程卡”时,先对当前 pendingId 执行 --decision reject,废弃当前操作确认 pending,再选择新 cardHandle,以新的业务意图和幂等 key 重新运行扣卡 action 并重新预览。不得保留旧 pending 或沿用旧预览确认。
Agent 只能在下一条明确无歧义的用户消息确认后执行 resume。预览过期或重新预览会生成新 token;新 token 必须再次确认,不能沿用旧消息的确认。
多个写操作通过一个文件组成顺序组。只要任一项必须确认,Skill 就先以 PREVIEW 预览全部操作,一次确认后按文件顺序以 EXECUTE_CONFIRMED 提交:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-run --operations-file .operations.json
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-resume --pending-id <pendingId> --decision confirm
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-resume --pending-id <pendingId> --decision reject
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-resume --pending-id <pendingId> --decision retry
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-resume --pending-id <pendingId> --decision reconcile
python external-skills/dw-business-assistant/scripts/query_course_data.py --action operation-group-resume --pending-id <pendingId> --decision abandon首个失败或未知结果出现后立即停止,成功前缀必须保留,不执行补偿回滚。已知失败只允许用原 payload、幂等 key 和授权上下文执行 retry;UNKNOWN 只能使用原请求执行 reconcile,持续未知时保持待协调状态并转人工复核,也可以由用户明确 abandon。不得把 UNKNOWN 当成新写请求重试。
十三个同步写动作
排课
Action:schedule-course
Scene:SKILL_COURSE_SCHEDULE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action schedule-course --payload-json '{"storeHandle":"store_handle_001","categoryHandle":"category_handle_001","courseType":"REGULAR","startTime":"2026-07-24T08:00:00+08:00","classHours":1}' --idempotency-key schedule-course-20260724-001普通排课必须显式传 courseType 为 REGULAR,不得省略。需要初始带学员的普通排课可传 memberSelections。
单次买排课必须显式传 courseType 为 SINGLE_BUY。首次请求静默调用结构化 feasibility,读取 singleBuyPricing.availablePrices、selectedPrice、selectionRequired 和 defaulted;不得根据时间、课程名称、价格配置或自然语言推断或猜测价格类型。唯一价格由 Skill 自动采用,不单独确认价格,直接进入正式 preview。两种价格时先由用户选择,选择价格不算执行确认,随后正式 preview 只确认一次;用户尚未选择黄金或非黄金价格时,先询问用户“这节单次买课程使用黄金时段价格还是非黄金时段价格?”,获得选择后将精确的 singleBuyPriceType 写入最终请求。
{"storeHandle":"store_handle_001","categoryHandle":"category_handle_001","courseType":"REGULAR","startTime":"2026-07-24T08:00:00+08:00","classHours":1}{"storeHandle":"store_handle_001","categoryHandle":"category_handle_001","courseType":"SINGLE_BUY","singleBuyPriceType":"GOLD","startTime":"2026-07-24T19:00:00+08:00","classHours":1}单次买排课不得携带 memberSelections;若用户同时指定了学员,先要求用户移除学员或改为普通排课,不得发起预览或执行。venueHandle、teacherHandle 可省略,省略时不自动选择默认场地或老师。categoryHandle 与 courseContentHandle 必须二选一且只能传一个。
排课确认必须从 preview 的 confirmationDetails 中读取 courseTypeLabel 展示中文课程类型;单次买排课还必须读取 singleBuyPriceTypeLabel 额外展示中文价格类型。
排课和改期的正式 preview 都从 confirmationDetails.feasibility 展示 feasible、conflicts、warnings 和 resolvedDurationMinutes。单次买的正式 preview 必须从 confirmationDetails.feasibility.singleBuyPricing.availablePrices 展示全部配置价格,并从 confirmationDetails.feasibility.singleBuyPricing.selectedPrice 展示最终采用价格。存在 BLOCKING 冲突时不签发 preview token;Agent 必须展示公开 reasonCode 和 message 后立即停止。遇到 BLOCKING 时不得创建或恢复操作确认 pending,也不得要求用户确认。WARNING 及非阻断冲突进入同一次操作确认摘要。显式调用 course-operation-feasibility 是只读诊断,不创建操作确认 pending。正式执行仍重新校验实时业务状态。
修改排课
Action:reschedule-course
Scene:SKILL_COURSE_RESCHEDULE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action reschedule-course --payload-json '{"coursePlanHandle":"course_plan_handle_001","startTime":"2026-07-13T10:00:00+08:00","venueHandle":"venue_handle_002"}' --idempotency-key reschedule-course-20260713-001除时间、场地、老师和课时外,memberChanges 也属于修改排课字段。添加使用 memberChanges.add,每项可仅传 cardHandle,或传 memberHandle 由服务端选卡;删除使用 memberChanges.remove,每项是 courseOrderHandle;未扣记录换卡使用 memberChanges.update,每项包含 courseOrderHandle 与 cardHandle。三组都是增量意图,不需要提交未变化的学员,不允许空元素。同一订单不得同时删除和换卡。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action reschedule-course --payload-json '{"coursePlanHandle":"course_plan_handle_001","memberChanges":{"add":[{"cardHandle":"courseCard_handle_002"}],"remove":["course_order_handle_001"]}}' --idempotency-key course-member-change-20260713-001
python external-skills/dw-business-assistant/scripts/query_course_data.py --action reschedule-course --payload-json '{"coursePlanHandle":"course_plan_handle_001","memberChanges":{"update":[{"courseOrderHandle":"course_order_handle_003","cardHandle":"courseCard_handle_003"}]}}' --idempotency-key course-card-change-20260713-001只修改时间、场地、老师或课时时,不携带 memberChanges;Skill 不会为纯排课属性修改执行学员预检或学员回验。
添加学员的稳定拒绝 reasonCode 包括 COURSE_MEMBER_ALREADY_EXISTS、MEMBER_NO_BOOKABLE_CARD、CARD_NOT_FOUND、CARD_MEMBER_MISMATCH、CARD_STORE_MISMATCH、CARD_UNAVAILABLE、CARD_CATEGORY_MISMATCH、CARD_EXPIRED 和 CARD_BALANCE_INSUFFICIENT。候选选卡阶段没有适用卡,或显式卡已不满足预约条件时,可返回 MEMBER_NO_BOOKABLE_CARD;执行时重新检查容量也可能返回 CARD_BALANCE_INSUFFICIENT。直接展示服务端安全 message,不要在本地改写错误码或静默换卡。
排课和改排课 preview 中,每个新增学员选择都会返回 expectedCardClassHours。同一卡的多个新增选择按复合卡标识累计;preview 只基于当时快照,不预留容量。execute 仍以事务锁内回验结果为准,失败时按本次实际返回的公开错误处理。CLI 必须原样保留服务端 message、reasonCode 和 requestId,不得用本地通用文案覆盖。
删除排课
Action:delete-course
Scene:SKILL_COURSE_DELETE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action delete-course --payload-json '{"coursePlanHandle":"course_plan_handle_001","deleteRepeat":false}' --idempotency-key delete-course-20260713-001扣卡
Action:consume-card
Scene:SKILL_CARD_CONSUME / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action consume-card --payload-json '{"courseOrderHandle":"course_order_handle_001","cardHandle":"courseCard_handle_001","classHours":1}' --idempotency-key consume-card-20260713-001修改扣卡
Action:change-card-consumption
Scene:SKILL_CARD_CONSUME_CHANGE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action change-card-consumption --payload-json '{"courseOrderHandle":"course_order_handle_001","cardHandle":"courseCard_handle_002","classHours":2}' --idempotency-key change-card-consumption-20260713-001标记单次买订单缺课
Action:mark-single-buy-absent
Scene:SKILL_CARD_CONSUME / WRITE
处理缺课结算时先使用 settle-absence。它查询 course-orders 后只依据 orderKind 与 actions.markAbsent 分流:CARD 普通订单进入既有 consume-card 完整预览和确认流程,且必须由用户显式提供卡与课时;SINGLE_BUY 且 actions.markAbsent.allowed=true 才使用本操作。本操作确认内容必须明确说明“标记缺课,不扣会员卡”;必须经用户确认后才执行。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action settle-absence --payload-json '{"courseOrderHandle":"course_order_handle_001"}' --card-handle card_handle_0001 --class-hours 1 --idempotency-key settle-card-absence-20260724-001
python external-skills/dw-business-assistant/scripts/query_course_data.py --action settle-absence --payload-json '{"courseOrderHandle":"course_order_handle_001"}' --idempotency-key settle-single-buy-absence-20260724-001python external-skills/dw-business-assistant/scripts/query_course_data.py --action mark-single-buy-absent --payload-json '{"courseOrderHandle":"course_order_handle_001"}' --idempotency-key single-buy-absent-20260724-001请求只能传 courseOrderHandle,不得携带 cardHandle、classHours 或其他扣卡参数。已登记的单次买订单拒绝直接展示服务端安全 message;未知结果只展示 requestId。
提交反馈
Action:submit-feedback
Scene:SKILL_COURSE_FEEDBACK_CREATE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action submit-feedback --payload-json '{"courseOrderHandle":"course_order_handle_001","content":"本节课程完成情况良好"}' --image-file '.attachments课堂正面.jpg' --image-file '.attachments课堂侧面.png' --idempotency-key submit-feedback-20260713-001--image-file 可重复,只传入用户本轮明确附加的图片;Skill 不扫描目录,也不自动发现或上传其他本地文件。提交反馈不接受 --image-mode。图片与 payload 中已有的合法 imageUrls 按首次出现顺序合并,最终最多 10 张。
修改反馈
Action:update-feedback
Scene:SKILL_COURSE_FEEDBACK_UPDATE / WRITE
python external-skills/dw-business-assistant/scripts/query_course_data.py --action update-feedback --payload-json '{"courseOrderHandle":"course_order_handle_001","content":"更新后的课程反馈"}' --image-file '.attachments补充画面.jpg' --image-mode replace --idempotency-key update-feedback-20260713-001修改反馈未指定图片模式且没有图片输入时,CLI 只提交文字字段,由服务端保留原图;有图片输入时默认使用 append,先查询课程订单现有图片再追加。有图片变更时,CLI 将 imageMode 与编排后的最终 imageUrls 一并提交。replace 使用本轮新 URL 替换原图,clear 主动清空且不能同时传 --image-file。append、replace 必须提交至少 1 个编排后的最终 imageUrls,clear 固定提交空数组。replace 的新附件全部上传失败且没有其他新 URL 时保留原图。最终图片最多 10 张,超出配额的附件不会发起上传。已有反馈时只读查询必须返回 actions.updateFeedback.allowed=true,Agent 应调用 update-feedback,不得将其误判为不可操作。
部分图片上传失败时,仍继续提交文字反馈和其他成功图片;公开结果只显示失败文件基本名,不显示本地完整路径。若图片已经上传但反馈请求失败,按“图片已上传、反馈未更新”处理,并用相同反馈幂等 key 重试,避免重新上传已成功图片。
新增会员卡订单
Action:create-card-order,Scene:SKILL_CARD_ORDER_CREATE / WRITE。
新增卡前只使用统一商品查询:query_course_data.py --action store-products。商品名称或用户输入的卡名只放入 nameKeyword,分页只传整数 page 和 size;时间卡使用结构化 productType=FORMAL_TIME_CARD,课次卡使用 FORMAL_COUNT_CARD。不得调用绑定 OfflinePageReq 的小程序探索页或旧商品分页接口,也不得把商品名称、用户原话或任意字符串传给 page、pageNum、size。查询返回候选后只使用公开 productHandle 创建订单。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action store-products --payload-json '{"nameKeyword":"少儿编程时间卡","productType":"FORMAL_TIME_CARD","saleStatus":"ON_SALE","page":1,"size":20}'python external-skills/dw-business-assistant/scripts/query_course_data.py --action create-card-order --payload-json '{"memberHandle":"member_handle_001","productHandle":"product_handle_001","orderKind":"FORMAL_CARD","confirmedAmount":1280}' --idempotency-key create-card-order-001必须展示会员、门店、商品、订单类型、标准价、确认金额、有效期和全部 warnings;金额或对象不明确时先查询和消歧,不得默认。scripts/card_sales.py --action create-order 会转交本动作并返回公开 pendingId。
新增卡返回 MEMBER_PROFILE_INCOMPLETE、CARD_ORDER_PRODUCT_INVALID、CARD_ORDER_KIND_MISMATCH、PRODUCT_OFF_SALE、CARD_ORDER_PRICE_CHANGED、MEMBER_MOBILE_CONFLICT、CARD_ORDER_PRODUCT_UNAVAILABLE、CARD_ORDER_PRICE_UNAVAILABLE、CARD_ORDER_TYPE_MISMATCH、CARD_ORDER_CLASS_HOURS_INVALID 或 CARD_ORDER_VALIDITY_INVALID 时,直接展示服务端安全 message 和 requestId。未知 BUSINESS_RULE_REJECTED 仍不得猜测或展示原始异常。
正式卡转卡
Action:transfer-card,Scene:SKILL_CARD_TRANSFER / WRITE。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action transfer-card --payload-json '{"cardOrderHandle":"card_order_handle_001","targetMemberHandle":"member_handle_002"}' --idempotency-key transfer-card-001必须展示原会员、目标会员、卡名、剩余权益、有效期和影响提示。执行后服务端回读卡订单并核验最终会员确为目标会员;同会员、非正式卡或不可转状态直接停止。
零差价升卡
Action:upgrade-card-zero-price,Scene:SKILL_CARD_UPGRADE_ZERO / WRITE。
源卡只允许选择正式卡。优先复用当前会话中同一会员、同一门店且此后没有写操作的升阶候选结果;没有可复用结果时,只调用一次 scripts/card_sales.py --action upgrade-source-candidates。该动作固定使用 orderKind=FORMAL_CARD、paymentStatus=PAID、cardStatus=ACTIVE 查询,不得先查体验卡或再次进行无过滤的课程卡查询。候选结果已包含确认所需业务信息时不再查询订单详情;只有同名消歧或字段缺失时才调用 order-detail。
目标商品通过统一运行时查询 store-products,优先带目标名称和 saleStatus=ON_SALE,只保留结构化 productType 为 FORMAL_COUNT_CARD 或 FORMAL_TIME_CARD 的候选。会员卡订单与商品查询均由统一运行时读取共享 Ticket 缓存,不得搜索 Ticket 文件或手工传递 Ticket。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action upgrade-card-zero-price --payload-json '{"cardOrderHandle":"card_order_handle_001","targetProductHandle":"product_handle_002"}' --idempotency-key upgrade-zero-001差价完全由服务端重算。预览 payload 提交 cardOrderHandle、targetProductHandle、orderAmount 和 priceDifferenceAmount;用户明确自定义升阶后有效期时额外传 validityDays(1 至 36500 天),未指定时省略该字段并使用目标卡默认有效期。不得根据源卡剩余有效期自行推导,也不得携带商品展示字段。确认摘要展示最终有效期、旧卡、目标卡、会员、门店、差价、权益和不可逆影响;非零差价停止并建议改走付费升卡。执行后回读并核验新卡已激活、属于原会员且旧卡已关闭。
门店商品上下架
Action:set-store-product-status,Scene:SKILL_STORE_PRODUCT_STATUS_CHANGE / WRITE。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action set-store-product-status --payload-json '{"productHandle":"product_handle_001","targetStatus":"OFF_SALE"}' --idempotency-key product-status-001必须展示商品、门店、当前状态、目标状态和 warnings,不得默认上下架方向。单次课不走本动作;重复目标状态按服务端 no-op 结果说明。scripts/store_management.py --action set-status 会转交本动作。
售卡和门店商品领域适配器的同步写入口不接受调用方传入 mode 或 preview token。首次调用由统一运行时创建私密 pending;只有用户下一条明确确认后,使用领域适配器的 operation-group-resume --pending-id <pendingId> --decision confirm,其他决定可用 reject、retry、reconcile 或 abandon。
新增 CRM AI 跟进
Action:create-crm-follow-record,Scene:SKILL_CRM_FOLLOW_UP / WRITE。
先用 scripts/crm_insights.py --action customers 查询并消歧,只能提交查询返回的 crmCustomerHandle,不得要求用户提供内部 memberId。本动作固定先 PREVIEW,展示 AI 总结、风险、跟进方向、下一步行动、话术和建议;用户下一条明确确认后才执行。
生成 content、AI 总结、关键信息、原因诊断、建议和话术时,只使用接口返回的中文 *Label 状态文案,不得复制 PENDING、DEPLETED、DISABLED、ACTIVE 等内部英文枚举,也不得以括号形式附在中文状态后。中文 label 缺失时省略该状态,不根据英文枚举自行翻译或展示;内部枚举只用于程序判断。提交 PREVIEW 前检查所有用户可见文本,发现内部英文状态必须移除。
customerType=RENEWAL 只用于选择续费对象,所有用户可见内容统一称“续费会员”,不得称“续费账本”“续费账本客户”或直接展示 RENEWAL。续费会员分析使用“续费风险”“续费阻碍”“续费建议”,不得套用“线索”“未成单客户”“弃单客户”等新客转化文案。customerType=CLUE 的用户文案使用“潜在学员”或“线索”。
python external-skills/dw-business-assistant/scripts/query_course_data.py --action create-crm-follow-record --payload-json '{"crmCustomerHandle":"crm_customer_handle_001","content":"家长认可课程效果,计划周五确认续费","nextFollowTime":"2026-08-28T10:00:00+08:00","intention":"HIGH"}' --idempotency-key crm-follow-001若填写下次跟进时间,CRM 跟进成功后 WorkBuddy 可根据自身能力自行创建待办;能创建就创建,不能创建就忽略。Backend 不查询企微绑定、不创建待办、不返回待办决策字段,待办失败不得回滚或改变 CRM 跟进结果。
较长请求可将同一 JSON 写入本地文件并把 --payload-json '<JSON>' 替换为 --payload-file .request.json。
授权与撤销
只建立或校验查询授权:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-start在前置查询之前建立或扩展写意图权限包:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action auth-start --auth-package COURSE_SCHEDULING撤销当前缓存 Ticket:
python external-skills/dw-business-assistant/scripts/query_course_data.py --action revoke-ticket撤销只处理已有 Ticket,不应为了撤销而新建授权会话。只有用户明确要求撤销授权时,Agent 才能调用 revoke-ticket。不得把 revoke-ticket 用于授权失败、权限不足、超时、重试或改走 NEW 的恢复流程。
已有有效 Ticket 而需要新增权限时使用 EXTEND。EXTEND 的创建、等待或候选 Ticket 校验失败时,保留旧 Active Ticket、其过期时间和已授权权限;只按失败类型保留或清理本次 pending 与临时二维码。需要再次授权时继续 EXTEND,不得先撤销旧 Ticket 再创建 NEW。
完整授权协议、同步接口、错误处理和人工 E2E 安排见 references/api.md。
单次买价格编排
单次买在创建 schedule-course preview 前,必须静默调用 course-operation-feasibility,请求含 operation=SCHEDULE 和 courseType=SINGLE_BUY。只使用返回的 singleBuyPricing,不根据上课时间、课程、课程卡、金额或自然语言推断价格;这次只读价格发现不创建操作确认 pending。
defaulted=true时,只能采用selectedPrice.priceType;向用户说明“系统仅配置了 {priceTypeLabel},价格为 {displayAmount},已自动采用”,直接用该priceType填入singleBuyPriceType并创建正式 preview,不单独等待价格确认。selectionRequired=true时,按availablePrices原顺序同时展示每项的priceTypeLabel与displayAmount,等待用户选择;选择价格不算执行确认,选择前不得创建 preview 或执行,选择后只确认一次正式 preview。availablePrices=[]时停止,展示SINGLE_BUY_PRICE_NOT_CONFIGURED;不构造排课 payload。- 自动采用唯一价或用户选择候选价后,
schedule-course的直接 payload 必须显式包含该精确的singleBuyPriceType。单次买始终先 preview,只有用户确认该 preview 后才执行。 - 正式 preview 从
confirmationDetails.feasibility.singleBuyPricing.availablePrices展示全部配置价格,从confirmationDetails.feasibility.singleBuyPricing.selectedPrice展示最终采用价格,并展示confirmationDetails.feasibility的冲突与提醒;成功结果从operationDetails.singleBuyPricing.selectedPrice展示priceTypeLabel和displayAmount。两种结果都同时展示courseTypeLabel与singleBuyPriceTypeLabel。
已登记的 SINGLE_BUY_PRICE_NOT_CONFIGURED 等拒绝直接展示服务端 message;未知结果仅说明无法确认,并展示 requestId 供排查。