前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
AI 热点
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
AI 热点
开发者导航
返回 AI 情报前线
All News · 全部资讯6731
  • 多Agent系统生产级编排:事件总线、隔离内存与工具边界设计
  • 统一网关接入多模型:结构化输出正确性实战测试
  • Skill还是Subagent?Agent架构关键抉择
  • Aider 因格式猜测错误静默丢弃正确代码变更
  • Agent 记忆层的设计陷阱:所有记忆拥有同等权威性
  • 依赖包被污染后 60 分钟应急响应手册
  • 为 AI Agent SDK 构建定价真相门
  • 生产级 RAG 核心:动态检索路由而非一次性召回
  • 生产环境 LLM 成本优化:十大关键检查点
  • Grok存在加密上下文注入漏洞,可导致用户数据泄露
  • SpriteShip MCP:将 2D 游戏美术资源引入 AI 编程工作流
  • 构建千页书籍 RAG 踩坑:嵌入模型选型与长文本摘要失败教训
  • 开发者必读:系统最小权限实施指南
  • OpenAI披露电脑操控智能体最新进展:Codex已形成代码编写测试闭环
  • AI模型评估的陷阱:评分标准本身不可靠
  • Docker 硬化镜像多阶段实践与 GitHub Actions 流水线集成
  • 图灵奖得主 Sutton:合成数据是大错特错
  • Slack 推出协作 vibe-coding 频道,Claude/Devin 可直接建代码频道
  • AI没有贬值初级工程师,反而提升了其价值
  • 250 美元复刻 Kimi K3 小模型,击败 GPT-2
  • 从零构建生产级 AI Agent:LangGraph 实战模板解析
  • OmnisRouter:给每次LLM调用附带消费收据
  • AI生成代码的审查方法清单
  • Explyt MCP:让AI coding agent读懂JetBrains
  • 让AI coding agent自己完成网站部署
  • 用用户抱怨作为 Agent 自进化数据源:反馈→PR 闭环实战
  • CoSnitch 攻击提醒:你的 Chatbot 会被诱导泄露架构信息
  • Supabase发布官方MCP Server
  • AI 生成数据库迁移的五大风险与安全流程
  • Automox MCP Server:Claude Code 可直接管理万台终端
  • Amazon Bedrock AgentCore实现多Agent共享客户记忆
  • 嵌入式工程师实战:三大 AI 编程助手深度横评
  • Anthropic内部模型"Model 2"超越所有公版Claude
  • 渐进式自主权:让AI Agent安全落地的设计模式
  • AI Agent 调用 API 的七种失败模式
  • Next.js 缓存机制可能把用户 A 的数据泄露给用户 B
  • 五年做游戏后用C手写引擎的完整复盘
  • Kimi K3用Harness逼近Opus 5:18个Agent自主科研
  • Qwen-UI-Agent:能真正操作GUI的AI Agent基座
  • 构建结构化排错Agent:从堆栈到诊断与修复建议
  • Binance开放AI Agent自主交易
  • 数据库只读设计: 让AI安全查询生产环境
  • Mojo编译器正式开源,GitHub原生Stacked PRs上线
  • 选LLM别光比token单价——按任务成本评估才准确
  • 我为AI助手写了MCP记忆服务器,六周后效率大幅提升
  • AI沙箱失效:OpenAI Agent越狱在Hugging Face潜伏4.5天
  • 使用DPO+TRL+LoRA审计HH-RLHF偏好偏见
  • 陶哲轩:AI或将引发数学界自 Gödel 以来最大危机
  • 用状态机范式重塑网页爬虫开发
  • 生产级RAG系统:上下文压缩与提示构建
  • 本地LLM推理框架:基于VRAM自动选择最优模型
  • 已加载 51 / 6731
8.0
热点
AI SCORE
技术实践2026-08-20 19:20

从零构建生产级 AI Agent:LangGraph 实战模板解析

dev.to · AI#AI Agent#LangGraph#工程实践
Editor brief · 编辑速览

深入解析基于 LangGraph 的生产级 AI Agent 架构:Bedrock 知识库按需检索、MCP 工具源、人类审核持久化、代码沙盒执行及 Prompt 缓存等关键设计。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

每个 AI agent demo 都是调用一个工具然后打印结果。没有一个真正展示 agent 实际上在推理什么、工具调用需要人工确认时会发生什么、需要真正计算而不是猜测时会发生什么,以及在每一轮都描述几十个工具的 token 账单如何在不知不觉中蚕食你的利润空间。ai-agent-template 是一个 LangGraph agent,专门为解决这些问题而构建:按需调用的 Bedrock Knowledge Base 检索,而不是每轮都自动注入,让它有真实的内容来支撑答案——这可以说是整个系统的真正大脑——工具完全从 MCP 获取而非手工逐个注册、带有人工审批的人机协作机制且在决策过程中服务器重启也能恢复、用于处理工具调用无法完成的数学和图表的真正代码沙箱、永不让聊天因失败而崩溃的输入护栏、以及真正控制 token 成本的 prompt 缓存而不是仅仅宣称有。默认运行在 OpenAI 上——clone 一下、填入 API key,无需 AWS 账号——一旦你真正需要生产级的能力(真正的护栏、持久化记忆、CloudWatch 可观测性),Bedrock 是推荐路径。

接下来会介绍:让上述每一点成为现实的中间件链、一个看似浪费但仔细算过数字后才发现合理的缓存策略、三个已修复的线上 bug,以及一次真实的 Bedrock 线上运行是什么样的。

Architecture at a glance

Architecture at a glance

核心思路:中间件,而非手撸 graph

与其将每个关注点——记忆、prompt 缓存、护栏、上下文限制——直接写入 graph 节点逻辑,不如把每一个都做成独立的中间件,按顺序组合,可独立测试。大致按执行顺序:生命周期(调用前读取记忆、调用后写入轮次摘要)、动态上下文注入(每轮追加记忆和文档,从不写回消息历史)、prompt 缓存设置、上下文溢出安全网(在调用返回过大时裁剪并重试一次)、输入护栏(每轮运行一次而非每次模型调用都运行)、以及与风险分类器配对的 HITL 策略,决定哪些工具调用需要人工介入。

工具在每次模型调用时重新绑定,而非硬编码到静态 graph 中;系统 prompt 本身在启动时从配套的 MCP 服务器获取而非硬编码——agent 不定义自己的工具,而是从外部获取。

Execution Flow

What you get out of the box

HITL with stateless resume. 审批、拒绝、回复或编辑一个提议的工具调用。中断发生在 graph 执行时,而非中间件内部——轮次结束,等决策回来后,一个独立的新轮次从检查点恢复继续。正是这一点使得审批能够跨服务器重启存活,而不依赖连接保持打开。

Tools sourced entirely from MCP. 没有手工注册的工具列表——它通过 HTTP 连接到配套的 MCP 服务器,在启动时列出工具一次,并自动转换为 LangChain 工具。

Knowledge-base retrieval via Bedrock KB. kb_retrieve 是一个真实的工具,与从 MCP 获取的工具一起绑定,由 Bedrock Knowledge Base 的只读 Retrieve API 支持——模型在决定需要外部知识时按需调用,而不是每轮都自动注入上下文,不管需不需要。结果按来源去重并附带引用。如果没有配置 KB ID,工具就不会注册——agent 正常运行其他工具。这一点让 agent 能够基于你自己的文档来支撑答案,而不是靠猜测——可以说比任何一个单独的工具承担了更多真正的推理工作。无论哪个模型提供商活跃,Bedrock 独有。

Guardrails. 在轮次完成前运行真正的 ApplyGuardrail 检查——真正的内容/主题过滤,不是关键词列表——设计上为 fail-open,所以护栏故障会优雅降级而不是让聊天崩溃。

Long-term memory across conversations. AgentCore 支持的会话记忆,持久化跨轮次和跨会话的事实,而不是仅限单会话内;如果后端存储不可达,自动回退到内存状态。

Observability. 带有轮次关联 ID 的结构化日志,加上标准化 token 和缓存计费,接入 CloudWatch traces 和 metrics——不是靠你去找的 print 语句。

Prompt caching that's actually measured. 每次调用都做标准化 token 和缓存计费,因为没人看得见的缓存指标比没有指标更糟糕。

A real code sandbox for math and charts (run_python). 一个远程 AgentCore 沙箱,当答案需要真正计算时——统计、聚合、Plotly 图表——agent 把任务交给它,而不是靠工具调用。服务器拥有完整的生命周期(启动、执行、注册生成的文件、停止)在一个自包含的调用中;模型永远不会看到沙箱 id。它完全无法访问这个 agent 自己的工具——这是故意的,见下。

An orchestration tool for dependent tool calls (run_orchestration). 一个单独的、本地的、亚秒级的沙箱,专门处理单一工具调用无法处理的场景:相互依赖的调用——链、分支、重塑、循环——不需要每步都浪费一次往返。只读;更多解释见下。

A WebSocket API, plus a health endpoint.

HITL 和 MCP 工具获取之后的所有功能默认关闭——每一个都只需一个环境变量即可开启,在全部未设置的情况下 agent 也能干净地完成一个完整轮次。

Binding every tool, every turn — on purpose

一个显而易见的优化是只检索与用户当前问题相关的工具并绑定它们。一旦 prompt 缓存介入,这就是错误的做法:缓存的前缀写入昂贵但读取便宜,而这个溢价只有在前后轮次前缀保持稳定时才能回本。每轮收窄工具集意味着每次都改变前缀,击碎了你本来想用的缓存。所以这个模板故意反其道而行——无差别地、强制地、每轮绑定所有工具。block 大了一些,但逐字逐句相同,所以能待在缓存里:一次付清写入溢价,之后读取便宜。

Three bugs I hit building this — already fixed here

A telemetry counter that read zero forever. 接到了一个被重构掉的代码路径,所以它一直报告零而不是报错——修复:在测试中针对当前路径断言计数器存在,而不只是断言它存在。

HITL state that didn't survive a restart. 在运行进程中持有状态的审批循环,如果审批过程中进程重启就会丢失一切——修复:在 graph 执行时中断,结束轮次,从检查点作为新轮次恢复。

A safety rule living only in the prompt. "只自动审批只读工具"作为系统 prompt 指令,意味着你要求一个概率模型每轮都遵守这条规则——修复:一种命名约定(get_* 是只读,其他需要审批)由风险分类器在代码中强制执行,而不是在文本中请求。

What I actually verified

结构层面:每个中间件和网关都用了假模型独立测试,集成测试针对模拟 MCP 服务器和假 Bedrock 客户端运行完整轮次——日常开发不需要真实的模型调用。两个沙箱同样处理:run_orchestration 的测试确认工作线程/主循环的交接确实发生(不只是被调用了),确认变更被拒绝并返回审批消息而不是静默跳过,确认调用预算能切断失控循环;run_python 的测试针对假的 CodeExecutionService 运行,确认沙箱在每个失败分支都停止,而不只是正常路径——没有任何一个接触真实的 AWS 或 MCP。端到端、真实的:一次针对真实 Bedrock 的线上运行干净地完成了完整轮次——护栏检查应用了,响应逐 token 流回,轮次完成无需人工干预。

如果你想自己试试,有一个前置条件值得提一下:在默认的 OpenAI 提供商上,你只需要一个 API key——不需要 AWS 账号。切换到 Bedrock 就需要真实的 AWS 凭证才能访问,一旦配置了 AgentCore 记忆更是如此——模型调用本身没有离线或 mock 路径。本地 AWS_PROFILE、BEDROCK_API_KEY bearer token,或显式的 AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN 都可以;一旦选中 Bedrock,agent 缺少任何一个都无法启动。

Why this shape, specifically

OpenAI by default, Bedrock for production. OpenAI 是默认提供商,API key 零配置,create_model() 是简单的 if/else 分派而非提供商接口——与这个模板在其他地方所做的防过度工程化选择一致。Bedrock 是生产环境的推荐提供商,因为有六样东西在 OpenAI 根本没有等价物:真正的 ApplyGuardrail 调用而非关键词过滤、Bedrock Knowledge Base 检索、AgentCore 的持久化可恢复记忆、真正的代码解释器沙箱、cachePoint 调优的 prompt 缓存、跨区域模型访问、以及基于 IAM 的凭证而非 env 文件中的 API key。工程努力花在了让这每一项在你不在 Bedrock 上时都能优雅降级而非报错:护栏回退到基于 LangChain 自身检测函数构建的真正 PII 脱敏检查(匿名化并继续,而非阻断,符合框架自身有文档的指导),记忆即使 AgentCore memory ID 仍在配置中也会自动回退到内存状态,知识库检索如果未配置就根本不注册为工具。87 个测试专门覆盖这些降级路径,而不只是 Bedrock 的正常路径,套件中对任何一个提供商都没有真实调用。

Two sandboxes, kept deliberately separate. run_python 和 run_orchestration 从外部看起来相似——都允许模型写代码而不是在纯文本中推理——但它们存在的原因正好相反,且没有一个能完成另一个的工作。run_python 是一个远程 AgentCore 沙箱,有 pandas/numpy/plotly 且完全无法访问这个 agent 自己的工具,用于数学和图表。run_orchestration 是一个本地、进程内的沙箱,根本没有数学库,它的全部目的是在依赖链中调用已绑定的工具而无需每步一次往返。它们合并成一个"代码工具"意味着要么给数学沙箱访问它根本不该做的实时工具调用,要么在一个不需要它的工具调用循环上硬塞 pandas——分开之后,每个都足够小,可以推理清楚。

Read-only inside the tool-calling sandbox, on purpose. run_orchestration 的明显版本允许脚本调用任何已绑定的工具,包括变更——很有用,因为链/重塑/循环模式通常以写入结尾。但这同时也是真正的人机协作绕过:从沙箱内脚本发出的调用永远不会经过普通工具调用的审批路径,所以埋在循环里的变更会直接执行而无人审查,尽管相同调用直接由模型发出时会先停等人审批。这里的修复是一条硬规则,而非 prompt 指令:沙箱的工具桥接层检查与 agent 其他部分使用的相同风险分类器,只有只读(get_*)工具可以从内部访问。需要变更的计划必须先用 run_orchestration 收集所需内容,然后直接调用变更,此时人类才能真正看到它。不如无限制版本能力强——但这是保持这个模板在其他地方已做出的人工审批保证完整所必须付出的诚实权衡。

Middleware over graph nodes. 缓存和护栏这类关注点在作为独立中间件时更容易添加、移除或重排序,而不是把逻辑穿在 graph 本身里。

Ephemeral context, never persisted to history. 记忆和文档在调用时渲染进 prompt,从不写回消息列表——保持缓存前缀稳定,也防止消息历史因仅与单轮相关的数据而膨胀。

Resilient fallback over hard failure. 如果 AgentCore 记忆或持久化不可达,agent 降级到内存状态并记录一次警告,而不是让聊天崩溃。

最后三件事之一:聊天 UI,通过 WebSocket 与这个 agent 通信——一个 React 19 应用,渲染流式 token、工具调用和 HITL 审批提示。

模板是 MIT 许可且公开的:ai-agent-template。它获取工具的配套 MCP 服务器是 mcp-server-template。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
250 美元复刻 Kimi K3 小模型,击败 GPT-2
下一篇
OmnisRouter:给每次LLM调用附带消费收据