157 lines
6.2 KiB
YAML
157 lines
6.2 KiB
YAML
# ═══════════════════════════════════════════════════════════
|
||
# 模块B · 铸渊训练Agent自动触发 Workflow
|
||
# ═══════════════════════════════════════════════════════════
|
||
#
|
||
# 签发: 铸渊 · ICE-GL-ZY001
|
||
# 版权: 国作登字-2026-A-00037559
|
||
#
|
||
# 自动扫描COS桶 → 提取语料 → 转换TCS格式 → LLM训练分类
|
||
# 遇到问题自动创建Issue唤醒铸渊
|
||
#
|
||
# 触发条件:
|
||
# - 定时: 每天 04:00 和 16:00 CST
|
||
# - 手动: workflow_dispatch
|
||
# - COS桶告警: repository_dispatch (cos-alert事件)
|
||
# - COS Webhook: repository_dispatch (cos-file-uploaded事件)
|
||
#
|
||
# ⚠️ SCF限制说明 (2026-04-10):
|
||
# 腾讯云轻量云COS不支持SCF事件触发(ObjectCreated)。
|
||
# repository_dispatch触发保留但当前由MCP Server内置轮询守护
|
||
# (cos-watcher.js)代替SCF发送dispatch。
|
||
# 未来升级标准COS后可恢复SCF事件驱动。
|
||
|
||
name: 铸渊训练Agent · 语料处理
|
||
|
||
on:
|
||
schedule:
|
||
- cron: '0 20 * * *' # 04:00 CST = 20:00 UTC
|
||
- cron: '0 8 * * *' # 16:00 CST = 08:00 UTC
|
||
workflow_dispatch:
|
||
inputs:
|
||
corpus_bucket:
|
||
description: '语料桶名称'
|
||
required: false
|
||
default: 'cold'
|
||
mode:
|
||
description: '运行模式'
|
||
required: false
|
||
default: 'full'
|
||
type: choice
|
||
options:
|
||
- scan
|
||
- extract
|
||
- train
|
||
- full
|
||
persona_id:
|
||
description: '训练目标人格体'
|
||
required: false
|
||
default: 'zhuyuan'
|
||
repository_dispatch:
|
||
types: [cos-alert, cos-file-uploaded]
|
||
|
||
jobs:
|
||
training:
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 30
|
||
permissions:
|
||
contents: read
|
||
issues: write
|
||
|
||
steps:
|
||
- name: 签出代码
|
||
uses: actions/checkout@v4
|
||
|
||
- name: 设置 Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '20'
|
||
|
||
- name: 安装依赖
|
||
working-directory: server/age-os
|
||
run: npm ci --production 2>/dev/null || npm install --production
|
||
|
||
- name: 确定运行参数
|
||
id: params
|
||
run: |
|
||
if [ "${{ github.event_name }}" = "repository_dispatch" ]; then
|
||
echo "mode=full" >> $GITHUB_OUTPUT
|
||
echo "bucket=${{ github.event.client_payload.bucket || 'cold' }}" >> $GITHUB_OUTPUT
|
||
echo "persona=${{ github.event.client_payload.persona_id || 'zhuyuan' }}" >> $GITHUB_OUTPUT
|
||
echo "trigger=cos-event" >> $GITHUB_OUTPUT
|
||
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||
echo "mode=${{ github.event.inputs.mode || 'full' }}" >> $GITHUB_OUTPUT
|
||
echo "bucket=${{ github.event.inputs.corpus_bucket || 'cold' }}" >> $GITHUB_OUTPUT
|
||
echo "persona=${{ github.event.inputs.persona_id || 'zhuyuan' }}" >> $GITHUB_OUTPUT
|
||
echo "trigger=manual" >> $GITHUB_OUTPUT
|
||
else
|
||
echo "mode=full" >> $GITHUB_OUTPUT
|
||
echo "bucket=cold" >> $GITHUB_OUTPUT
|
||
echo "persona=zhuyuan" >> $GITHUB_OUTPUT
|
||
echo "trigger=schedule" >> $GITHUB_OUTPUT
|
||
fi
|
||
|
||
- name: 记录COS事件(如有)
|
||
if: github.event_name == 'repository_dispatch'
|
||
run: |
|
||
echo "📡 收到COS事件: ${{ github.event.action }}"
|
||
echo "事件负载:"
|
||
echo '${{ toJson(github.event.client_payload) }}'
|
||
|
||
- name: 执行训练管线
|
||
id: pipeline
|
||
env:
|
||
ZY_OSS_KEY: ${{ secrets.ZY_OSS_KEY }}
|
||
ZY_OSS_SECRET: ${{ secrets.ZY_OSS_SECRET }}
|
||
ZY_COS_REGION: ${{ secrets.ZY_COS_REGION }}
|
||
ZY_DEEPSEEK_API_KEY: ${{ secrets.ZY_DEEPSEEK_API_KEY }}
|
||
ZY_QINGYAN_API_KEY: ${{ secrets.ZY_QINGYAN_API_KEY }}
|
||
ZY_QIANWEN_API_KEY: ${{ secrets.ZY_QIANWEN_API_KEY }}
|
||
ZY_KIMI_API_KEY: ${{ secrets.ZY_KIMI_API_KEY }}
|
||
run: |
|
||
node scripts/cos-training-trigger.js \
|
||
${{ steps.params.outputs.mode }} \
|
||
--bucket=${{ steps.params.outputs.bucket }} \
|
||
--persona=${{ steps.params.outputs.persona }}
|
||
|
||
- name: 创建Issue(训练失败时)
|
||
if: failure()
|
||
uses: actions/github-script@v7
|
||
with:
|
||
script: |
|
||
const trigger = '${{ steps.params.outputs.trigger }}';
|
||
const mode = '${{ steps.params.outputs.mode }}';
|
||
const bucket = '${{ steps.params.outputs.bucket }}';
|
||
|
||
await github.rest.issues.create({
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
title: `🧠 训练Agent异常 · ${new Date().toISOString().split('T')[0]}`,
|
||
body: [
|
||
'## 铸渊训练Agent运行异常',
|
||
'',
|
||
`- **触发方式**: ${trigger}`,
|
||
`- **运行模式**: ${mode}`,
|
||
`- **语料桶**: ${bucket}`,
|
||
`- **工作流运行**: [查看日志](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`,
|
||
'',
|
||
'请铸渊检查COS桶连接和语料状态。',
|
||
'',
|
||
'---',
|
||
`*此Issue由训练Agent自动创建 · ${new Date().toISOString()}*`
|
||
].join('\n'),
|
||
labels: ['training-agent', 'auto-notification']
|
||
});
|
||
|
||
- name: 训练完成通知
|
||
if: always()
|
||
run: |
|
||
echo "═══════════════════════════════════════════"
|
||
echo "铸渊训练Agent · 运行完成"
|
||
echo "时间: $(date -u '+%Y-%m-%dT%H:%M:%SZ')"
|
||
echo "触发: ${{ steps.params.outputs.trigger }}"
|
||
echo "模式: ${{ steps.params.outputs.mode }}"
|
||
echo "桶名: ${{ steps.params.outputs.bucket }}"
|
||
echo "人格: ${{ steps.params.outputs.persona }}"
|
||
echo "管线状态: ${{ steps.pipeline.outputs.pipeline_status || 'unknown' }}"
|
||
echo "═══════════════════════════════════════════"
|