LangChain.js 三行配置搭一个工具调用代理
2026/9/9 16:20:35 网站建设 项目流程

LangChain.js 三行配置搭一个工具调用代理

【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs

让代理能查知识库、能调内部 API,写代码反而是最快的一步——LangChain.js 的 createAgent 一行就能建出完整代理,工具用 zod 声明参数。更有用的是之后的事:怎么防止它半夜干危险操作、长对话里上下文怎么不爆、想换掉 gpt-4o 时业务代码要改几行。下面按实际会碰到的顺序过这三件事。

顺带交代定位:LangChain.js 是 TypeScript 写的智能体工程框架,createAgent 底层构建在 LangGraph 之上——你建出来的代理本质是一张带状态的图,检查点、中断恢复、流式输出都是附带的。

工具定义:一个函数加一份 zod 声明

先写工具,再谈代理。tool()的写法很固定:第一个参数是真正的执行函数,第二个是模型看到的声明,仓库里 示例代码 都是这个模式。

const searchCode = tool( async ({ query }) => runYourSearch(query), { name: "search_code", description: "Search code in repositories.", schema: z.object({ query: z.string() }), }, );

两个细节值得留意:description 是写给 LLM 看的,模型调不调用、什么时候调用,很大程度上由这句话决定;schema 会被自动转成工具调用契约,参数校验不用手写。

从模型到工具调用:三行配置

工具就绪后,建代理就是三行配置加一次调用:

const agent = createAgent({ model: new ChatOpenAI({ model: "gpt-4o" }), tools: [searchCode], systemPrompt: "Only answer after searching.", }); const result = await agent.invoke({ messages: [{ role: "user", content: "How does auth work?" }], });

这里我踩过个小坑:model 也可以直接写成"openai:gpt-4o"这样的字符串,不用先实例化;但想传 temperature 这类参数就得用 provider 包的实例。换模型只动这一处——tools 和 prompt 与模型完全正交,这正是 provider 拆成 @langchain/openai、@langchain/anthropic 独立包的好处。

invoke 返回的result.messages是含完整工具调用过程的对话,取最后一条就是最终答案。

给危险操作加一道人工批准 🛑

这是 2.x 里我认为最实用的一块。humanInTheLoopMiddleware 声明哪些工具需要审批,代理走到它面前会自动暂停:

const hitl = humanInTheLoopMiddleware({ interruptOn: { write_file: { allowedDecisions: ["approve", "reject"] }, search_code: false, }, });

具体流程:代理执行到 write_file 时挂起,你用agent.graph.getState(config)能拿到挂起的调用及其参数,人确认后以new Command({ resume: { decisions: [{ type: "approve" }] } })恢复执行。

前置条件有两个,仓库的 HITL 示例就是完整做法:给 createAgent 传 checkpointer(演示用内存版 MemorySaver 即可),config 里带上 thread_id。

审批粒度是「每个工具」,不是「整个代理」。只读工具设 false 放行、写操作设 approve/reject,比全局开关实用得多。

🔧 几行中间件,上下文管理不用自己造

对话变长后有两个问题:上下文窗口溢出,以及为冗余内容付 token 钱。官方做法是 middleware:createAgent 接受 middleware 数组,每个中间件就是一个带 beforeModel、afterModel 钩子的对象。

const summarizer = createMiddleware({ name: "SummarizationMiddleware", beforeModel: async (state, runtime) => { if (state.messages.length > 10) { return { messages: compress(state.messages) }; } }, });

beforeModel 钩子里能读到当前状态、返回状态更新——觉得消息太旧就替换成摘要,代理对此毫无感知。中间件示例目录 里有现成的 modelCallLimit(限一轮对话的模型调用次数)、promptCaching、toolRetry、piiRedaction,大部分拿来即用。

这个钩子设计思路挺巧妙:框架内置策略和你的业务策略写出来是同一种东西,放同一个数组里,没有特殊 API。

一个代理扛不住时:supervisor 与 router

业务一复杂,一个代理挂十几个工具,模型选错工具的概率明显上升。examples/src/multi-agent/ 下有四个真实例子,给的是两种常见拆法:

  • Supervisor:日历、邮件各自建成小代理,再包成两个工具(schedule_event、manage_email)交给上层代理调用。上层只看到两个工具,下层的内部工具它碰不到。
  • Router:先用结构化输出把 query 分类到多个知识源,用 Send 并行查 GitHub、Notion、Slack,最后由一个模型汇总成答案。

两种模式的共同点:组合单位还是「代理即工具」,不需要为此学一套新编排框架。真遇到复杂循环、需要精细检查点恢复的流程,用 LangGraph.js 更合适;createAgent 返回的本身就是图,迁移路径是通的。

选型边界在哪里

用之前有几件事值得说清楚:

  • 2.x 是重写版本,老教程里的 LLMChain、SequentialChain 已移入单独的 langchain-classic 包,主包里没有,照着旧教程写会直接报错。
  • 主包服务「代理」场景。如果你的需求是固定流水线(模板 → 模型 → 解析器),不必硬套 createAgent,@langchain/core 的 runnables 直接组合即可。
  • 这个 monorepo 是给框架开发者用的(pnpm + Turborepo),用户项目npm install -S langchain就能起步。

往哪里看 📎

  • examples/src/createAgent/:createAgent 的流式、结构化输出、记忆、动态工具等用法,每个场景一个独立文件
  • 中间件示例:内置中间件速查
  • 核心文档 与 CONTRIBUTING.md:更细的机制说明

新项目我会先跑一遍 HITL 和 router 这两个示例——把 interrupt 和 resume 摸熟之后,再往真实服务上搬,多数问题会在 demo 阶段就暴露出来。

【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询