我第一次写多 Agent 系统时犯过一个错误:把所有工具塞进一个 tools 数组,然后把这个数组挂给每个 Agent。结果上线后发现:负责写文章摘要的 Agent,有时候莫名其妙地调用了删除接口;负责检索资料的 Agent,偶尔会触发支付工具。不是 bug,是 LLM 的「创意发挥」——它看到工具就会用。

这不是模型的问题,是架构设计的问题。工具权限应该跟着 Agent 角色走,不是跟着 LLM 走。


01 工具隔离的本质:职责边界就是权限边界

先说清楚我们在解决什么问题。

一个生产级的 Multi-Agent 系统通常有三类角色:

Supervisor(协调者)

├── ResearchAgent(调研者)—— 只能「读」

├── WriterAgent(创作者)  —— 只能「写」

└── AdminAgent(管理者)   —— 能「读 + 写 + 删」

如果三个 Agent 共享工具池,本质上等于把数据库的 root 权限交给了每个人。一旦 LLM 幻觉发作或者 prompt 注入攻击触发,任何 Agent 都能操作不该操作的资源。

权限隔离做的事,说白了就一句话:你的角色决定你的工具,你的工具决定你的边界。

这跟后端系统的 RBAC(基于角色的访问控制)是同一个道理。角色不再是「管理员/普通用户」,而是「ResearchAgent/WriterAgent/AdminAgent」——换了场景,逻辑没变。


02 方案一:静态绑定——最简单,用 createReactAgent

最直接的方案:在创建 Agent 时,就把它的专属工具集传进去

importfrom"@langchain/langgraph/prebuilt"importChatOpenAIfrom"@langchain/openai"importfrom"@langchain/core/tools"importfrom"zod"constnewChatOpenAImodel"gpt-4o"// 按职责分组定义工具consttoolasync`搜索结果:${query} 的相关信息...`name"web_search"description"搜索网络上的公开信息"schemaobjectquerystringdescribe"搜索关键词"toolasync`文档内容:${docId}`name"read_document"description"读取数据库中的文档"schemaobjectdocIdstringdescribe"文档ID"consttoolasync`已保存文章:${title}`name"save_article"description"保存生成的文章到数据库"schemaobjecttitlestringdescribe"文章标题"contentstringdescribe"文章内容"consttoolasync`已删除文档:${docId}`name"delete_document"description"永久删除数据库中的文档,不可恢复,仅限管理员使用"schemaobjectdocIdstringdescribe"要删除的文档ID"// ✅ 每个 Agent 只拿到自己该有的工具constcreateReactAgenttoolsconstcreateReactAgenttoolsconstcreateReactAgenttools

注意每个 Agent 传入的是独立数组(展开运算符),不是同一个引用。原因后面「常见坑」里会说。

优点:简单直白,一眼看出每个 Agent 能干什么。限制:工具集在创建时固定,无法根据运行时状态动态调整。


03 方案二:动态注入——根据 State 决定工具集

更灵活的方案:工具集不在创建时绑死,而是在每次节点执行前,从 State 中读取权限配置,动态拼装工具列表

适用场景:同一个 Agent,在不同对话阶段有不同工具权限——比如付费前只能用基础工具,付费后解锁高级工具。

importStateGraphAnnotationfrom"@langchain/langgraph"importChatOpenAIfrom"@langchain/openai"importHumanMessagefrom"@langchain/core/messages"constnewChatOpenAImodel"gpt-4o"// 模块级别,只创建一次// State 定义:包含权限级别constAgentStateAnnotationRootmessagesAnnotationHumanMessagereducer(curr, update) =>default() =>permissionLevelAnnotation"read-only""read-write""admin"reducer(_, update) =>default() =>"read-only"// 工具工厂:根据权限级别返回对应工具集functiongetToolsForPermissionlevel: "read-only" | "read-write" | "admin"constif"read-only"returnif"read-write"returnreturn// admin 全量// 动态注入工具的节点asyncfunctiondynamicAgentNodestate: typeof AgentState.StateconstgetToolsForPermissionpermissionLevelconstbindTools// bindTools 开销远低于 new LLMconstawaitinvokemessagesreturnmessagesconstnewStateGraphAgentStateaddNode"agent"addEdge"__start__""agent"compile// 调用时传入不同的权限级别constawaitinvokemessagesnewHumanMessage"帮我把新闻整理成文章并保存"permissionLevel"read-write"

getToolsForPermission 是一个纯函数,输入权限级别,输出工具集。这样的设计很容易测试:不用启动图,直接断言函数返回值就够了。


04 方案三:工具守卫——在工具内部做鉴权

前两种方案都在「分配工具」这一层做隔离。还有第三种思路:每个工具自己检查调用方是否有权限执行

这更接近后端 API 的鉴权模式:不管谁调用,工具自己说了算。

importfrom"@langchain/core/tools"importfrom"zod"importRunnableConfigfrom"@langchain/core/runnables"interfaceAgentContextagentIdstringpermissionsstringuserIdstring// 带守卫逻辑的删除工具consttoolasyncconfigRunnableConfigconstconfigurableagentContextasAgentContextundefinedifthrownewError"缺少 Agent 上下文信息,无法验证权限"// 工具内部鉴权ifpermissionsincludes"delete"thrownewError`Agent "${ctx.agentId}" 没有删除权限,当前权限:${ctx.permissions.join(", ")}`// 审计日志:谁、通过哪个 Agent、删了什么consolelog`[AUDIT] ${ctx.userId} via ${ctx.agentId} → delete ${docId}`return`文档 ${docId} 已删除`name"delete_document"description"永久删除指定文档(需要 delete 权限)"schemaobjectdocIdstring// 调用时通过 configurable 传入 Agent 上下文constawaitinvokemessagesnewHumanMessage"删除文档 doc-123"configurableagentContextagentId"writer-agent"permissions"read""write"// 没有 delete → 工具会拒绝userId"user-456"

适用场景:你有一套共享工具库,不同调用方权限不同;或者需要细粒度的审计日志(谁在什么时间调用了什么工具),金融、医疗、内部合规场景必备。


05 三种方案对比:怎么选?

维度 静态绑定 动态注入 工具守卫
实现复杂度 ⭐ 简单 ⭐⭐ 中等 ⭐⭐⭐ 较高
隔离时机 Agent 创建时 运行时(每次执行) 调用时(工具内部)
适用场景 角色固定的系统 权限随状态变化 共享工具库 + 审计需求
审计能力 ❌ 无 ❌ 无 ✅ 有
性能开销 最低 中等 最低
可测试性 高(纯函数工厂)

选型建议:

  • 90% 的场景用静态绑定:角色清晰、职责固定,最省事,代码最易读。
  • 权限需要动态变化,用动态注入:付费/免费分级、不同阶段解锁不同能力。
  • 需要审计日志,用工具守卫:金融、医疗、内部合规场景。
  • 最佳实践是组合:静态绑定做第一道防线,工具守卫做第二道——两层隔离,安全性翻倍。

06 完整实战:内容生产 Multi-Agent 系统

把三种方案串起来,搭一个真实场景:内容生产 Multi-Agent 系统(ResearchAgent → WriterAgent → ReviewAgent)。

importStateGraphAnnotationENDSTARTfrom"@langchain/langgraph"importfrom"@langchain/langgraph/prebuilt"importChatOpenAIfrom"@langchain/openai"importHumanMessageAIMessageBaseMessagefrom"@langchain/core/messages"constnewChatOpenAImodel"gpt-4o"temperature0// 按最小权限原则分配工具constcreateReactAgenttools// 只读constcreateReactAgenttools// 读 + 写草稿constcreateReactAgenttools// 审核 + 发布// Graph StateconstContentStateAnnotationRootmessagesAnnotationBaseMessagereducer(curr, update) =>default() =>currentStepAnnotation"research""write""review""done"reducer(_, update) =>default() =>"research"researchResultAnnotationstringreducer(_, update) =>default() =>""draftIdAnnotationstringreducer(_, update) =>default() =>""asyncfunctionresearchNodestate: typeof ContentState.Stateconstawaitinvokemessagesmessagesconstmessagesmessageslength1asAIMessagereturnmessagesmessagesresearchResultcontentasstringcurrentStep"write"asconstasyncfunctionwriterNodestate: typeof ContentState.StateconstmessagesnewHumanMessage`基于调研结果写文章并保存草稿:\n${state.researchResult}`constawaitinvokemessagesconstmessagesmessageslength1asAIMessageconstcontentasstringmatch/draft-\d+/returnmessagesmessagesdraftId0""currentStep"review"asconstasyncfunctionreviewNodestate: typeof ContentState.StateconstmessagesnewHumanMessage`审核草稿 ${state.draftId},确认无误后发布上线`constawaitinvokemessagesreturnmessagesmessagescurrentStep"done"asconstconstnewStateGraphContentStateaddNode"research"addNode"write"addNode"review"addEdgeSTART"research"addEdge"research""write"addEdge"write""review"addEdge"review"ENDcompileconstawaitinvokemessagesnewHumanMessage"请写一篇关于 LangGraph 权限隔离的技术文章"

数据流向清晰:Research(只读)→ Writer(读写草稿)→ Review(发布)。每个 Agent 只能往「自己的方向」走,不会越界。


07 常见坑:这些错误让系统在生产环境翻车

坑 1:共享同一个 tools 数组引用

// ❌ 以为是复制,其实是同一个引用constconstcreateReactAgentconstcreateReactAgent// 一旦外部 push 了新工具进 tools,两个 Agent 同时受影响// ✅ 展开运算符创建独立副本constcreateReactAgenttoolsconstcreateReactAgenttools

坑 2:工具描述太泛,LLM 乱用工具

// ❌ 描述模糊,LLM 猜不准该不该用name"process_document"description"处理文档"// ✅ 精确到「动作 + 对象 + 后果」name"delete_document"description"永久删除数据库中的文档,不可恢复,仅限管理员使用"

工具描述越清晰,LLM 误调用概率越低。 这是权限隔离之外最容易被忽视的第二道防线。

坑 3:遗漏工具执行节点(ToolNode)

createReactAgent 时工具执行是内置的。但如果你用 bindTools 手动构建 Agent,必须加 ToolNode,否则 LLM 只会「生成工具调用请求」,没有东西去真正执行工具。

importToolNodefrom"@langchain/langgraph/prebuilt"constnewStateGraphAgentStateaddNode"llm"addNode"tools"newToolNode// ← 必须加这个addConditionalEdges"llm"addEdge"tools""llm"

总结

这篇我们把 Multi-Agent 权限隔离从三个角度拆了个透:

  • 静态绑定是基础:创建 Agent 时按角色分配工具集,简单直接,90% 场景够用
  • 动态注入是进阶:把权限级别放进 State,每次执行前按级别拼装工具,适合权限随状态变化的场景
  • 工具守卫是最后防线:在工具内部做鉴权检查,适合共享工具库 + 需要审计日志的场景
  • 工具描述是隐形防线:描述越精确,LLM 误调用概率越低,这是容易被忽视的细节
  • 最佳实践是组合:静态绑定 + 工具守卫,两层隔离,安全性翻倍
  • 三个高频坑:数组引用共享、描述太泛、忘记 ToolNode——在生产环境出现率极高:数组引用共享、描述太泛、忘记 ToolNode——在生产环境出现率极高

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐