新闻详情

新闻详情

首页 / 资讯中心 / 详情

12-Factor Agents 实战:用 Express 为 Agent 添加 HTTP API 端点

发布时间:2026/10/1 2:39:59来源:尧图网络
12-Factor Agents 实战:用 Express 为 Agent 添加 HTTP API 端点
文档教程人工智能大模型AI Agent【免费下载链接】12-factor-agentsWhat are the principles we can use to build LLM-powered software that is actually good enough to put in the hands of production customers?项目地址https://gitcode.com/GitHub_Trending/12/12-factor-agents点击查看免费下载导读本文基于 12-factor-agents 开源仓库中的 Workshop 章节 08-api-endpoints讲解如何为前一章基于 BAML 与 TypeScript 构建的工具循环 Agent添加一个 Express HTTP 服务将其从命令行交互升级为可通过POST /thread调用的生产可用 API。读完本文你将掌握如何用express.json()解析请求体、如何把用户消息构造成 Agent 的Thread事件并通过agentLoop驱动循环、如何用curl验证返回的 agentic trace以及如何通过PORT环境变量控制服务端口——这正是 12-Factor 方法论中进程可配置、服务可通过网络暴露的一次最小实践。前置背景我们正在把什么暴露成 API在进入本章代码之前先明确当前 Agent 的形态。上一章07-context-window之后核心的 Agent 循环位于 src/agent.tsThread类持有events: Event[]每个事件形如{ type, data }例如user_input、tool_call、tool_response、human_responseserializeForLLM()将事件序列化为 XML 风格文本作为 BAML 函数DetermineNextStep的输入上下文agentLoop(thread)是一个while (true)循环调用 BAML 生成的b.DetermineNextStep(thread.serializeForLLM())让模型决定下一步将决策以tool_call推入事件流若是add/subtract/multiply/divide则通过handleNextStep执行本地计算并把结果以tool_response写回线程直到模型输出done_for_now或request_more_information才返回。在此之前该 Agent 的入口是命令行 src/cli.ts从process.argv.slice(2)取参数、new Thread([{ type: user_input, data: message }])、调用agentLoop并用readline在request_more_information时向人类追问。本章的任务就是把这段命令行内循环迁移到 HTTP 服务里让任何客户端都能通过网络发起一次对话。第一步关闭 BAML 日志并安装依赖本章为了聚焦 HTTP 层会先关闭 BAML 的日志输出若想观察模型决策细节可自行开启export BAML_LOGoff安装 Express 及其类型定义同时安装 supertest后续章节做 HTTP 测试时会用到npm install express npm install --save-dev types/express supertest从 package.json 可以看到项目运行 TypeScript 的方式是tsxdev: tsx src/index.ts并依赖bamlBAML 客户端运行时。Express 与types/express会作为新依赖加入tsx可以直接执行带 ES 模块语法的server.ts而无需先编译。第二步编写服务器实现将现成的服务器实现复制到源码目录cp ./walkthrough/08-server.ts src/server.ts完整的实现如下与 walkthrough/08-server.ts 一致// ./walkthrough/08-server.ts import express from express; import { Thread, agentLoop } from ../src/agent; const app express(); app.use(express.json()); app.set(json spaces, 2); // POST /thread - Start new thread app.post(/thread, async (req, res) { const thread new Thread([{ type: user_input, data: req.body.message }]); const result await agentLoop(thread); res.json(result); }); // GET /thread/:id - Get thread status app.get(/thread/:id, (req, res) { // optional - add state res.status(404).json({ error: Not implemented yet }); }); const port process.env.PORT || 3000; app.listen(port, () { console.log(Server running on port ${port}); }); export { app };逐段拆解这段代码app.use(express.json())把请求体按 JSON 解析并挂到req.body这是POST /thread能读取message字段的前提app.set(json spaces, 2)让res.json(...)输出的响应带缩进便于人眼阅读 agentic tracePOST /thread接收{message: ...}构造一个仅含单个user_input事件的Thread交给agentLoop跑完整个工具循环再把完整的线程含每一步tool_call/tool_response作为 JSON 返回。对比 CLI 版本的 src/cli.ts这里把输入来自键盘、输出到终端替换为输入来自请求体、输出到响应体而 Agent 核心循环本身完全复用GET /thread/:id本章留作占位404 Not implemented下一章 09-state-management 会利用ThreadStore让该端点真正返回已存线程。这也体现了 12-Factor 的渐进式设计——先打通最小链路再补状态process.env.PORT || 3000端口来自环境变量符合 12-Factor 中配置存于环境的原则本地无配置时默认 3000export { app }把 Express 实例导出为后续引入 supertest 等测试框架或把 app 与 listen 分离做准备。第三步启动服务用tsx直接运行无需先tsc编译npx tsx src/server.ts启动成功后控制台输出Server running on port 3000关于运行环境需要注意Agent 的决策依赖 BAML 生成的客户端 baml_client该客户端默认以async模式生成见generators.baml的default_client_mode async并调用 clients.baml 中定义的CustomGPT4oprovider openai模型gpt-4o密钥来自env.OPENAI_API_KEY。因此运行前需要确保OPENAI_API_KEY已设置、BAML 代码已按 baml_src 生成到客户端目录。第四步用 curl 验证完整 Agent 调用链在另一个终端发起一次计算任务curl -X POST http://localhost:3000/thread \ -H Content-Type: application/json \ -d {message:can you add 3 and 4}请求会走如下链路Express 解析 JSON 得到messagenew Thread([{ type: user_input, data: can you add 3 and 4 }])构造初始事件agentLoop调用b.DetermineNextStep模型依据 agent.baml 中的提示词判断出intent: add、参数a: 3, b: 4src/agent.ts 的handleNextStep命中case add执行a b把tool_response推入事件循环再次调用模型得到done_for_nowagentLoop返回线程。响应中会包含完整的 agentic trace即事件序列并以done_for_now收尾{intent:done_for_now,message:The sum of 3 and 4 is 7.}注意该响应是最后一个事件的 data而实际res.json(result)返回的是整个Thread对象含events数组其中每一步的tool_call模型决策如add及其参数与tool_response本地计算结果7都会逐条列出这正是可观测的 agentic trace。局限与下一章的衔接本章的 API 是无状态的每次POST /thread都新建一个空线程多轮对话、澄清追问request_more_information都无法跨请求继续——GET /thread/:id的404占位也暗示了这一点。若要支撑生产场景的多轮对话 异步澄清需要为线程引入状态存储。仓库中紧随其后的 09-state-management 正好演示了如何用ThreadStore内存 Map crypto.randomUUID()生成线程 ID实现POST /thread返回thread_id与response_url、实现GET /thread/:id读取线程、实现POST /thread/:id/response追加human_response并继续agentLoop。读完本章后可以顺着这一节把无状态端点升级为可续跑的对话 API。小结本章用约 30 行代码完成了 Agent 从 CLI 到 HTTP API 的跃迁核心要点可归纳为复用而非重写Thread与agentLoop完全复用HTTP 层只负责把请求体变成user_input事件、把返回的线程变成 JSON 响应最小可用端点POST /thread是唯一真实实现GET /thread/:id预留接口体现了渐进式开发节奏配置外置端口通过PORT环境变量控制符合 12-Factor 配置管理原则可观测性响应携带完整 agentic trace方便调试模型决策与工具执行过程。至此你已经掌握了用 Express 暴露 Agent 能力的最小路径。下一章引入状态存储后这套端点将具备真正的多轮对话能力。赞分享文档教程人工智能大模型AI Agent【免费下载链接】12-factor-agentsWhat are the principles we can use to build LLM-powered software that is actually good enough to put in the hands of production customers?项目地址https://gitcode.com/GitHub_Trending/12/12-factor-agents点击查看免费下载相关推荐为 12-Factor Agent 添加计算器工具用 BAML 结构化输出驱动 Agent 的下一步决策为 12 Factor Agent 添加计算器工具用 BAML 结构化输出驱动 Agent 的下一步决策 本文以开源仓库 12 factor agents 工文档教程人工智能大模型AI Agent12-factor-agents 实战第 1 章用 BAML 搭建你的第一个 CLI Agent 循环12 factor agents 实战第 1 章用 BAML 搭建你的第一个 CLI Agent 循环 导读 本文对应仓库 12 factor agents文档教程人工智能大模型AI Agentx402-express 实战用 Express 中间件为 API 端点搭建加密货币付费墙x402 express 实战用 Express 中间件为 API 端点搭建加密货币付费墙 本文以 x402 项目仓库中的 Express 示例服务器 e2桌面应用文档上一篇Daft LeRobot 视频解码公开数据集验证逐行解码到按分片批量解码的 4-13 倍提速下一篇Happy Island Designer 岛屿设计工具从零到高手实战手册创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Godot回合制游戏轮次系统实战:状态机与信号驱动设计详解 2026/10/1 3:26:15

Godot回合制游戏轮次系统实战:状态机与信号驱动设计详解

最近在按项目式的节奏做一款回合制小游戏,正好推进到“游戏轮次”这一节。轮次这个东西,听起来不就是“你动一下、我动一下”吗?真正落到代码里才发现,它牵扯到状态控制、信号传递、UI锁定、AI延时、回合结算这一整条链路&#xf…

阅读更多 →
自建GitHub镜像站:用Gitea实现内网仓库同步与加速 2026/10/1 3:26:15

自建GitHub镜像站:用Gitea实现内网仓库同步与加速

上周开发同事又在群里喊:公共基础库的 clone 又超时了,快看看 GitHub 镜像站。这台镜像站是运维部自己搭的,8 核 16G 内存,跑着一台 Gitea,同步了三百多个常用开源仓库。半年多折腾下来,坑踩了不少&#xf…

阅读更多 →
Linux磁盘满排查实战:从syslog失控到logrotate根治 2026/10/1 3:26:15

Linux磁盘满排查实战:从syslog失控到logrotate根治

半夜被监控连环报警叫起来,看到根分区 100%,那一刻的心情相信每个运维都懂。上个月我就实打实踩了一次:SSH 登录卡得不行,写文件直接 No space left on device,连数据库都起不来,最后df一敲,系统…

阅读更多 →
Redis缓存面试高频考点:穿透、击穿、雪崩与分布式锁实战 2026/10/1 3:26:15

Redis缓存面试高频考点:穿透、击穿、雪崩与分布式锁实战

1. 破题:Redis缓存面试题到底在考什么先聊点实在的。我面试过不少人,简历上写着“熟悉Redis”,但一问“缓存穿透和缓存击穿有什么区别”,十个人里有六七个会卡壳。这不是背题的问题,而是很多人刷“Redis缓存面试题50道…

阅读更多 →
exFAT文件系统深度解析:从磁盘布局到Linux挂载与数据恢复 2026/10/1 3:26:15

exFAT文件系统深度解析:从磁盘布局到Linux挂载与数据恢复

SDXC 卡和 32GB 以上 U 盘,出厂几乎都被 exFAT 承包了。说起 exFAT,很多人脑子里的印象就是“能放 4GB 以上的单文件”,但真到了实际用的时候,Linux 上遇到modprobe: fatal: module exfat not found,或者想搞清楚为什么…

阅读更多 →
从Nginx+PHP-FPM到FrankenPHP:PHP常驻内存部署实践 2026/10/1 3:26:08

从Nginx+PHP-FPM到FrankenPHP:PHP常驻内存部署实践

做了十多年 PHP,我的部署栈很长时间都是 Nginx PHP-FPM。不是说这套组合不好,而是它把一件本该简单的事拆得特别碎:进程管理、Unix socket 权限、HTTPS 证书续期、cgi 参数、gzip,每个环节都要单独维护。更难受的是框架项目每次请…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉