Chapter 16 · Deployment: CI and Hosted Platforms
Chapter goals: Learn to run agents in GitHub Actions / GitLab CI, use Daytona and Render as deployment targets, and consume deployed agent sessions with @flue/sdk.
16.1 Scenarios for Running Agents in CI
Agents in CI are not long-lived services — they "run one task and exit":
text
① PR opened → agent reviews code and comments
② Scheduled task → agent patrols issues and labels them
③ Release pipeline → agent generates changelog16.2 GitHub Actions
yaml
# .github/workflows/agent-triage.yml
name: agent-triage
on:
issues:
types: [opened] # Trigger on new issue
schedule:
- cron: "0 * * * *" # Patrol hourly
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:
# Keys from repo Settings → Secrets; never hardcode
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}yaml
# Static validation before actual execution (good habit to save tokens)
- name: dry-run validate agent definition
run: npx flue run agents/triage.ts --dry-run16.3 GitLab CI/CD
yaml
# .gitlab-ci.yml — equivalent GitLab pipeline
agent-triage:
image: node:22
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" # Schedule trigger
script:
- npm ci
# Keys from GitLab CI/CD Variables (masked)
- npx flue run agents/triage.ts "$ISSUE_TITLE"
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEYCI running注意点
- Each job is a新环境: Durability state must use an external database for retry to接力;
- Jobs have time limits: split长 tasks into segments or use
--outputto persist中间结果; - Logs are观测: enable verbose output in CI for easier debugging.
16.4 Hosted Platforms: Daytona and Render
| Platform | Role | Key Points |
|---|---|---|
| Daytona | Remote sandbox | Provides isolated container execution environment for the agent |
| Render | Node service hosting | Long-lived process + env var injection + Postgres add-on |
bash
# Render uses render.yaml to declare the service
# 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 # Enter in the console; not committed
# - key: DATABASE_URL
# fromDatabase: { name: flue-db, property: connectionString }
# databases:
# - name: flue-db # Attach Postgres for persistence16.5 @flue/sdk: Consuming Deployed Sessions
After deployment, the frontend or other services read agent sessions via the SDK:
typescript
import { FlueClient } from '@flue/sdk';
const client = new FlueClient({
baseUrl: 'https://your-flue-app.example.com',
});
// Send a message to a session
const result = await client.dispatch('triage', [
{ role: 'user', content: 'Triage issue #42' },
]);
console.log('Session ID:', result.id);
// Read session history
const session = await client.getSession(result.id);
console.log('Messages:', session.messages.length);16.6 Chapter Summary
- CI scenarios: PR review, scheduled patrol, release changelog — all "run once and exit";
- GitHub Actions / GitLab CI: inject keys via secrets/variables; use
--dry-runfor static validation; - Daytona: remote sandbox provider for isolated execution;
- Render: Node service hosting with Postgres add-on for persistence;
- @flue/sdk: consume deployed agent sessions from any client.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What type of workload is an agent in CI?
2. Why use --dry-run in CI?
3. What is the role of Daytona in the Flue ecosystem?
4. How does @flue/sdk differ from running flue run locally?
🛠️ Hands-On Exercises
- Create a GitHub Actions workflow that triggers on issue opened; run a triage agent and post a comment with the result.
- Add a scheduled cron job that patrols issues daily; verify the agent labels stale issues.
- Deploy a Flue agent to Render with a Postgres add-on; verify the session persists across restarts.
CI/CD mastered. Next, Capstone: Full-Stack Load Testing — wait, this is Flue! Next: 实战一:GitHub 自动分诊 Agent.