Skip to content

第 16 章 · 部署:CI 与托管平台

本章目标:学会在 GitHub Actions / GitLab CI 中运行 agent,把 Daytona、Render 作为运行目标,并用 @flue/sdk 消费已部署 agent 的会话。

16.1 CI 中运行 Agent 的场景

CI 里的 agent 不是常驻服务,而是"跑一次任务就退出":

text
① PR 打开 → agent 审查代码并评论
② 定时任务 → agent 巡检 issue 并打标签
③ 发布流水线 → agent 生成变更说明

16.2 GitHub Actions

yaml
# .github/workflows/agent-triage.yml
name: agent-triage
on:
  issues:
    types: [opened]        # 新 issue 触发
  schedule:
    - cron: "0 * * * *"   # 每小时巡检一次

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      - run: npm ci
      - run: npx flue run agents/triage.ts "${{ github.event.issue.title }}"
        env:
          # 密钥来自仓库 Settings → Secrets,绝不硬编码
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
yaml
# 先做静态校验再真正执行(省 token 的好习惯)
      - name: dry-run 校验 agent 定义
        run: npx flue run agents/triage.ts --dry-run

16.3 GitLab CI/CD

yaml
# .gitlab-ci.yml — 等价的 GitLab 流水线
agent-triage:
  image: node:22
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"   # 定时触发
  script:
    - npm ci
    # 密钥来自 GitLab CI/CD Variables(masked)
    - npx flue run agents/triage.ts "$ISSUE_TITLE"
  variables:
    ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY

CI 运行的注意点

  • 每次 job 都是新环境:Durability 状态必须外接数据库,重试才能接力;
  • job 有时限:长任务拆成多段或用 --output 落盘中间结果;
  • 日志即观测:CI 里建议开启 verbose 输出便于排障。

16.4 托管平台:Daytona 与 Render

typescript
// Daytona:作为远程沙箱 provider 使用(见第 11 章)
// 这里展示在 Render 上托管 Node 版 Flue 服务
平台角色要点
Daytona远程沙箱给 agent 提供隔离容器执行环境
RenderNode 服务托管常驻进程 + 环境变量注入 + Postgres 附加项
bash
# Render 用 render.yaml 声明服务
# services:
#   - type: web
#     name: flue-bot
#     runtime: node
#     buildCommand: npm ci && npm run build
#     startCommand: node dist/main.js
#     envVars:
#       - key: ANTHROPIC_API_KEY
#         sync: false     # 在控制台填入,不入库
#       - key: DATABASE_URL
#         fromDatabase: { name: flue-db, property: connectionString }
# databases:
#   - name: flue-db       # 附带 Postgres 作持久化

16.5 @flue/sdk:消费已部署的会话

部署完成后,前端或其他服务用 SDK 读取 agent 会话:

bash
npm install @flue/sdk
typescript
// client.ts — 用 SDK 连接已部署的 agent
import { FlueClient } from '@flue/sdk';

const flue = new FlueClient({
  baseUrl: 'https://flue-agent.example.com', // 你的部署地址
  apiKey: process.env.FLUE_API_KEY!,
});

// 发起一次会话并等待结果
const session = await flue.sessions.create({
  agent: 'Triage',
  input: '分诊 issue #99',
});
console.log(session.id, session.status);

// 读取历史会话消息(构建聊天 UI 的数据源)
const messages = await flue.sessions.messages(session.id);
for (const m of messages) {
  console.log(m.role, ':', m.content.slice(0, 80));
}
typescript
// React 组件中消费(配合官方 Frontend React 指南)
import { useSession } from '@flue/sdk/react';

export function Chat({ sessionId }: { sessionId: string }) {
  // 订阅该会话的消息流,UI 自动更新
  const { messages, loading } = useSession(sessionId);
  if (loading) return <p>加载中…</p>;
  return (
    <ul>
      {messages.map((m) => (
        <li key={m.id}><b>{m.role}</b>: {m.content}</li>
      ))}
    </ul>
  );
}

16.6 本章小结

  • CI 场景 = 单次执行 + 外接持久化 + Secrets 注入;先 --dry-run 再真跑;
  • GitHub Actions 与 GitLab CI 配置同构,差异只在密钥变量语法;
  • Daytona 提供远程沙箱,Render 托管常驻 Node 服务并附带 Postgres;
  • @flue/sdk 是消费端:创建会话、读历史、React hooks 订阅消息流。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. 在 CI 中运行 Flue agent 前,为什么建议先执行 --dry-run?

2. GitHub Actions 中注入 ANTHROPIC_API_KEY 的正确方式是?

3. Daytona 与 Render 在 Flue 生态中的角色分别是?

4. @flue/sdk 的主要用途是?

🛠️ 动手实践

  1. 把分诊 agent 接入 GitHub Actions,在新 issue 上真实跑一次并在 PR/issue 里留下评论。
  2. 为 GitLab 写一条带 schedule 规则的流水线,验证 masked variable 的密钥注入。
  3. 用 @flue/sdk 写一个 CLI 小工具:列出最近 10 个会话及其状态。