从零开始搭建一个 AI Agent —— LangChain + TypeScript 实战手记 1. 引言为什么选择 LangChain TypeScript随着大语言模型LLM能力的快速演进越来越多的开发者希望把模型能力封装成可复用的智能应用。AI Agent 正是这一趋势下的核心产物它不仅能调用模型生成文本还能自主规划任务、调用工具、读取上下文最终完成一个相对复杂的业务目标。在技术选型上LangChain 是目前生态最成熟的 Agent 编排框架之一而 TypeScript 版本LangChain.js则让前端、Node.js 全栈开发者可以用同一套语言完成 Agent 的搭建与部署。本文将从零开始带你一步步用 LangChain TypeScript 构建一个可运行的 AI Agent并给出完整的代码实战。本文的实战目标构建一个「技术问答助手 Agent」它能够根据用户的问题自主决定是否需要调用外部工具如网络搜索、本地文档检索并最终给出带依据的回答。2. 环境准备与项目初始化在开始写代码之前我们需要先准备好 Node.js 环境并初始化一个 TypeScript 项目。2.1 环境要求Node.js 18 及以上版本推荐 20 LTSnpm 或 yarn 包管理器一个可用的 LLM API Key本文以 OpenAI 为例也可替换为其他模型2.2 初始化项目打开终端执行以下命令创建项目目录并初始化 package.jsonmkdir langchain-agent-demo cd langchain-agent-demo npm init -y2.3 安装依赖接下来安装 LangChain.js 核心包、OpenAI 集成包以及 TypeScript 相关工具npm install langchain langchain/openai dotenv npm install -D typescript tsx types/node2.4 配置 TypeScript创建 tsconfig.json 文件{ compilerOptions: { target: ES2022, module: ESNext, moduleResolution: bundler, strict: true, esModuleInterop: true, skipLibCheck: true, outDir: dist }, include: [src/**/*.ts] }2.5 配置环境变量在项目根目录创建 .env 文件填入你的 API KeyOPENAI_API_KEYsk-your-key-here然后在 package.json 的 scripts 中添加启动命令scripts: { dev: tsx src/index.ts }3. 第一个 Agent最小可运行示例环境准备好之后我们先写一个最简单的 Agent让它具备「调用工具」的能力。这里我们给 Agent 注册一个「获取当前时间」的工具让它学会在需要时调用工具而不是凭空编造。3.1 创建入口文件在 src 目录下创建 index.tsimport dotenv/config; import { ChatOpenAI } from langchain/openai; import { createReactAgent } from langchain/langgraph/prebuilt; import { tool } from langchain/core/tools; import { z } from zod; // 1. 定义一个获取当前时间的工具 const getCurrentTime tool( async () { return new Date().toLocaleString(zh-CN, { timeZone: Asia/Shanghai, }); }, { name: get_current_time, description: 获取当前日期和时间当用户询问时间时调用, schema: z.object({}), } ); // 2. 初始化 LLM const model new ChatOpenAI({ model: gpt-4o-mini, temperature: 0, }); // 3. 创建 Agent const agent await createReactAgent({ llm: model, tools: [getCurrentTime], }); // 4. 运行 Agent const result await agent.invoke({ messages: [{ role: user, content: 现在几点了 }], }); console.log(result.messages[result.messages.length - 1].content);3.2 运行验证在终端执行以下命令npm run dev如果一切正常你会看到 Agent 输出了当前时间。这个过程中Agent 内部经历了「理解问题 → 决定调用工具 → 获取结果 → 组织回答」的完整链路。这里的关键点在于我们没有在代码里写死时间而是让 Agent 自主决定调用工具。这就是 Agent 与普通 LLM 调用的本质区别。4. 深入理解 Agent 的核心机制上面的示例虽然简单但背后涉及了 Agent 的几个核心概念。理解这些概念是搭建复杂 Agent 的基础。4.1 ReAct 模式LangChain 的 createReactAgent 基于 ReActReasoning Acting模式实现。它的工作流程可以概括为循环思考Thought模型分析当前问题决定下一步做什么。行动Action调用某个工具传入参数。观察Observation读取工具返回的结果。循环根据观察结果继续思考直到得出最终答案。这种「思考-行动-观察」的循环让 Agent 能够处理需要多步推理的复杂任务。4.2 工具Tool的本质工具是 Agent 与外部世界交互的桥梁。在 LangChain.js 中一个工具由三部分组成名称name唯一标识模型通过名称调用。描述description告诉模型这个工具是干什么的、什么时候该用。参数模式schema定义工具需要的入参结构模型会按此生成参数。工具描述写得越清晰模型就越能准确判断何时调用、如何传参。这是提升 Agent 准确率的关键技巧。4.3 记忆Memory上面的示例是无状态的每次调用都是独立对话。但在真实场景中Agent 往往需要记住上下文。LangChain.js 提供了多种记忆方案最简单的是把历史消息传入 messages 数组const result await agent.invoke({ messages: [ { role: user, content: 我叫小明 }, { role: assistant, content: 你好小明 }, { role: user, content: 我叫什么名字 }, ], });对于更复杂的场景可以使用 LangGraph 的持久化检查点Checkpointer机制把对话状态保存到数据库或文件中实现跨会话记忆。5. 实战构建带搜索能力的问答 Agent掌握了核心机制后我们来构建一个更实用的 Agent技术问答助手。它除了能回答常规问题还能在遇到不确定的问题时调用「网络搜索」工具获取最新信息。5.1 定义搜索工具这里我们使用 Tavily 搜索 API 作为示例。首先安装依赖npm install langchain/community然后在 .env 中添加TAVILY_API_KEYtvly-your-key-here创建 src/search-agent.tsimport dotenv/config; import { ChatOpenAI } from langchain/openai; import { createReactAgent } from langchain/langgraph/prebuilt; import { TavilySearchResults } from langchain/community/tools/tavily_search; // 1. 初始化搜索工具 const searchTool new TavilySearchResults({ maxResults: 3, }); // 2. 初始化 LLM const model new ChatOpenAI({ model: gpt-4o-mini, temperature: 0, }); // 3. 创建 Agent const agent await createReactAgent({ llm: model, tools: [searchTool], }); // 4. 测试问一个需要实时信息的问题 const result await agent.invoke({ messages: [ { role: user, content: LangChain.js 最新版本是多少有什么新特性, }, ], }); console.log(result.messages[result.messages.length - 1].content);5.2 运行测试执行以下命令npx tsx src/search-agent.ts你会看到 Agent 先调用搜索工具获取最新信息再基于搜索结果组织回答。相比直接问模型这种方式能显著减少「幻觉」问题回答也更有依据。5.3 多工具协同真实场景中Agent 往往需要同时具备多个工具。我们可以把搜索工具和时间工具一起注册const agent await createReactAgent({ llm: model, tools: [searchTool, getCurrentTime], });当用户问「今天关于 TypeScript 的最新资讯」时Agent 会先获取当前日期再带着日期去搜索从而得到更精准的结果。这就是多工具协同的价值。6. 进阶使用 LangGraph 自定义 Agent 流程createReactAgent 适合快速搭建但当你需要精细控制 Agent 的执行流程时就需要使用 LangGraph。LangGraph 是 LangChain 官方推出的图编排框架它把 Agent 的每一步建模为图节点节点之间通过边连接形成可预测、可调试的执行流程。6.1 安装 LangGraphnpm install langchain/langgraph6.2 构建自定义流程下面我们构建一个「先规划、再执行、最后总结」的三步 Agentimport dotenv/config; import { ChatOpenAI } from langchain/openai; import { StateGraph, Annotation } from langchain/langgraph; import { TavilySearchResults } from langchain/community/tools/tavily_search; // 1. 定义状态 const AgentState Annotation.Root({ messages: Annotationany[]({ reducer: (x, y) x.concat(y), }), plan: Annotationstring({ reducer: (x, y) y ?? x, }), }); // 2. 初始化模型和工具 const model new ChatOpenAI({ model: gpt-4o-mini, temperature: 0 }); const searchTool new TavilySearchResults({ maxResults: 3 }); // 3. 定义节点规划 async function planNode(state: typeof AgentState.State) { const response await model.invoke([ { role: system, content: 你是任务规划器。请把用户的问题拆解为 1-3 个需要搜索的子问题用编号列表输出。, }, ...state.messages, ]); return { plan: response.content as string }; } // 4. 定义节点执行搜索 async function searchNode(state: typeof AgentState.State) { const searchResults await searchTool.invoke(state.plan); return { messages: [ { role: assistant, content: 搜索计划\n${state.plan}\n\n搜索结果\n${searchResults}, }, ], }; } // 5. 定义节点总结回答 async function answerNode(state: typeof AgentState.State) { const response await model.invoke([ { role: system, content: 你是技术问答助手。请基于搜索结果用中文给出条理清晰、有依据的回答。如果搜索结果不足请明确说明。, }, ...state.messages, ]); return { messages: [response] }; } // 6. 构建图 const graph new StateGraph(AgentState) .addNode(plan, planNode) .addNode(search, searchNode) .addNode(answer, answerNode) .addEdge(__start__, plan) .addEdge(plan, search) .addEdge(search, answer) .addEdge(answer, __end__) .compile(); // 7. 运行 const result await graph.invoke({ messages: [ { role: user, content: 2026 年 TypeScript 有哪些值得关注的新特性, }, ], }); console.log(result.messages[result.messages.length - 1].content);6.3 为什么用 LangGraph相比 createReactAgent 的黑盒循环LangGraph 的优势在于流程可控每一步做什么、顺序如何都由你定义。可调试可以查看每个节点的输入输出定位问题更轻松。可扩展可以方便地加入条件分支、人工审核节点、循环等复杂逻辑。当你的 Agent 业务逻辑越来越复杂时LangGraph 是更合适的选择。7. 部署与生产化建议开发完成之后把 Agent 部署到生产环境还需要考虑几个关键问题。7.1 封装为 HTTP 服务使用 Express 把 Agent 封装为 REST API是最常见的部署方式npm install express corsimport dotenv/config; import express from express; import cors from cors; import { ChatOpenAI } from langchain/openai; import { createReactAgent } from langchain/langgraph/prebuilt; import { TavilySearchResults } from langchain/community/tools/tavily_search; const app express(); app.use(cors()); app.use(express.json()); const model new ChatOpenAI({ model: gpt-4o-mini, temperature: 0 }); const searchTool new TavilySearchResults({ maxResults: 3 }); const agent await createReactAgent({ llm: model, tools: [searchTool] }); app.post(/api/chat, async (req, res) { const { message, history [] } req.body; try { const result await agent.invoke({ messages: [...history, { role: user, content: message }], }); const reply result.messages[result.messages.length - 1].content; res.json({ reply }); } catch (error) { console.error(error); res.status(500).json({ error: Agent 调用失败 }); } }); const PORT process.env.PORT || 3000; app.listen(PORT, () { console.log(Agent server running on http://localhost:${PORT}); });7.2 成本控制Agent 的每次任务可能涉及多次模型调用成本比普通对话高。建议采取以下措施设置 maxIterations 限制 Agent 的最大循环次数。对工具调用结果做缓存避免重复搜索。使用更便宜的模型处理简单任务复杂任务才用强模型。7.3 可观测性生产环境强烈建议接入 LangSmith 或类似的追踪平台记录每次 Agent 运行的完整轨迹包括思考过程、工具调用、耗时和成本。这能极大提升排查问题的效率。8. 常见问题与踩坑记录在实战过程中有几个高频问题值得记录。8.1 工具调用格式错误如果模型返回的工具调用格式不符合预期通常是因为工具 schema 定义不清晰。建议给每个参数写清楚描述。尽量使用必填参数减少模型自由发挥空间。工具描述中明确「什么时候不要调用」。例如「仅当用户明确要求搜索时才调用」。8.2 循环不终止Agent 陷入死循环是常见问题。解决办法在 createReactAgent 中传入 maxIterations 参数。检查工具描述是否过于模糊导致模型反复调用。在 LangGraph 中设置最大步数限制。8.3 上下文过长多轮对话后历史消息可能超出模型上下文窗口。解决方案对历史消息做截断只保留最近 N 轮。使用摘要压缩历史。引入向量数据库做长期记忆只检索相关片段。9. 总结与下一步学习方向本文从零开始带你走完了「环境准备 → 最小 Agent → 工具调用 → 搜索增强 → LangGraph 自定义流程 → 生产化部署」的完整链路。核心要点总结如下Agent 的本质是「模型 工具 循环决策」。工具描述的质量直接影响 Agent 的准确率。createReactAgent 适合快速原型LangGraph 适合复杂生产流程。生产环境要重点关注成本、可观测性和上下文管理。下一步你可以从以下几个方向继续深入接入本地知识库RAG让 Agent 基于私有文档回答。使用 LangGraph 加入人工审核节点构建「人在回路」工作流。探索多 Agent 协作模式让多个 Agent 分工完成复杂任务。研究流式输出提升用户交互体验。AI Agent 的生态发展非常快保持动手实践的习惯是跟上这个领域最好的方式。希望这篇手记能成为你 Agent 开发之路的起点。