热门搜索:和平精英 原神 街篮2 

您的位置:首页 > > 教程攻略 > ai教程 >Langchain.js 实战五:Agent 实战

Langchain.js 实战五:Agent 实战

来源:互联网 更新时间:2026-07-26 07:24

Agent 这个概念,官方定义其实很简洁:一个大模型不断调用工具,直到完成给定的任务。用大白话说,Tool 就是手脚,Model 就是脑子,脑子指挥手脚干活儿,而衔接这两者的自动化程序,才是真正的 Agent。目前 AI 落地,说来说去核心就两样东西:LLM 大模型和 Prompt 提示词。LLM 决定了基础能力,是下限;而 Prompt 的玩法就多了。Tool 本质上也是提示词——把工具的功能和调用结果以提示词形式告诉大模型,大模型并不会主动执行工具,而是由本地的自动化程序监听大模型输出的格式化命令,然后替它执行,再把结果以提示词返回。整个流程就是 Agent。形象地说,大模型是通过袋里人完成工具调用的,那个自动化程序才是真正的 Agent,负责衔接大模型与 Tool。

上面提到,与 LLM 交互的一切都是提示词:Tool 是提示词,SKILL 是提示词,RAG 也是提示词(检索问题相关内容喂给 AI),Harness 还是提示词。因为 LLM 天生只能通过自然语言交互,别无他法。当前 AI 圈和币圈有点像,喜欢造热词,今天是 SKILL,明天是龙虾,后天是 Hermes、Loop Engineering……

既然搞清楚了什么是 Agent,那就用 Langchain 来实现它。

Agent 尝鲜

创建 Agent 其实很简单,create_agent 是一个高度可配置的执行框架,下面代码就创建了一个 Agent:

import { createAgent } from "langchain";
const agent = createAgent({ model: "openai:gpt-5.4", tools });

可以配置 modeltoolssystem_prompt,高级能力可以参考 middleware。下面给出一个可运行的 Agent 代码,首先创建一个模型:

import dotenv from "dotenv" // 加载环境变量中的模型 API 密钥
import { ChatOpenAI } from "@langchain/openai"

dotenv.config()

const model = new ChatOpenAI({
  model: "qwen-plus",
  apiKey: process.env.QWEN_API_KEY,
  temperature: 0.7,
  streamUsage: false, // 是否开启流式返回,默认 false
  // maxTokens: 1000, // 最大Tokens
  // maxRetries: 6 , // 最大重试次数,
  // timeout: undefined, // 超时时间
  logprobs: true,
  configuration: {
    baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
  }
}) 

然后创建一个 Agent,并给它一个可以模拟天气查询的工具:

import { createAgent, tool } from "langchain";
import * as z from "zod";

const search = tool(
  ({ query }) => `${query}的查询结果是:杭州今日晴朗,温度25°C。`,
  {
    name: "searchWeather",
    description: "Search for weather information",
    schema: z.object({ query: z.string().describe("需要查询天气的城市名称") }),
  }
);

const agent = createAgent({
  model: model,
  tools: [search],
  systemMessage: "你是一个有用的智能助手!你必须信任工具的结果。"
});

最后调用该 Agent 看看结果:

const result = await agent.invoke({
  messages: [{ role: "user", content: "杭州今日天气?" }]
});
console.log(result.messages[result.messages.length - 1].content);

到这里应该已经理解了什么是 Agent——就是给大模型赋予调用工具的能力,让它从“纸上谈兵”变成“动手实干”。

结构化输出

如果想让 Agent 输出结构化的内容,只需要加一个参数,如下代码:

import * as z from "zod";

const Answer = z.object({
  summary: z.string().describe("天气的总结描述"),
  confidence: z.number().describe("天气的置信度")
});

const agent = createAgent({
  model: model,
  tools: [search],
  responseFormat: Answer
});

const result = await agent.invoke({
  messages: [{ role: "user", content: "今天天气如何?" }]
});
result.structuredResponse; // { summary: ..., confidence: ... }

通过 responseFormat 可以让大模型按照给定的格式输出,上面约束了模型以 JSON 格式输出结论和置信度。

获取 Agent 执行进度

Agent 可能执行一个非常耗时的任务,比如写代码,需要不断思考、写代码、测试、修 BUG、再验证。如果执行进度不可知,用户会疯掉。好在 Langchain 提供了相关技术。为了显示中间进度,可以实时回传消息:

const stream = await agent.stream(
  {
    messages: [{ role: "user", content: "搜索杭州今天的天气,然后总结!" }],
  },
  { streamMode: "values" }
);

for await (const chunk of stream) {
  // Each chunk contains the full state at that point
  const latestMessage = chunk.messages.at(-1);
  if (latestMessage?.content) {
    console.log(`Agent: ${latestMessage.content}`);
  } else if (latestMessage?.tool_calls) {
    const toolCallNames = latestMessage.tool_calls.map((tc) => tc.name);
    console.log(`Calling tools: ${toolCallNames.join(", ")}`);
  }
}

对 Agent 的约束

开头说了 Agent = Model + Harness,Harness 对大模型的执行至关重要。本节来实战,如何使用 Langchain 实现对大模型的约束。

create_agent 具有极高的可扩展性,其定制化基元就是中间件:每个中间件只专注处理一个特定关注点,在智能体循环的恰当时机切入,并且能与其他任意中间件自由组合。只需按需取用,不需要的部分直接跳过即可。常见的业务模式已经作为内置中间件提前构建好了,任何个性化的定制需求,往往只需要编写一个中间件就能搞定。

随着 Agent 承担更复杂的工作,它们需要在几个关键领域获得支持。中间件生态系统涵盖了所有这些领域:

约束执行环境

智能体只有在能够真正“采取行动”时才具有实用价值,而不仅仅是生成文本。执行环境为智能体提供了一个专属的工作空间:里面有它可以调用的工具,还有用于在多轮对话中读写文件的文件系统,以及用来运行脚本或 Shell 命令的代码执行环境。下面的中间件演示了这一点。

执行环境

下面介绍一个中间件——createFilesystemMiddleware,用于创建包含所有工具和功能的文件系统。

import { createAgent } from "langchain";
import { FilesystemMiddleware, StateBackend } from "deepagents";

const agent = createAgent({
  model: "anthropic:claude-sonnet-4-6",
  tools: [search],
  middleware: [
    new FilesystemMiddleware({ backend: new StateBackend() })
  ],
});

这段代码构建了一个以 Claude Sonnet 4.6 为大脑、具备搜索能力的智能体。通过挂载文件系统中间件和内存状态后端,让智能体拥有了一个虚拟的临时文件系统,能够自主管理长文本和中间数据,非常适合处理需要多步推理和大量信息检索的复杂任务。

  • middleware: [new FilesystemMiddleware({ backend: new StateBackend() })]:这是核心配置。FilesystemMiddleware 赋予了智能体 lsread_filewrite_fileedit_file 等工具。当搜索工具返回大量结果时,智能体可以将长文本保存到“文件”中,避免撑爆上下文窗口,实现高效的上下文工程。StateBackend 指定了文件系统的底层存储方式,使用 StateBackend 意味着文件是临时存储在智能体的运行状态(内存)中,通常用于开发和测试阶段,会话结束后数据不会跨线程持久化。

上下文管理

每次模型调用都有固定的上下文窗口限制。随着智能体运行——不断积累历史对话、工具返回结果以及中间推理步骤——这个窗口很快就会被填满。为了解决这个问题,系统采用了以下机制:

  • 摘要压缩(Summarization):在窗口溢出前,自动对历史对话进行压缩提炼;
  • 记忆(Memory):在启动时加载持久化的指令,确保关键知识能够跨越不同会话延续;
  • 技能(Skills):按需动态加载领域知识,而不是在启动时就把所有内容一股脑塞进上下文里。
import {
  FilesystemMiddleware,
  MemoryMiddleware,
  SkillsMiddleware,
  SummarizationMiddleware,
  StateBackend
} from "deepagents";

const backend = new StateBackend();
const model = "anthropic:claude-sonnet-4-6";

const agent = createAgent({
  model,
  tools: [search],
  middleware: [
    new FilesystemMiddleware({ backend }),
    new SummarizationMiddleware({ model, backend }),
    new MemoryMiddleware({ backend, sources: ["./AGENTS.md"] }),
    new SkillsMiddleware({ backend, sources: ["./skills/"] }),
  ],
});

以下是代码的逐行解析:

  1. 导入核心依赖——从 deepagents 导入了四个关键中间件:FilesystemMiddleware(文件系统)、MemoryMiddleware(长期记忆)、SkillsMiddleware(技能/领域知识)和 SummarizationMiddleware(自动摘要),以及用于底层存储的 StateBackend
  2. 初始化基础配置——const backend = new StateBackend(); 创建一个基于内存状态的临时文件系统后端;const model = "anthropic:claude-sonnet-4-6"; 定义智能体使用的大模型。
  3. 创建并配置智能体——createAgent({ ... }) 初始化智能体,指定了模型和搜索工具,并在 middleware 数组中挂载了四个中间件,它们按顺序协同工作:
    • FilesystemMiddleware:赋予智能体虚拟文件系统能力,当搜索工具返回超长文本时,智能体可以将其写入文件,避免直接塞入上下文导致溢出。
    • SummarizationMiddleware:自动摘要压缩中间件,当上下文接近窗口上限时,自动将旧历史对话压缩成摘要,释放上下文空间。
    • MemoryMiddleware:长期记忆中间件,配置了 sources: ["./AGENTS.md"],意味着智能体在启动时会加载该文件中的持久化指令或背景知识,确保跨会话的知识传承。
    • SkillsMiddleware:技能中间件,配置了 sources: ["./skills/"],允许智能体按需动态加载特定领域的专业知识,从而极大节省 Token 消耗。

总结:这段代码构建了一个高度工程化的智能体,不仅具备搜索能力,还通过中间件机制实现了“大结果卸载(Filesystem)”、“历史自动压缩(Summarization)”、“持久化知识注入(Memory)”以及“按需加载技能(Skills)”,完美契合了现代 Agent 开发中的上下文工程理念。

规划与任务委派

复杂任务往往超出了单个上下文窗口能处理的极限。通过“任务委派”,主智能体可以将庞大的工作拆解为若干子任务,并交由在各自独立上下文中运行的子智能体去处理。主智能体就能专注于全局统筹与协调,而非陷入具体执行细节中。子任务还可以并行推进,确保上下文始终保持整洁与高效。

import { createAgent, todoListMiddleware, tool } from "langchain";
import {
  createFilesystemMiddleware,
  createSubAgentMiddleware,
  StateBackend,
} from "deepagents";
import * as z from "zod";

const search = tool(
  ({ query }) => `Search results for: ${query}`,
  {
    name: "search",
    description: "Search for a query and return a short summary.",
    schema: z.object({ query: z.string() }),
  }
);

const backend = new StateBackend();

const agent = createAgent({
  model: "openai:gpt-5.4",
  tools: [search],
  middleware: [
    createFilesystemMiddleware({ backend }),
    todoListMiddleware(),
    createSubAgentMiddleware({
      defaultModel: "anthropic:claude-sonnet-4-6",
      defaultTools: [],
      subagents: [
        {
          name: "researcher",
          description: "Searches and returns a structured summary.",
          systemPrompt: "Use the search tool to research the question and summarize key points.",
          tools: [search],
          model: "anthropic:claude-sonnet-4-6",
          middleware: [],
        },
      ],
    }),
  ],
});

这段代码展示了如何使用 deepagents 框架构建一个具备任务规划和多智能体协作能力的复杂 AI 智能体架构。主智能体负责任务拆解和统筹,子智能体拥有独立上下文执行具体任务。

详细解析:

  1. 导入依赖与定义工具——从 langchain 导入 createAgenttodoListMiddlewaretool;从 deepagents 导入文件系统中间件、子智能体中间件以及内存状态后端;使用 zod 定义 search 工具的输入校验模式。
  2. 初始化存储后端——const backend = new StateBackend(); 创建基于内存的临时文件系统后端。
  3. 核心配置:中间件管道——在 createAgent 中挂载三个核心中间件:
    • createFilesystemMiddleware({ backend }):赋予智能体虚拟文件系统能力,大型工具调用结果自动卸载到文件中。
    • todoListMiddleware():任务规划引擎,强制智能体在行动前先生成结构化的待办事项列表,将复杂目标拆解为可验证的原子步骤。
    • createSubAgentMiddleware({ ... }):子智能体协作机制,配置了一个名为 researcher 的子智能体,拥有独立上下文、专属模型和工具。主智能体可以通过内置的 task 工具将研究任务委派给它,支持并行执行。

总结:这段代码构建了一个“主-子”架构的生产级智能体。主智能体使用 GPT-5.4 作为大脑,负责任务拆解和统筹;遇到具体研究任务时,委派给专门的 researcher 子智能体执行搜索和总结。结合文件系统卸载机制,非常适合处理多步推理、大量信息检索的超长周期任务。

容错机制

在生产环境中,智能体经常会遇到一些在开发阶段极少出现的故障,比如请求频率限制、模型响应超时以及瞬时的 API 错误。容错中间件会在基础设施层面统一处理这些问题,工具和业务逻辑就不必在每次调用时都写一堆 try/catch 了。

import {
  createAgent,
  modelRetryMiddleware,
  tool,
  toolRetryMiddleware,
} from "langchain";
import * as z from "zod";

const search = tool(
  ({ query }) => `Search results for: ${query}`,
  {
    name: "search",
    description: "Search for a query and return a short summary.",
    schema: z.object({ query: z.string() }),
  }
);

const agent = createAgent({
  model: "openai:gpt-5.4",
  tools: [search],
  middleware: [
    modelRetryMiddleware({ maxRetries: 3 }),
    toolRetryMiddleware({ maxRetries: 2 }),
  ],
});

这段代码展示了如何使用 langchain 框架为 AI 智能体构建高可用性与容错机制。在真实工程环境中,大模型 API 调用可能因为网络波动、限流或格式错误而失败。通过挂载两个重试中间件,赋予智能体在遇到错误时自动恢复的能力,从而保证任务连续性。

详细解析:

  1. 导入依赖与定义工具——从 langchain 导入 createAgenttool 以及两个核心重试中间件 modelRetryMiddlewaretoolRetryMiddleware;使用 zod 定义 search 工具的参数类型。
  2. 核心配置:容错中间件管道——在 createAgentmiddleware 数组中挂载两个重试机制:
    • modelRetryMiddleware({ maxRetries: 3 }):模型调用重试。当智能体向底层大模型发起推理请求时,如果因网络超时、API 限流或服务端错误导致失败,自动重试最多 3 次。
    • toolRetryMiddleware({ maxRetries: 2 }):工具执行重试。当智能体调用 search 工具抛出异常(如搜索接口超时或返回非预期格式数据)时,自动重试最多 2 次。

总结:这段代码构建了一个具备自我修复能力的生产级智能体,能够在模型响应失败或工具执行出错时按照预设阈值自动重试,是构建稳定、可靠 AI Agent 系统的最佳实践之一。

安全护栏(Guardrails)

有些策略无法仅靠写在提示词里来约束,必须被确定性地强制执行,无论模型做出什么反应。安全护栏会在数据流经智能体循环时进行拦截,在工具返回的结果进入模型上下文之前,提前应用合规规则或内容安全策略。

import { createAgent, piiMiddleware, tool } from "langchain";
import * as z from "zod";

const search = tool(
  ({ query }) => `Search results for: ${query}`,
  {
    name: "search",
    description: "Search for a query and return a short summary.",
    schema: z.object({ query: z.string() }),
  }
);

const agent = createAgent({
  model: "openai:gpt-5.4",
  tools: [search],
  middleware: [
    piiMiddleware("email")
  ],
});

这段代码展示了如何使用 langchain 框架为 AI 智能体配置数据隐私保护机制。在企业级或面向公众的 AI 应用中,防止用户个人敏感信息(如邮箱、身份证号、信用卡号)被意外发送给大模型至关重要。通过挂载 piiMiddleware,在数据流向模型之前自动拦截并处理敏感信息。

详细解析:

  1. 导入依赖与定义工具——从 langchain 导入 createAgenttool 以及核心的 piiMiddleware;使用 zod 定义 search 工具的参数类型。
  2. 核心配置:隐私保护中间件——piiMiddleware("email") 是一个专门用于拦截和脱敏邮箱地址的中间件。当用户输入或工具返回结果中包含电子邮件地址时,该中间件会在数据传递给底层大模型之前进行自动处理,通常采用替换、掩码或阻断等策略,确保大模型永远不会接触到真实的邮箱数据。

总结:这段代码构建了一个具备隐私合规能力的智能体,在中间件层拦截敏感数据,既享受大模型推理能力,又确保用户隐私安全,是构建安全可信赖 AI Agent 系统的核心最佳实践。

人工引导(Steering)

完全的自主性并不总是合适的。通过“人工引导”,可以将人类介入点设置在特定的决策环节——例如在执行破坏性写入、高成本 API 调用或任何需要人工判断的操作之前——而无需重构智能体架构。在这种模式下,智能体会暂停并等待:由人类进行审批、修改或拒绝,随后智能体再继续执行后续操作。

import { createAgent, humanInTheLoopMiddleware, tool } from "langchain";
import * as z from "zod";

const search = tool(
  ({ query }) => `Search results for: ${query}`,
  {
    name: "search",
    description: "Search for a query and return a short summary.",
    schema: z.object({ query: z.string() }),
  }
);

const agent = createAgent({
  model: "openai:gpt-5.4",
  tools: [search],
  middleware: [
    humanInTheLoopMiddleware({ interruptOn: { writeFile: true } })
  ],
});

这段代码展示了如何使用 langchain 框架为 AI 智能体配置人机交互与人工审批机制。在高度自主的 AI 应用中,为了防止智能体在执行危险操作(如删除数据、写入文件、发送邮件等)时产生不可逆后果,通常需要在关键节点引入人工监督。通过挂载 humanInTheLoopMiddleware,赋予智能体在执行特定操作前“暂停并等待人类确认”的能力。

详细解析:

  1. 导入依赖与定义工具——从 langchain 导入 createAgenttool 以及核心的 humanInTheLoopMiddleware;使用 zod 定义 search 工具的参数类型。
  2. 核心配置:人工审批中间件——humanInTheLoopMiddleware({ interruptOn: { writeFile: true } }) 定义了一个中断策略,告诉中间件在遇到特定工具调用时需要暂停执行。interruptOn 中的 writeFile: true 表示当智能体决定调用 writeFile 工具时,执行流程会被强制中断,等待人工决策。人类通常可以做出三种决策:批准(Approve)、编辑(Edit)或拒绝(Reject)。

总结:这段代码构建了一个具备安全控制与人工监督能力的智能体,将只读或低风险操作交由 AI 自主完成,将高风险写操作交由人类把关,是构建生产级、高安全性 AI Agent 系统的核心最佳实践。

具体可参考 Middleware resources:

  • Middleware overview: how the middleware stack works and when hooks fire
  • Prebuilt middleware: full reference with configuration examples
  • Custom middleware: write your own hooks for business logic, PII scrubbing, and more

热门手游

手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc