公司动态

企业 Agent 替谁做事:权限、数据边界和用户身份

📅 2026/7/18 23:08:27
企业 Agent 替谁做事:权限、数据边界和用户身份
上一篇讲人工接管时我列了三类必须停下等人的动作其中一类是“越权”。很多人会问怎么算越权要回答这个得先把一个更基础的问题说清楚这个 Agent 到底有什么权它替谁做事这半年重构 Office Agent我越来越觉得企业 Agent 的权限问题比 Prompt 问题更早暴露。模型还没开始“聪明”系统就已经要先回答一个问题它是一个独立账号还是某个人的手我的结论先放前面Agent 不该有自己的超级账号。它必须以发起人的身份、在发起人的权限范围内做事。这篇文章只讨论一件事企业 Agent 替人做事但不能替系统重新定义权限。接 CRM 的第一个技术问题给 Agent 接 CRM 时我一开始以为第一个技术问题是它能不能正确地改数据。真正卡住我的不是这个而是另一个问题它以谁的身份改CRM 天生有数据权限。销售只能看自己的客户主管能看团队的普通员工看不到别人的成单金额。很多企业系统跑了很多年最核心的不是页面而是这套权限和数据边界。现在塞进来一个 Agent它该看到什么如果图省事给它配一个能看所有数据的公共服务账号问题立刻来了。一个销售让 Agent 帮他查“最近需要重点跟进的大客户”。如果 Agent 用公共高权限账号去查它可能把别人名下的客户也一起拿出来。它没有攻击系统。它没有绕过登录。它只是用了你给它的权限。而你给多了。这类问题最麻烦的地方在于它看起来不像一个明显的安全事故。界面能跑接口能通模型也能解释得头头是道。但从企业系统视角看权限边界已经被打穿了。我不把这个包装成“某次 CRM 泄露事故”。更诚实的说法是在设计 CRM Agent 权限时我很早就意识到不能先给它一个大账号再靠 Prompt 约束它“不要看不该看的数据”。后来我会把这条边界拆成三个很具体的工程约束。第一查询层先收窄。查询客户列表时权限过滤必须在查询条件里完成。Agent 拿到的结果本来就只能是当前发起人可见的客户而不是先查全量再让模型自己筛。第二技术账号不等于业务授权。技术账号只承担系统间调用通道。真正决定能看什么、能改什么的仍然是发起人的身份、组织范围和业务角色。第三写入动作必须能追到人。审计记录里不能只写“Agent 修改成功”。至少要留下发起人、执行动作、影响对象、授权范围和审批结果。Prompt 是提醒不是权限系统。权限必须落在系统里。如果把这件事翻译成代码它不应该长这样坏写法只要工具能调用就把判断交给模型。# 错误方向只要工具能调用就把判断交给模型def run_agent_action(user, action, payload): result llm.decide(actionaction, payloadpayload) return crm_api.execute(result)更稳的写法是先让系统判断“这个身份在这个对象上能不能做这个动作”好写法模型提出意图系统判断边界。# 脱敏后的最小形态业务权限先过系统边界再进入工具执行def can_operate(scope, entity, action): if scope.role admin: return True if entity customer: return action in {read, create, update} and scope.role in {sales, manager} if entity opportunity: if scope.role sales: return action in {read, create, update} if scope.role pre_sales: return action in {read, update} return False这里的关键不是代码多复杂而是判断位置变了。模型可以决定下一步想做什么。但它不能决定自己有没有权限。权限判断不交给模型Agent 到底有没有自己的权限站在企业系统开发负责人的角度我现在的判断很明确Agent 没有自己的业务权限只有借来的权限。张三让它做事它就是张三的手。张三看不到的客户它也不该看到。张三不能改的订单它也不能改。张三只能提交草案它也不能直接让草案生效。这句话听起来很朴素但落到系统里经常会被偷懒破坏。最常见的偷懒方式是把 Agent 当成一个“系统用户”。为了调用方便给它配一个权限很大的账号。所有查询都从这个账号走所有写入也从这个账号走。业务系统只看到“Agent 做了某个动作”看不到背后是谁发起的。这样做短期很快。但它会带来三个后果。第一原来的数据权限失效了。销售、主管、管理员之间的边界被一个公共账号抹平了。第二责任主体变模糊了。出问题之后你只能看到“Agent 改了数据”却很难回答“谁让它改的”。第三自动化越强风险越大。它不只是查错一条数据而是可能批量查、批量写、批量触发后续流程。所以我更愿意把 Agent 理解成一种执行能力而不是一个新的业务主体。它可以帮人跑流程。但它不能替系统重新定义谁能看什么、谁能改什么。权限边界应该落在哪一层“借来的权限”不能只停在原则上。它至少要落成四个工程设计点。这四个点不是架构装饰。它们分别回答四个问题谁在发起。数据在哪里被挡住。工具到底能做什么。事后能不能追责。第一身份透传。Agent 调用业务系统时必须带上发起人的身份和组织上下文。这不一定意味着底层完全不用技术账号。很多系统为了集成仍然需要服务端凭证。但那个凭证只能承担“技术通道”的角色不能承担“业务授权”的角色。真正决定能看什么、能改什么的仍然应该是发起人。谁发起按谁鉴权。谁批准记谁责任。第二数据边界落在查询层。销售只能看自己客户这件事不能靠 Prompt 写一句“请不要查看其他人的客户”。模型会忘。提示词会被绕过。上下文也可能被拼错。数据边界必须落在查询本身每一次查询天然带上权限过滤每一次列表返回都只返回当前身份能看的数据。换句话说不是让 Agent 先查全量再让它“自觉”过滤。而是系统一开始就不把越界数据给它。我在 CRM Agent 里更倾向于把这类规则写成工具入口的硬边界ALLOWED_ENTITY_SETS { customers, contacts, opportunities, tasks,}def enforce_query_scope(request, scope): entity extract_entity(request.path) if entity not in ALLOWED_ENTITY_SETS: raise PermissionError(entity is not declared in the CRM model) if has_template_placeholder(request.params): raise ValueError(query contains unresolved placeholder) request.params[filter] merge_filter( request.params.get(filter), scope.to_customer_filter(), ) request.params.setdefault(top, 25) return request这段代码背后的思想很简单未知表不让查。占位符没解析不让查。没有数据范围不让查全量。列表查询默认限制返回数量。这些都不是 Prompt 能稳定兜住的事。查询层硬边界第三最小权限。Agent 的权限应该按任务给不按想象给。它这次只需要查客户跟进状态就不要给它修改客户阶段的能力。它这次只需要生成建议就不要给它直接生效的能力。它这次只需要处理一个客户就不要给它批量处理全表的能力。很多风险不是来自“恶意”而是来自“以防万一多给一点”。在传统后台里多给一点权限已经危险。到了 Agent 这里多给一点会被自动化放大。第四全程审计。企业系统最后一定会问四个问题谁发起的Agent 以谁的身份做的它看了什么、改了什么谁批准它继续往下走如果这四个问题答不上来这个 Agent 就还没有真正进入企业系统。因为企业系统不是只要“能跑”还要能追责、能复盘、能回滚。权限设计和上一篇的人工接管在这里连起来了。当动作进入高风险区系统不能只记录“Agent 执行成功”。它还要记录发起人、授权范围、审批人、动作摘要和影响对象。否则一旦出问题所有责任都会混在一个模糊的“智能助手”里。这在企业里是不可接受的。我现在会先问六个问题如果你正在把 Agent 接进业务系统我建议先不要急着设计复杂架构。先把每个工具、每个动作过一遍六个问题。问题 1谁发起这个动作如果系统里只记录“Agent 发起”说明身份设计还不够。问题 2它能看到哪些数据不要回答“理论上能看全部但 Prompt 会限制”。这个答案不合格。要回答具体的组织、团队、客户、订单、审批或任务范围。问题 3谁保证它只能看到这些数据如果答案是模型自己那就还没有边界。真正的答案应该是鉴权层、查询层或业务系统原有的数据权限。问题 4它能写什么查询、生成草案、修改状态、触发外部流程是完全不同的权限等级。不要把它们混成一个“调用工具”的权限。所以工具本身也要有治理元数据。比如一个读取报表证据的能力应该明确告诉系统它是只读的、给哪个业务系统可见、是否需要审批、审计标签是什么。tool( namecollect_report_evidence, governanceToolGovernance( side_effectread, approval_modenever, visible_to_systems(crm,), audit_tags(crm, report, evidence), ),)async def collect_report_evidence(customer_id: str, opportunity_id: str): token await resolve_runtime_app_token() return await evidence_service.collect( customer_idcustomer_id, opportunity_idopportunity_id, access_tokentoken, )这里用系统 token 读取证据并不等于 Agent 拿到了系统的无限权限。真正重要的是系统 token 被包在一个只读工具里工具有可见范围有副作用声明有审计标签。这才是企业系统能接受的“系统能力”。系统 token 被工具治理包住问题 5超过范围时会发生什么是直接失败、进入人工接管还是降级成只读建议这件事要提前写进规则里不能等模型临场判断。问题 6事后怎么查一次完整审计记录至少要能看到发起人、执行身份、动作类型、影响对象、审批信息和结果。这六个问题问完很多 Agent 权限设计里的“方便做法”就会暴露出来。比如给 Agent 一个全量账号方便查询。让 Agent 自己在 Prompt 里记住“不要越权”。把读权限和写权限绑在同一个工具里。只记录动作成功不记录发起人和授权范围。这些做法在 Demo 里很顺在生产里都很危险。真正可上线的设计应该反过来默认没有全量账号。默认按发起人身份鉴权。默认查询层过滤数据。默认读写权限拆开。默认高风险动作进入人工接管。默认每一步都能审计。我真正开始重视这个问题是在做开发态身份切换时。页面上看起来已经切到了销售身份但如果权限链路里还混着真实登录人的管理员角色所有验证都会失真。功能不会报错数据也能返回。但你验证的已经不是销售视角而是管理员视角留下的影子。最后还要用测试把身份边界钉住。我很看重这类回归用例因为权限 bug 往往不是“功能坏了”而是“看起来功能正常但身份混了”。def test_dev_switch_user_should_not_inherit_real_admin_role(): real_login {email: adminexample.com, role: admin} switched_user {id: sales-user-1, role: sales} scope build_scope( login_userreal_login, dev_switched_userswitched_user, debugTrue, ) assert scope.role sales assert scope.user_id sales-user-1 assert adminexample.com not in scope.identity_candidates这个测试防的不是黑客攻击。它防的是开发过程中最常见的权限错觉你以为自己在验证销售身份实际系统还夹带了管理员身份。可以把这一整套设计压缩成一句话Agent 可以走技术通道但业务授权必须回到发起人和原有权限体系。这些规则不会让 Agent 看起来更炫。但它们会让 Agent 像一个能进入企业系统的工程能力。学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%免费】