用TypeScript走通AWS智能体部署流程
文章以书店智能体演示 AgentCore CLI 1.0 的完整流程:创建 TypeScript 项目、本地测试,再通过 CDK 部署到 AgentCore Runtime。文中提醒 0.x 项目需执行 agentcore migrate,部分在线文档仍使用旧命令。
AI 深度解读
Agent 能在电脑上回答问题,离交给用户使用还有一段路:代码跑在哪里、谁能调用、出了错去哪里查。AgentCore CLI 1.0 想接管的就是这段工程工作。作者用一个 TypeScript 图书推荐助手,把创建、本地调试、部署和排错串了起来。
这篇最有用的地方,是展示了 AWS 上一条比较完整的交付路径。但阅读时要分清验证范围:作者检查了命令、工具逻辑和迁移流程,本地模型调用却因缺少 AWS 访问而失败,不能把它当成完整的云端效果评测。
它替你接管的是部署,Agent 逻辑仍要自己写
按原文,AgentCore CLI 1.0 于 2026 年 10 月 28 日正式可用,npm 包 @aws/agentcore 从 2026 年 2 月开始提供预览版。作者逐条核对命令时使用的是 1.0.1。
理解它,只需要先区分四个组件。Runtime 托管代码,每个会话获得独立的 microVM;Harness 用模型、提示词和工具配置描述 Agent,由平台执行循环;Memory 保存跨会话的历史与事实;Gateway 把 API、Lambda 暴露为 MCP 工具。
作者选择 Runtime,因为他希望自己控制执行逻辑。Harness 配置更快,遇到限制后也可以用 agentcore export harness 转成代码。
CLI 底层使用 AWS CDK。agentcore/agentcore.json 描述项目资源,部署时转换为 CDK stack;账号和区域放在 agentcore/aws-targets.json。需要 DynamoDB 等资源,可以继续修改 agentcore/cdk/lib/cdk-stack.ts。
因此,它适合已经决定采用 AWS 的团队。它缩短了接入托管运行环境的路径,业务工具、权限边界和回答质量仍由开发者负责。
TypeScript 项目怎样从工具函数走到可调用服务
准备条件包括 Node.js 20.12 或更新版本,作者使用 Node 22,以及 npm、有效 AWS 凭据、AgentCore 和 CDK bootstrap 权限。凭据可用 aws sts get-caller-identity 检查。模板通过 global inference profile 使用 Claude Sonnet,需要相应 Bedrock 模型访问权限。TypeScript 模板使用 ZIP 包 CodeZip,无需 Docker。
安装命令是 npm install -g @aws/agentcore,再用 agentcore --version 检查版本。旧 Python 包 bedrock-agentcore-starter-toolkit 也占用 agentcore 命令;遇到未知参数,先用 which agentcore 排查。匿名遥测可通过 agentcore config telemetry.enabled false 关闭。
创建项目应明确指定 agentcore create --name buecherfuchs --template agent-typescript-strands,随后 cd buecherfuchs。不带参数的向导默认创建 Harness。另有 Vercel AI SDK 模板 agent-typescript-vercel。
Strands 模板默认添加 facts、preferences、summaries、episodes 四种 Memory 策略。作者先执行 agentcore remove memory --name agentMemory 和 rm -r app/agent/memory,减少成本与排查变量;需要时再用 agentcore add memory 恢复。
业务工具只有两个:search_books 搜索书目,check_stock 查询库存。它们通过 @strands-agents/sdk 的 tool() 注册,用 Zod 的 inputSchema 校验参数,callback 执行业务逻辑。模型根据名称和描述选择工具,所以描述会直接影响调用。
入口文件负责校验请求、按会话保存 Agent,并把模型文本流返回客户端:
// app/agent/main.ts
import { BedrockAgentCoreApp } from 'bedrock-agentcore/runtime';
import { Agent } from '@strands-agents/sdk';
import { z } from 'zod';
import { loadModel } from './model/load.js';
import { searchBooksTool, checkStockTool } from './tools/catalog.js';
const SYSTEM_PROMPT = `
You are the friendly book advisor of the bookstore "Bücherfuchs".
Use search_books and check_stock before you say anything about books, prices or stock.
Never invent books. Answer briefly and in English.
`;
const requestSchema = z.object({
prompt: z.string().min(1),
});
// 每个会话保留一个 Agent,让对话能够延续
const agents = new Map<string, Agent>();
async function agentFor(sessionId: string): Promise<Agent> {
let agent = agents.get(sessionId);
if (!agent) {
agent = new Agent({
model: await loadModel(),
systemPrompt: SYSTEM_PROMPT,
tools: [searchBooksTool, checkStockTool],
});
agents.set(sessionId, agent);
}
return agent;
}
const app = new BedrockAgentCoreApp({
invocationHandler: {
requestSchema,
async *process(payload, context) {
const agent = await agentFor(context?.sessionId ?? 'local');
for await (const event of agent.stream(payload.prompt)) {
if (
event.type === 'modelStreamUpdateEvent' &&
event.event?.type === 'modelContentBlockDeltaEvent' &&
event.event.delta?.type === 'textDelta'
) {
yield { data: event.event.delta.text };
}
}
},
},
});
app.run({ port: parseInt(process.env.PORT ?? '8080', 10) });
要看清 agentFor(context?.sessionId ?? 'local'):会话标识决定复用哪个 Agent。这里的 Map 只保存进程内状态,跨会话记忆需要 Memory。模型选择则在 app/agent/model/load.ts。
工具返回值必须兼容 JSON。作者遇到过 Book 使用 interface 报错、改用 type 通过的情况,这是 SDK 类型约束下的表现,不能推广为所有 TypeScript 接口都不能序列化。日期应转 ISO 字符串,类实例也应转为普通数据。
本地跑通以后,部署和迁移分别检查什么
作者先用 node --import tsx --test tools/catalog.test.ts 测试作者搜索、类型筛选和未知词三种情况,再执行 npx tsc --noEmit。这些检查不调用模型,也不消耗 token。
随后运行 agentcore dev,在 8080 端口启动热更新服务并采集 OpenTelemetry traces。agentcore dev --mode browser 还会打开 Agent Inspector;curl -s localhost:8080/ping 检查服务健康。
本地调用使用 agentcore invoke --runtime agent --local --payload '{"prompt":"Do you have any crime novels in stock?"}'。--runtime agent 不能省略,否则 CLI 要求明确选择资源。作者在缺少 AWS 访问的环境中收到 event: error,说明本地启动并不免除 Bedrock 凭据和网络要求。

部署依次运行 agentcore build、agentcore deploy、agentcore status。首次部署会根据当前账号和区域创建 default target,必要时执行 CDK bootstrap。作者的精简项目包含 IAM role、policy 和 Runtime 三项相关资源。
云端调用去掉 --local,可以增加 --session-id "customer-4711-$(date +%Y%m%d)-book-consultation" 延续会话;不传则新建会话。实际应用应由后端通过 SDK 调用,例如放在 API 后面的 Lambda。
排错用 agentcore logs runtime --name agent --since 30m --level error 和 agentcore traces runtime list --name agent --since 1h。前者读 CloudWatch 日志,后者帮助定位模型、工具调用及耗时。
旧项目另有一道迁移关。作者用 0.31.2 项目验证:agentcore.json 格式从 version 1 升到 version 2,要求 Git 工作区干净,默认只生成计划。
git status # 工作区必须干净
agentcore migrate # 只展示迁移计划
agentcore migrate --yes
git diff --stat
agentcore deploy
关键是先运行不带 --yes 的那一行。计划写入 agentcore/.cli/migrate/;迁移后用 "migratedFrom": "v1" 保留旧资源命名,但生成目录中的 Jest 配置和示例测试等文件会被删除,自定义修改要提前检查。
我的判断
这套流程最值得借鉴的是把业务测试、模型调用和部署排错分开验证。 普通工具函数先测确定性逻辑,再看模型是否选对工具,最后查运行环境,可以少走很多弯路。
局限也很明确。系统提示词要求先查工具、不编造书籍,只是行为要求,原文没有提供遵守率或错误率数据。作者也没有给出与手写 CDK、普通 Node 服务或其他平台的耗时、成本对照。「部署更省事」有流程支撑,「整体更划算」仍缺数据。
费用包括按秒计量的 Runtime CPU、内存,以及 Bedrock token、CloudWatch 和可选 Memory。按原文引用的定价说明,纯等待模型或工具时不计 CPU 时间,但不等于整个请求免费;作者关于模型费用通常占大头的判断也是经验之谈。
安全方面,独立 IAM role 和 CDK grant… 方法值得采用。密钥应放 AgentCore Identity,通过 agentcore add credentials 配置,或使用 Secrets Manager。会话隔离也不能替代业务鉴权,原文没有展开真实用户身份如何绑定会话。
能拿来做什么
- 做 Node 或 TypeScript Agent 时,先把查询、筛选等业务逻辑抽成普通函数,独立测试后再包装成工具;模型调用测试单独检查工具选择和回答是否有依据。
- 已采用 AWS 的团队,可以从
agent-typescript-strands或agent-typescript-vercel建立最小项目,先移除不需要的 Memory,在沙箱账号验证调用与 traces。 - 升级 0.x 项目时,先开分支、保持工作区干净,查看迁移计划和 Git diff。原文发现在线文档仍有旧命令
agentcore import,具体选项应以agentcore <command> --help为准。 - 实验结束后执行
agentcore remove all --yes,再执行agentcore deploy --yes删除对应 stack。删除本地目录不会清理 AWS 资源。