在 SST 上部署智能体
使用 SST 将 Flue 智能体部署到 AWS,作为长期运行的 Fargate 容器服务。SST 是一个框架,可以轻松地将全栈应用部署到 AWS。
Flue 的 Node 目标是一个长期运行的 HTTP 服务器,而非函数。它在进程中持有智能体会话,并通过长连接提供流式响应。在 SST 上,这意味着将其作为长期运行的 Fargate 容器服务运行 — 不是 Lambda 函数,不是 serverless 调用。
先决条件
你需要:
设置
1. 初始化 SST 项目
从你的 Flue 项目根目录运行:
npx sst init
这将创建一个 sst.config.ts 配置文件。
2. 配置 SST
编辑 sst.config.ts 以使用 Fargate 容器:
import { StackContext, Cluster, Service } from "sst/constructs";
export function MyStack({ stack }: StackContext) {
// 创建 ECS 集群
const cluster = new Cluster(stack, "FlueCluster", {
vpc: {
nat: 1,
},
});
// 创建 Fargate 服务
const service = new Service(stack, "FlueService", {
cluster,
cpu: "0.25 vcpu",
memory: "0.5 GB",
containers: {
app: {
image: {
cmd: ["node", "dist/server.mjs"],
},
ports: [{ listen: "80/http" }],
environment: {
PORT: "8080",
},
},
},
});
// 输出服务 URL
stack.addOutputs({
ServiceEndpoint: service.url,
});
}3. 创建 Dockerfile
在项目根目录创建一个 Dockerfile:
# syntax=docker/dockerfile:1
FROM node:22-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npx vite build
FROM node:22-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
USER node
ENV PORT=8080
EXPOSE 8080
CMD ["node", "dist/server.mjs"]4. 设置密钥
SST 使用 AWS Secrets Manager 来管理密钥。设置你的模型 provider key:
npx sst secrets set ANTHROPIC_API_KEY sk-...
在 sst.config.ts 中使用密钥:
import { StackContext, Cluster, Service, Config } from "sst/constructs";
export function MyStack({ stack }: StackContext) {
// 创建密钥
const ANTHROPIC_API_KEY = new Config.Secret(stack, "ANTHROPIC_API_KEY");
// 创建 ECS 集群
const cluster = new Cluster(stack, "FlueCluster", {
vpc: {
nat: 1,
},
});
// 创建 Fargate 服务
const service = new Service(stack, "FlueService", {
cluster,
cpu: "0.25 vcpu",
memory: "0.5 GB",
containers: {
app: {
image: {
cmd: ["node", "dist/server.mjs"],
},
ports: [{ listen: "80/http" }],
environment: {
PORT: "8080",
},
bind: [ANTHROPIC_API_KEY],
},
},
});
// 输出服务 URL
stack.addOutputs({
ServiceEndpoint: service.url,
});
}5. 设置持久化
没有数据库适配器,Flue 将对话保存在内存中 — 重启时会丢失。添加一个 Postgres 支持的适配器:
import { postgres } from '@flue/postgres';
import { Pool } from 'pg';
// 使用 DATABASE_URL 连接字符串创建连接池
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export default postgres({
query: async (text, params) => (await pool.query(text, params)).rows,
transaction: async (fn) => {
const client = await pool.connect();
try {
await client.query('BEGIN');
const result = await fn(client);
await client.query('COMMIT');
return result;
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
},
close: () => pool.end(),
});在 sst.config.ts 中添加 RDS 数据库:
import { StackContext, Cluster, Service, Config, Rds } from "sst/constructs";
export function MyStack({ stack }: StackContext) {
// 创建密钥
const ANTHROPIC_API_KEY = new Config.Secret(stack, "ANTHROPIC_API_KEY");
// 创建 RDS 数据库
const database = new Rds(stack, "FlueDatabase", {
engine: "postgresql",
defaultDatabaseName: "flue",
});
// 创建 ECS 集群
const cluster = new Cluster(stack, "FlueCluster", {
vpc: {
nat: 1,
},
});
// 创建 Fargate 服务
const service = new Service(stack, "FlueService", {
cluster,
cpu: "0.25 vcpu",
memory: "0.5 GB",
containers: {
app: {
image: {
cmd: ["node", "dist/server.mjs"],
},
ports: [{ listen: "80/http" }],
environment: {
PORT: "8080",
},
bind: [ANTHROPIC_API_KEY, database],
},
},
});
// 输出服务 URL 和数据库连接信息
stack.addOutputs({
ServiceEndpoint: service.url,
DatabaseEndpoint: database.clusterEndpoint.hostname,
DatabaseSecret: database.secretArn,
});
}6. 部署
npx sst deploy
这将构建你的 Docker 镜像并将其部署到 AWS Fargate。部署完成后,你的智能体将在输出的 URL 可用。
自定义域名
1. 使用 Route 53
在 sst.config.ts 中添加自定义域名:
import { StackContext, Cluster, Service, Config, Rds } from "sst/constructs";
export function MyStack({ stack }: StackContext) {
// ... 其他配置 ...
// 创建 Fargate 服务(带自定义域名)
const service = new Service(stack, "FlueService", {
cluster,
cpu: "0.25 vcpu",
memory: "0.5 GB",
customDomain: {
domainName: "agents.yourdomain.com",
hostedZone: "yourdomain.com",
},
containers: {
app: {
// ... 容器配置 ...
},
},
});
// ... 输出配置 ...
}2. 配置 DNS
SST 会自动在 Route 53 中创建 DNS 记录。如果你使用其他 DNS 提供商,添加 CNAME 记录:
agents.yourdomain.com CNAME <service-url>
扩展
垂直扩展
在 sst.config.ts 中调整 CPU 和内存:
const service = new Service(stack, "FlueService", {
cluster,
cpu: "0.5 vcpu", // 增加 CPU
memory: "1 GB", // 增加内存
// ... 其他配置 ...
});
水平扩展
在 sst.config.ts 中调整实例数量:
const service = new Service(stack, "FlueService", {
cluster,
scaling: {
min: 1,
max: 4,
},
// ... 其他配置 ...
});
健康检查
Flue 不会自动生成健康检查端点。在你的 app.ts 中添加一个:
import { createAgentRouter } from '@flue/runtime/routing';
import { Hono } from 'hono';
import { MyAgent } from './agents/my-agent.ts';
const app = new Hono();
app.get('/health', (c) => c.text('ok'));
app.route('/agents/my-agent', createAgentRouter(MyAgent));
export default app;在 sst.config.ts 中配置健康检查:
const service = new Service(stack, "FlueService", {
cluster,
// ... 其他配置 ...
containers: {
app: {
// ... 容器配置 ...
health: {
command: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
interval: "10 seconds",
retries: 3,
startPeriod: "30 seconds",
},
},
},
});
日志和监控
CloudWatch 日志
SST 自动将日志发送到 CloudWatch:
- 转到 AWS Console → CloudWatch → Log Groups
- 查找
/sst/FlueService日志组 - 查看实时日志或筛选历史日志
CloudWatch 监控
SST 自动设置基本的 CloudWatch 监控:
- CPU 使用率
- 内存使用率
- 请求量
- 响应时间
参考资料
- SST 文档 — 官方 SST 文档。
- SST Fargate 服务 — Fargate 服务指南。
- AWS Fargate — AWS Fargate 文档。
- Docker 部署 — 底层 Docker 镜像的详细信息。