
最近在做一个多团队共用的 AI Agent 平台时遇到了一个非常典型的需求多个业务团队都希望复用同一个 Agent 能力但每个团队的账号体系、数据范围和操作权限又完全不同。最开始我们让所有团队直接共享同一个 Agent 服务结果很快暴露出配置互相覆盖、日志串租户、误操作等问题改成每个团队独立部署之后又带来资源浪费和版本不一致。直到把“共享 Agent 独立权限”作为设计原则重新落地问题才真正解决。本文将围绕 AgentConnect 这一类共享 Agent 系统的核心设计展开完整拆解“Agent 复用”与“权限隔离”并存时的架构方案、权限模型、数据库设计、核心代码和排错思路。无论你是准备自建多租户 Agent 平台还是想把现有单机 Agent 改造成可共享、可控权的服务这篇文章都能直接复用。1. AgentConnect 是什么共享 Agent 与独立权限的矛盾1.1 从单体 Agent 到共享 Agent在项目早期每个团队的 Agent 都是独立开发的比如销售团队有一个客户画像 Agent运维团队有一个日志分析 Agent客服团队有一个工单分类 Agent。这些 Agent 内部有不少逻辑是重复的比如都依赖同一个大模型接口、都做了相似的工具调用封装、都要处理相似的文件上传需求。后来我们开始把这些 Agent 收敛成公共能力让不同团队按需调用。这个阶段出现了一个新的问题Agent 是公共的但调用方是不同团队权限不能是公共的。如果一个 Agent 只服务一个团队权限模型非常简单“谁能调用就登录谁”。但共享之后“谁能查看这个 Agent”“谁能调用它”“谁能修改它的 prompt 和模型参数”“谁能把它停掉”就是完全不同的几件事了。AgentConnect 这个名字背后本质上就是解决“Agent 连接起来”之后“权限怎么分开管”的问题。1.2 “共享”与“隔离”并不冲突很多人听到“共享”和“独立权限”第一反应是矛盾。实际设计完成后就会发现这两者并不冲突关键是怎么划分边界。共享的是 Agent 的定义和运行时能力隔离的是每个租户对 Agent 的可见性、调用权、配置权以及运行时数据。换句话说Agent 的 prompt 模板、工具列表、模型配置可以复用每个租户只能看到自己被授权的 Agent每个租户调用 Agent 时输入、输出、会话数据必须互相隔离每个租户对 Agent 的修改权限需要单独控制不能因为 A 团队改了配置B 团队也被影响。这个模型在业界并不新鲜本质上就是多租户架构在 Agent 场景下的落地。但 Agent 场景比普通 Web 服务更复杂的地方在于Agent 是一个有状态、有自主动作、可能调用外部工具的执行单元。权限控制不仅要管“能不能访问接口”还要管“这个 Agent 在被调用时能不能动当前租户的数据”。1.3 本文的适用范围如果你正在做以下事情本文的内容会比较合适把内部多个 Agent 统一成共享服务供多个团队调用设计面向外部客户的多租户 Agent 平台在现有 Agent 框架上增加权限校验和审计能力排查 Agent 被越权调用、配置串改、日志泄露等安全问题。其中涉及的具体实现本文会用一个 FastAPI SQL 的示例来讲清楚核心思路。不同项目使用的框架、模型、基础设施可能不一样但“共享 Agent 独立权限”的设计模式是通用的。2. 权限模型先从设计上把边界划清楚2.1 租户、用户、角色三层模型共享 Agent 的权限设计第一步是要确定主体是谁。在大多数情况下直接用“用户 ID”来做授权粒度太细会导致权限表爆炸只用“团队”又太粗同一个团队内部不同角色也应该有不同操作权限。更合理的做法是拆成三层层级作用示例租户Tenant资源隔离的边界销售团队、运维团队、外部客户 A用户User实际发起请求的人张三、李四角色Role同一租户内部的操作分组访客、调用者、管理员在共享 Agent 场景里租户是最重要的授权单位。一个 Agent 的所有权归属某个租户其他租户通过授权记录获得访问权。用户通过自己所属的租户拿到对应权限再由角色决定能执行哪些操作。2.2 Agent 的四个权限维度对 Agent 的操作建议至少划分成四个独立维度不要把权限做成一个粗粒度的“可读 / 可写”。权限说明影响范围view是否能查看 Agent 的基本信息和配置影响信息可见性invoke是否能调用 Agent 执行任务影响资源消耗和业务动作configure是否能修改 prompt、参数、工具配置影响 Agent 行为manage是否能创建、删除、授权 Agent影响 Agent 生命周期这四个权限维度应该有清晰的依赖关系。比如一个租户能够 configure那么至少应该先具备 view 权限能够 manage原则上也应当具备其余所有权限。依赖关系可以在代码里显式校验避免出现“不能查看却可以修改”这种奇怪状态。2.3 运行时数据隔离权限模型还涉及一个容易被忽略的部分Agent 运行时的数据隔离。即使两个租户都有某个 Agent 的 invoke 权限他们在调用时产生的会话记录、上下文、知识库检索范围、工具调用结果也必须按租户隔离。比如说运维团队的日志分析 Agent 被销售团队调用销售团队只能查询自己有权访问的数据不能通过同一个 Agent 看到运维团队的服务器的日志内容。因此在实际实现中租户 ID 不能只用于第一层接口鉴权还要透传到 Agent 执行链路里。Agent 在执行过程中连接数据库、调用内部系统、查询知识库时都需要携带租户上下文由下游系统二次校验。这属于纵深防御的一部分光是网关层校验是远远不够的。3. 整体架构拆解3.1 核心组件一个完整的“共享 Agent 独立权限”系统通常由以下几个组件组成。Agent 网关Gateway所有对 Agent 的调用请求都从网关进入。网关负责识别租户身份、解析用户令牌、做基础权限校验同时承担限流和审计日志采集。网关层不应该写业务逻辑只负责“这个请求能不能进来”。Agent 注册中心Registry维护 Agent 的元数据包括 Agent 名称、描述、所属租户、prompt 模板、模型配置、工具列表、是否共享等。注册中心是配置的权威来源Agent 的新增、下线、版本更新都在这里管理。权限服务Permission Service独立的权限校验服务提供“某个租户对某个 Agent 是否具备某项权限”的查询能力。把权限逻辑从 Agent 执行引擎里拆出来可以保证多个入口的权限口径一致。Agent 执行引擎Execution Engine真正执行 Agent 任务的地方。它从注册中心读取配置向大模型发起请求编排工具调用最终生成结果。执行引擎需要接收并向下游透传租户上下文。审计服务Audit Service记录谁在什么时间、以什么租户身份、对哪个 Agent 执行了什么操作、结果如何。审计日志在出现安全事件、权限争议、配置回滚时至关重要。3.2 一次请求的完整链路下面用一个普通调用场景说明这些组件如何协作用户登录后获得一个携带用户 ID 和租户 ID 的令牌用户调用网关接口请求中携带令牌和要调用的 Agent ID网关解析令牌确认租户身份网关向权限服务查询“该租户是否具备该 Agent 的 invoke 权限”权限校验通过后网关将请求转发给执行引擎执行引擎根据 Agent ID 从注册中心加载配置执行任务执行过程中所有下游调用都携带租户 ID做数据范围控制调用结束后执行引擎返回结果网关记录审计日志。这条链路的核心原则是权限校验前置租户上下文贯穿全程。任何一步缺失都可能出现越权或者数据串租户的问题。4. 实战实现一个带独立权限的共享 Agent 服务下面我们用 Python 和 FastAPI 实现一个最小可运行的示例。这个示例不依赖真实的大模型接口重点演示权限模型、接口设计和数据隔离思路。4.1 环境与项目结构示例环境如下版本可根据实际情况调整Python 3.10FastAPI 0.100uvicorn 0.23项目结构建议这样组织agent-connect-demo/ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── models.py │ ├── permissions.py │ └── agent_engine.py ├── schema.sql └── requirements.txt先创建依赖文件fastapi uvicorn pydantic保存为requirements.txt然后执行pip install -r requirements.txt4.2 数据库表设计权限有关的表建议至少设计三张租户表、Agent 表、Agent 授权表。示例 SQL 如下-- schema.sql CREATE TABLE tenant ( tenant_id VARCHAR(64) PRIMARY KEY, tenant_name VARCHAR(128) NOT NULL, status TINYINT DEFAULT 1 COMMENT 1:启用 0:停用 ); CREATE TABLE agent ( agent_id VARCHAR(64) PRIMARY KEY, agent_name VARCHAR(128) NOT NULL, owner_tenant VARCHAR(64) NOT NULL, description TEXT, config_json TEXT COMMENT 存储模型配置、prompt模板等信息, shared TINYINT DEFAULT 1 COMMENT 1:共享 0:私有, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); CREATE TABLE agent_permission ( id BIGINT AUTO_INCREMENT PRIMARY KEY, agent_id VARCHAR(64) NOT NULL, tenant_id VARCHAR(64) NOT NULL, can_view TINYINT DEFAULT 0, can_invoke TINYINT DEFAULT 0, can_configure TINYINT DEFAULT 0, can_manage TINYINT DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_agent_tenant (agent_id, tenant_id) ) COMMENT Agent按租户的授权记录;这里的关键设计是agent_permission表把 Agent 和租户关联起来每一行代表“某个租户对某个 Agent 有哪些权限”。owner_tenant字段表示 Agent 的归属租户归属租户天然拥有全部权限不需要额外授权记录。4.3 权限模型核心代码先定义一个权限枚举和数据类用于统一管理权限类型# app/models.py from dataclasses import dataclass, field from enum import Enum class Permission(str, Enum): VIEW view INVOKE invoke CONFIGURE configure MANAGE manage dataclass class AgentInfo: agent_id: str agent_name: str owner_tenant: str shared: bool config: dict field(default_factorydict)接下来实现权限校验函数。这个函数会同时处理两种情况当前租户是 Agent 的归属方默认拥有全部权限当前租户不是归属方需要查授权记录。# app/permissions.py from fastapi import HTTPException from models import Permission def check_permission( agent_id: str, tenant_id: str, required: Permission, agent_store: dict, ) - None: 检查 tenant_id 是否对 agent_id 具备 required 权限。 校验失败时抛出 403由 FastAPI 统一转为 HTTP 响应。 if agent_id not in agent_store: raise HTTPException(status_code404, detailAgent not found) agent agent_store[agent_id] # 归属租户拥有全部权限 if agent[owner_tenant] tenant_id: return # 私有 Agent 不允许其他租户访问 if not agent[shared]: raise HTTPException( status_code403, detailAgent is not shared, ) # 查询该租户被授予的权限列表 grants agent.get(grants, {}).get(tenant_id, []) if required.value not in grants: raise HTTPException( status_code403, detailfTenant {tenant_id} has no {required.value} permission, )这个函数把“归属方优先”和“授权校验”两个逻辑放在一起调用方只需要传入 Agent ID、租户 ID 和所需权限就能得到一致的校验结果。在实际项目中agent_store应该替换成数据库查询这里用内存结构方便演示。4.4 Agent 调用 API接着实现 FastAPI 入口和两个典型接口查询 Agent 信息、调用 Agent。# app/main.py from fastapi import FastAPI, Header, HTTPException from agent_engine import run_agent from models import Permission from permissions import check_permission app FastAPI(titleAgentConnect Demo) # 模拟数据实际项目中从数据库加载 AGENT_STORE { agent_001: { owner_tenant: t_platform, shared: True, config: {model: gpt-4o-mini, prompt: 你是数据分析助手}, grants: { t_sales: [view, invoke], t_ops: [view, invoke, configure], }, }, agent_002: { owner_tenant: t_ops, shared: False, config: {model: gpt-4o-mini, prompt: 你是日志分析助手}, grants: {}, }, } app.get(/agents/{agent_id}) def get_agent( agent_id: str, x_tenant_id: str Header(..., description租户ID), ): 查询 Agent 基本信息需要 view 权限。 check_permission( agent_idagent_id, tenant_idx_tenant_id, requiredPermission.VIEW, agent_storeAGENT_STORE, ) agent AGENT_STORE[agent_id] # 只返回可视字段不返回完整授权表 return { agent_id: agent_id, agent_name: agent[config][prompt], shared: agent[shared], config: agent[config], } app.post(/agents/{agent_id}/invoke) def invoke_agent( agent_id: str, x_tenant_id: str Header(..., description租户ID), user_input: str , ): 调用 Agent 执行任务需要 invoke 权限。 check_permission( agent_idagent_id, tenant_idx_tenant_id, requiredPermission.INVOKE, agent_storeAGENT_STORE, ) agent AGENT_STORE[agent_id] result run_agent(agent[config], user_input, tenant_idx_tenant_id) return {agent_id: agent_id, result: result}执行引擎这里做一个简化实现真实项目中这里会接大模型接口、工具调用和上下文管理# app/agent_engine.py def run_agent(config: dict, user_input: str, tenant_id: str) - str: 简化版的 Agent 执行引擎。 真实场景中这里会 1. 加载租户自己的私有数据和知识库 2. 调用大模型接口生成回复 3. 执行工具调用 4. 把所有下游访问都限制在 tenant_id 范围内。 prompt config.get(prompt, ) # 仅在演示中直接拼接返回真实项目不要这样做 return f[{tenant_id}] {prompt} | 收到消息: {user_input}4.5 运行与验证启动服务uvicorn app.main:app --reload --port 8000然后用 curl 验证权限效果。场景一t_sales租户查询agent_001预期返回 200curl -s -H X-Tenant-Id: t_sales \ http://localhost:8000/agents/agent_001场景二没有授权的t_finance租户查询agent_001预期返回 403curl -s -H X-Tenant-Id: t_finance \ http://localhost:8000/agents/agent_001预期响应{detail: Tenant t_finance has no view permission}场景三t_sales租户调用agent_001预期返回 200curl -s -X POST \ -H X-Tenant-Id: t_sales \ -d user_input本周销售数据如何 \ http://localhost:8000/agents/agent_001/invoke预期响应{ agent_id: agent_001, result: [t_sales] 你是数据分析助手 | 收到消息: 本周销售数据如何 }这个示例虽然简单但已经覆盖了核心链路租户身份识别、权限查询、越权拒绝、租户上下文透传。在此基础上把内存数据结构换成数据库查询、把模拟执行换成真实模型调用就是一个可以投入内部使用的共享 Agent 服务雏形。5. 常见问题与排查思路5.1 常见错误汇总在实际开发中以下问题出现的频率最高问题现象常见原因解决思路调用接口返回 403租户 ID 缺失、授权记录未配置、权限维度判断错误检查请求头是否携带租户 ID确认该租户在授权表中的权限有 invoke 权限但调用报错下游数据源未做租户隔离或执行引擎没有透传租户上下文检查执行引擎传递给下游服务的租户参数A 团队修改配置后 B 团队也受影响Agent 配置全局共享没有按租户做配置版本隔离引入 Agent 版本概念或为需要独立配置的租户创建私有副本日志和审计记录里的租户信息为空网关解析了租户但没有写入日志上下文在日志框架中把租户 ID 加入 MDC 或上下文对象授权表数据量增长过快按用户而非按租户记录权限改为“租户 角色”的授权模型私有 Agent 被其他租户访问查询时漏掉了 shared 字段校验访问 Agent 的统一入口必须强制检查 shared 状态5.2 定位权限问题的排查清单如果你收到的反馈是“某个团队无法调用某个 Agent”建议按下面的顺序排查确认调用方请求头里的租户 ID 是否正确确认该 Agent 在agent_permission表里是否有对应的授权记录确认授权记录里can_invoke是否为 1确认 Agent 的owner_tenant是否是当前租户归属租户走的是默认放行逻辑确认shared字段没有被误改成 0查看审计日志确认权限服务实际返回的校验结果如果权限服务有缓存确认缓存是否过期或未刷新。这套排查顺序基本覆盖了从接口入口到数据库记录的完整链路大多数权限问题都能在两步之内定位。6. 最佳实践与生产环境建议6.1 遵循最小权限原则共享 Agent 的授权粒度越细安全风险越低。默认情况下新接入的租户不应该自动获得任何权限而是通过明确的授权流程按实际业务需要分配 view 和 invoke 权限。configure 和 manage 权限只能授予运维或平台管理员级别的角色普通业务团队原则上不建议开放。如果发现某个租户长期只使用 Agent 的查询能力可以把它的权限收敛为 view减少误操作导致配置变更的概率。6.2 配置变更必须可追溯、可回滚Agent 的 prompt、模型参数、工具列表属于高度敏感配置。生产环境中建议对 Agent 配置做版本化管理每次变更生成一个新版本号发布前可以预览发布后可以快速回滚到上一个版本。同时配置变更要按租户区分。如果只是某个租户需要调整参数应该先判断是否会影响其他租户。共享 Agent 的全局配置变更建议走灰度发布流程先让内部测试租户验证再逐步扩大范围。6.3 密钥与敏感信息隔离共享 Agent 意味着多个租户共用一个执行引擎但绝不意味着多个租户共用同一套密钥。每个租户的大模型 API Key、数据库密码、对象存储凭证都应该独立管理存储在专门的密钥管理服务中。执行引擎在调用外部资源时只加载当前租户的密钥不允许跨租户读取。这个原则需要在代码评审时重点检查避免出现“执行引擎全局加载一份配置”的隐患。6.4 全链路审计审计日志是权限系统最后的兜底防线。建议至少记录以下内容谁在什么时间发起了请求请求来自哪个租户、哪个用户调用的是哪个 Agent请求参数和响应摘要权限校验结果通过或被拒绝如果涉及配置修改记录修改前后的值。审计数据要保留足够长的时间并设置独立的访问权限。平时可能用不到但出现权限争议或安全事件时这些日志是定位问题的关键证据。6.5 限流与资源配额共享 Agent 被多个租户调用后单一租户的突发流量可能影响其他租户。建议在网关层为每个租户设置独立的调用限流和资源配额例如每分钟最多调用次数、每日最大 token 消耗量、最大并发数等。这样既能避免单点故障也能防止某个租户因为写错代码而拖垮整个 Agent 服务。6.6 对外暴露时的安全边界如果共享 Agent 服务需要对外部客户开放需要额外关注以下边界使用短期有效的访问令牌避免长期凭证泄露对下游系统调用做二次鉴权不仅依赖网关传来的租户 ID对 Agent 能够访问的数据范围做白名单限制对 Agent 的工具执行能力做约束禁止执行危险操作所有外部请求必须经过统一的协议转换和安全插件不能绕过网关直达执行引擎。7. 总结与下一步Agent 共享化是团队协作效率提升的必然方向但“共享”不能以牺牲安全边界为代价。本文围绕 AgentConnect 所代表的“共享 Agent 独立权限”模式完整覆盖了权限模型设计、系统架构拆解、数据库表设计、核心代码实现和排错思路。读完本文你应该已经掌握为什么共享 Agent 必须按租户隔离权限如何设计 view、invoke、configure、manage 四个权限维度权限校验如何与 Agent 调用链路结合数据库授权表如何设计归属方与授权方的逻辑如何区分生产环境中共享 Agent 的安全、审计、限流、配置管理注意事项。下一步建议先在自己的项目里跑通最小示例把内存数据替换成数据库把模拟执行引擎替换成真实模型调用。然后再逐步补充审计日志、配置版本管理和租户级限流。每一步都好验证、好回滚比一开始就追求大而全更稳妥。如果你在落地过程中遇到类似的权限问题欢迎在评论区留言一起讨论具体的排查思路。