芯耘培训助手(Xinyun Training Helper)· v1.3.0
> Goal:帮教师完成「芯耘 / 智教耘」培训平台(training.aiec.wflaiedu.com)的学习任务——把每场直播/回放累计到平台要求的达标时长,并批量提交作业心得。
>
> v1.3.0 新增(重要):生成任何作业正文前,必须先确认用户的学段与任教科目,并禁止沿用/继承其他账号的身份。教训:曾误把英语老师的 11 份作业全写成高中物理视角,学科串味、一眼假。详见「阶段 2 · 步骤 0」。
>
> v1.3.0 关键修正(已真机验证):登录必须走真实浏览器 OAuth 握手才能拿到平台签发的 RS256 令牌(iss=aiec-live,aud=aiec-live-api)。此前设想的「纯 API 登录」经实测不可行——sysLogin 返回的 HS512 主站令牌会被 training-api 拒绝(10401),而 OAuth 的 state 由服务端会话绑定、换票用的第二段码只在浏览器握手后由前端生成,纯 requests 无法复现。因此本版登录用浏览器,业务用纯 API。
适用平台
- 培训 H5:
training.aiec.wflaiedu.com - 数据 API:
training-api.aiec.wflaiedu.com - SSO 登录:
aiec.wflaiedu.com/web-api/smc-c/(智教耘统一登录)+ OAuth 授权页aiec.wflaiedu.com/oauth-mine - 登录方式:智教耘 SSO「短信验证码登录」,通过真实浏览器完成 OAuth 握手。
- 典型培训:芯耘公益暑期教师数字素养提升培训、各类教师研修。
When to Use
用户说类似:"帮我完成芯耘暑期教师研修" / "把培训平台的课刷完" / "提交一下教师培训的作业" / 给出类似 https://training.aiec.wflaiedu.com/h5/classes/724 的班级链接并要求完成。
运行环境要求
- 业务阶段:只需 Python +
requests(云端沙箱自带即可)。 - 登录阶段(必需):需要一个浏览器运行时——Playwright + Chromium/Chrome。
- 云端沙箱若预装浏览器/Playwright → 全自动云端运行。
- 云端沙箱若无浏览器 → 登录步骤回退到本机 agent-browser(周老师 PC 常驻),或让用户在其浏览器登录后把
Authorization: Bearer <token>贴给技能(兜底,见阶段 0 第 6 步)。 - 用户需提供自己的手机号用于短信验证码(平台按账号计学习时长,必须用本人账号)。
- 人在回路的唯一一步:登录时由用户本人收发短信验证码(在微信里把 6 位码发回来即可),其余全自动。
能力边界与限制(请先读,避免误用)
- ✅ 能做的:登录本人账号 → 累计观看时长达标 → 批量提交文字作业。
- ⚠️ 只支持芯耘 / 智教耘平台(域名见上)。其他培训平台接口不同,不适用。
- ⚠️ 必须本人账号 + 本人短信验证码,时长与作业才计入本人培训;不能用他人账号代刷。
- ⚠️ 作业为文字心得提交:按每道题要求生成本人视角反思并提交,不代做客观题 / 不伪造成绩。
- ⚠️ 登录依赖浏览器 OAuth 握手:这是平台安全机制,无法用纯 API 绕过(已实测确认)。
- ⚠️ 不保证平台改版后仍然有效:平台升级接口时本技能需同步更新(见 README 维护说明)。
隐私与数据安全
- 本技能仅向上述官方域名发起 HTTPS 请求,目的仅为完成用户主动要求的本人培训任务。
- 登录令牌(
RS256JWT)默认仅用于本次会话,不写入任何第三方服务器。演示/调试时可落盘,正式分发建议不落盘。 - 不收集、不上传用户通讯录、文件等任何与培训无关的数据。
- 所有网络请求均在用户明确授权下进行。
核心流程
阶段 0:浏览器 OAuth 登录(拿 RS256 令牌)
> 已用 Playwright + 系统 Chrome 真机跑通。完整链路(自动化脚本见 xinyun_auto.py 的 browser_login):
- 打开入口:
https://training.aiec.wflaiedu.com/h5/classes/{classId}
→ 自动跳到https://aiec.wflaiedu.com/oauth-mine?client_id=a7c3e2f9b1d846053a29e7f4c6b1d802&redirect_uri=https%3A%2F%2Ftraining.aiec.wflaiedu.com%2Fapi%2F1%2Fauth%2Faiec-sso%2Fcallback&response_type=code&state=<随机> - 验证码登录:点「验证码登录」tab,填手机号,勾选协议,点「获取验证码」。
- 向用户要码:在微信里请用户查短信,把 6 位码发回来(5 分钟内有效)。
- 回填并登录:填验证码,点「登 录」。浏览器自动完成:
-POST /web-api/smc-c/sysLogin(手机号+码)→ 主站HS512令牌
-GET /web-api/smc/oauth/wfl_zh/getCode(带主站令牌)→ OAuthcode
- 重定向到redirect_uri(training-api 的/api/v1/auth/aiec-sso/callback)→ 内部换票
-POST /api/v1/auth/exchange-sso→ 平台签发的RS256令牌(iss=aiec-live) - 取令牌:令牌同时存在于
- 浏览器localStorage的token字段(及refreshToken),
- 以及后续training-api请求的Authorization: Bearer <RS256>头。
脚本从localStorage.token读取并保存。 - 兜底(无浏览器时):让用户在自己浏览器登录后,从 DevTools → Network 里任意
training-api请求的请求头复制Authorization: Bearer <token>贴给技能。该RS256令牌 access_token 有效期约 2 小时、refresh_token 约 7 天。
> 令牌用途:所有 training-api 请求头带 Authorization: Bearer <RS256令牌>、Content-Type: application/json。
阶段 1:学习时长达标(观看直播+回放)
GET /api/v1/student/classes/{classId}/detail
- 返回data.class_info(项目名、状态)与data.live_summary:total/watched总场数与已看场数;items[]每项含session_id、title、watched、viewing_completion_threshold(各场不同)、session_duration_seconds、watched_seconds等。- 对
watched == false的场次,调用心跳接口累计时长:
-POST /api/v1/live/sessions/{sessionId}/replay/heartbeat
- Body:{"duration": <秒>, "position": <秒>},单段 duration ≤ 300(实测超出被拒)。
- 多段累计:发若干段使累计观看接近阈值% × 课时时长即达标(回放时长为 0 的场次也能累计生效)。 - 回拉
detail核验:live_summary.watched应增加。
阶段 2:作业提交
步骤 0(强制前置,不可跳过):确认用户身份与任教学科
作业署的是用户真实身份,学科写错即事故(把英语老师的反思写成物理实验,一眼假)。
在生成任何作业正文之前,必须先确认学段 + 任教科目:
- 若用户未在请求里写明任教科目 → 停下来问一次("请问您任教的学段和科目?例如高中英语。
方便的话再给个城市,破冰帖要用"),拿到答复再继续。 - 严禁:靠猜、沿用同一会话里上一个账号的科目、从历史对话继承身份。
每个账号、每次任务都要单独确认。 - 拿到后先复述核对("确认:您教的是浙江杭州·高中英语,我将以英语教师视角撰写"),
用户点头后才动笔。 -
提交前输出核对清单:
作业标题 → 正文首 30 字摘要,让用户一眼看出学科是否对得上,确认后才 POST。 -
GET /api/v1/homework?class_id={classId}→items[](每份含id、题目等)。 - 对每份(按状态区分已交/未交):
- 先GET /api/v1/homework/{id}看minWords、题目description(如需)。
- 以已确认的本人学科视角写真实心得(字数 ≥minWords,建议 100~200 字中文),不要空话。
- 学科案例必须属于该学科,禁止跨科串味。参考场景:
英语→语篇分析/读写结合/AI 口语陪练/作文批改;语文→群文阅读/写作支架/整本书阅读;
数学→一题多解/变式训练/错因归类;物理→实验数据处理/情境化变式题;
化学/生物→实验方案设计/探究式学习;其他学科按典型场景类推。 - 提交(关键字段是下划线
content_html):
-POST /api/v1/homework/{id}/submissions
- Body:{"content_html": "<p>正文</p>", "attachments": [], "word_count": <字数>}
-attachments非强制,纯文字可提交成功。
阶段 3:核验 + 出凭证
- 再拉
detail确认live_summary.watched全场达标、homework全交。 - 向用户汇报:已学几场、已交几份、是否全绿。
- 说明:已提交但老师未批阅的作业,PC 端显示"已提交"、手机 H5 可能仍标"待交"——平台两界面对"完成"定义不同,不是没提交。
输入 / 输出示例
输入(用户给的信息)
帮我完成芯耘暑期教师研修
班级链接:https://training.aiec.wflaiedu.com/h5/classes/724
手机号:137xxxxxxxx
(稍后回填)验证码:123456
输出(向用户汇报的示例)
[xinyun] 浏览器已打开并发送短信验证码
[xinyun] 请查收短信并把 6 位验证码发回(5 分钟内有效)
[xinyun] 已拿到 RS256 令牌(前20字符:eyJhbGciOiJSUz…)
[xinyun] 直播共 12 场,已看 10 场
[xinyun] ✓ 达标: 开班典礼 …
[xinyun] → 标记: 特别活动(session 90)
[xinyun] → 标记: 结业典礼(session 84)
[xinyun] 学习达标:12/12
[xinyun] 作业共 11 份
[xinyun] 提交[41] 第一周反思 -> 200 {"code":200}
[xinyun] 本轮新提交:11 份
全部完成:学习 12/12 达标,作业 11/11 已交。
API 速查(均经真机验证)
| 用途 | 方法 | 完整路径 |
|---|---|---|
| 发短信验证码 | POST | https://aiec.wflaiedu.com/web-api/smc-c/sysLogin/verifyCodeSend |
| 短信登录(浏览器内部) | POST | https://aiec.wflaiedu.com/web-api/smc-c/sysLogin |
| OAuth 换码(浏览器内部) | GET | https://aiec.wflaiedu.com/web-api/smc/oauth/wfl_zh/getCode |
| 换发 RS256 令牌(浏览器内部) | POST | https://training-api.aiec.wflaiedu.com/api/v1/auth/exchange-sso |
| 班级+直播总览 | GET | https://training-api.aiec.wflaiedu.com/api/v1/student/classes/{classId}/detail |
| 观看心跳(达标) | POST | https://training-api.aiec.wflaiedu.com/api/v1/live/sessions/{sessionId}/replay/heartbeat |
| 作业列表 | GET | https://training-api.aiec.wflaiedu.com/api/v1/homework?class_id={classId} |
| 作业详情 | GET | https://training-api.aiec.wflaiedu.com/api/v1/homework/{id} |
| 提交作业 | POST | https://training-api.aiec.wflaiedu.com/api/v1/homework/{id}/submissions |
| 当前用户态 | GET | https://training-api.aiec.wflaiedu.com/api/v1/me |
所有 training-api 请求头带 Authorization: Bearer <RS256令牌>。
关键坑位(已踩过)
- 登录必须浏览器:
sysLogin的HS512主站令牌对training-api无效(10401);OAuthstate服务端绑定,纯 API 无法复现握手;换票用的第二段码只在浏览器握手后由前端生成。不要试图纯 API 登录。 - 心跳
duration必须 ≤ 300/段。 - 提交字段是
content_html(下划线),驼峰contentHtml会被当成空 → 报"字数不足"。 training-api数据接口带 Bearer 时不需要 CSRF;未登录的鉴权接口才有 CSRF 网关。- 必须本人账号 + 本人短信,时长才计入本人培训。
- 验证码 5 分钟内有效,发码到回填要快;过期需重新发。
RS256令牌 access_token 约 2 小时过期,长任务建议中途用 refresh_token 刷新或重登。
附:参考实现 xinyun_auto.py
本目录附带 xinyun_auto.py,是可执行参考实现:
- browser_login(phone, code):用 Playwright 走完整 OAuth 握手,返回 RS256 令牌(发码与登录可分步:先 browser_send_code 发码,拿到用户回传的码后再 browser_login_with_code)。
- complete_learning(token, class_id) / submit_homeworks(token, class_id) / verify(token, class_id):纯 API 业务,已按上方实测接口实现。
云端模式下 agent 可直接调用;若环境无 Playwright/Chrome,按阶段 0 第 6 步让用户粘贴 token 即可继续后续纯 API 业务。
如何发布 / 分享给同事(SkillHub,v1.3.0)
- 在线发布:将本技能发布到 SkillHub 技能市场(步骤见随附
PUBLISH.md)。同事在小程序里搜「芯耘培训助手」或点安装指令即可装上。 - 同事使用:
- 微信打开 WorkBuddy 小程序 → 切到「云端模式」(需云端沙箱具备浏览器运行时;否则用本机模式 + agent-browser)。
- 说:"帮我完成芯耘暑期教师研修",并给出班级链接(如.../h5/classes/724)。
- 按提示发自己的手机号 → 收短信 → 把 6 位验证码发回聊天框。
- 登录(浏览器握手)后其余全自动:达标 + 交作业。 - 训练/作业数据均计入本人账号;电脑可关机,云端继续跑(令牌有效期内)。
附录 A:登录阶段无浏览器时的兜底
若云端沙箱无浏览器、Playwright 也不可用,改用「用户粘贴令牌」方式:
1. 请用户在其常用浏览器打开 https://training.aiec.wflaiedu.com/h5/classes/724 并完成短信登录。
2. 登录后按 F12 → Network → 筛选任意 training-api.aiec.wflaiedu.com 请求 → 复制请求头 Authorization: Bearer eyJ... 整串。
3. 把该串贴给技能,技能直接用于后续纯 API 业务(阶段 1~3)。
4. 该 RS256 令牌 access_token 约 2 小时有效;如需长久运行,请用户重登并重新粘贴,或改用本机 agent-browser 自动登录。