YAOTU INSIGHTS

PAP协议深度拆解:多Agent协同中的身份、权限与治理实践

PAP协议深度拆解:多Agent协同中的身份、权限与治理实践
最近在折腾多Agent协同的时候我盯上了一件事各家模型和框架都在疯狂堆Agent数量但Agent之间的通信方式却还停留在“你给我发个JSON我给你回个JSON”的裸奔阶段。某头部AI团队低调放出了一套协议名字叫PAPPerson Agent Protocol全称非常直白就是“人-智能体协议”。我花了两周时间在模拟项目X里做了接入和压测这篇文章不聊PPT只聊这套协议到底拆开来看是什么、怎么用、坑在哪。先说结论PAP不是又一个MCP式的工具调用协议它管的是Agent的“身份、权限和对话边界”。如果你正在做多Agent编排、AI工作流、或者企业内部助理类系统这套协议值得仔细看。它解决了一个很实际的问题——当Agent不再是“你的一个函数”而是“一个替你办事的数字员工”时协议层必须有“人”的位置。1. PAP协议的定位与设计思路1.1 没有“人味”的Agent通信是个大问题现在很多Agent系统互相调用本质上就是HTTP请求加一个API Key。两个Agent之间对话A问B要数据B根本不知道对面是谁在操控也不知道这次请求允许做什么。问题在单个Agent里不明显一旦变成十几个Agent协作的复杂系统就会出现三种混乱身份混乱不知道“谁”在发起请求是用户本人、用户授权的Agent还是另一个偷偷跑起来的Agent。权限混乱很多Agent拿到一把很宽泛的钥匙比如能读整个日历那它顺带读个通讯录也就没人发现。审计混乱出事之后你根本没法回答“这个操作到底是哪个Agent在哪条指令链路上做的”。我见过某公司的内部流程自动化项目助理Agent调用报销Agent因为权限模型没做助理Agent居然能直接改报销单金额。这已经不是技术问题是治理问题了。PAP的思路是把“人”这个角色显式地建模进协议里——每个Agent背后都有一个Person用户或者责任人每次通信都必须声明这个Person是谁以及这次会话被授予了哪些权限。1.2 PAP的三层模型把“人”装进协议PAP的核心设计可以拆成三层我习惯叫它“身份层-能力层-会话层”身份层解决“你是谁”的问题。每个Agent和人都有自己的去中心化标识类似DID风格并且人和Agent之间要有可验证的绑定声明。也就是说Agent不能自己声称“我是某某人的助手”必须能拿出一份由那个人的身份私钥签过名的凭证。能力层解决“你能做什么”的问题。每个Agent都会暴露一组能力声明比如“可以读日历”、“可以写待办”但调用之前必须经过策略引擎检查。能力描述不是自由文本是结构化机器可读的方便策略引擎做判断。会话层解决“这次对话的边界在哪”的问题。每次交互都发生在一个有生命周期的会话Session里会话里携带上下文ID、权限集Scope、过期时间。会话一旦关闭所有令牌自动失效。这套设计把“永久授权”改成了“临时会话授权”。以前是Agent拿到一个长期有效的Key现在是每次任务来了临时开一条会话给最小权限用完就销毁。从治理角度看这个思路非常正。1.3 和现有工具协议的关系不是替代是叠加治理很多人一看PAP就问这是不是要替代MCP、Function Calling我实测下来的理解是两者根本不在一个层次。现有工具协议解决的是“Agent怎么调用一个工具”PAP解决的是“Agent怎么在合法的身份和权限框架下被允许调用这个工具”。你可以把PAP理解成一层“外交护照签证系统”MCP理解成“高速公路”。你出国必须带护照签证但开车上的还是高速公路。实际接入时PAP通常作为通信骨架工具调用仍然走原有协议只是外面套了一层身份和策略校验。这个定位意味着如果你的项目已经用某种工具协议接了一堆工具不需要推翻重来只需要在入口处加一层PAP网关做身份验证和策略仲裁就能逐步迁移工程成本可控。2. PAP协议核心机制拆解2.1 可验证身份声明Agent的“数字身份证”PAP里每个参与者都有一个身份标识格式上类似did:pap:agent:{id}或者did:pap:person:{id}。仅有一个标识没有意义关键是必须要有“可验证的绑定关系”。具体机制是这样的一个用户Person在自己的客户端里生成一对公私钥私钥自己持有公钥可以公开。当这个用户想要授权一个Agent替他办事时用户用私钥对一条声明做签名声明内容大致是“我这个Person确认这个Agent从此刻起代表我有效期到某天为止”。签完名的声明就是一份可验证凭证Agent在发起任何请求时必须携带这份凭证。接收方收到请求后会做三件事验签确认这份声明确实是那个Person签的、查状态确认这份凭证没有被吊销、核对身份层级确认这次请求里的“人-代理”关系链完整。任何一个环节失败请求直接拒绝。我在国内某实验室的智能助理项目里做过类似实现最深的体会是所有的身份麻烦都比不过“密钥放哪里”麻烦。服务器端Agent持有用户私钥是方便但泄密等于用户身份被拿走。更稳妥的方案是用硬件安全模块或者操作系统钥匙串托管私钥Agent只拿临时签发的会话令牌不直接碰长期私钥。2.2 会话信封一次对话就是一个受控通道PAP把Agent之间的每一次交互都封装在会话里和“无状态调用”相比多了一层关键的控制能力。一次标准请求长这样{ protocol: pap, version: 0.9.0, session: { id: sess_8f2a1c, created_at: 2025-06-14T08:30:00Z, expires_at: 2025-06-14T08:35:00Z, scope: [calendar:read, calendar:write:own] }, from: did:pap:agent:assistant-01, to: did:pap:agent:calendar-service, delegation: { person: did:pap:person:alice, certificate_ref: vc_20250614_001 }, payload: { intent: list_events, params: {date: 2025-06-14} } }注意几个字段设计的用意expires_at会话必须有过期时间这个不是可选项。我见过有人为了省事把过期时间设成7天结果Agent令牌泄露后整整一周关不掉权限。最合理的做法是过期时间不超过单次任务预估时长的两倍。scope声明这次会话能做什么。策略引擎最终按这个字段来仲裁而Agent实际能调用的工具范围只会小于等于这个scope。delegation这是PAP最关键的部分显式声明背后的人。接收方不仅可以验证Agent身份还能验证“这个Agent确实被这个人授权了”。会话机制带来的一个额外好处是“可撤销”。以前要封禁一个失控Agent只能改配置文件重启服务。有了会话之后直接吊销会话ID所有拿着这个ID的请求立刻失效不需要动Agent本身。2.3 授权级联与人工介入权限只能收缩不能膨胀PAP的授权模型有一个非常值得借鉴的设计权限在做“人→主Agent→子Agent”的链条传递时每一级只能做减法不能做加法。用户授权给主Agent的scope如果包含calendar:read, 主Agent再派发给子Agent的scope只能是calendar:read的子集比如缩小到calendar:read:team-a而绝对不能扩展成calendar:write。这个约束是在协议层面强制的不是靠程序员自觉。我试过故意在子Agent请求里写大权限网关直接返回校验错误这比老式OAuth的模式严格多了。另一个设计是“人工介入点”。对于高风险操作比如“发送邮件”、“修改订单”、“对外付款”PAP策略引擎可以配置成必须回到对应Person那里做二次确认。流程是Agent请求高风险动作 → 网关挂起这个请求 → 向Person推送一条待确认通知 → Person确认后请求才放行。我在项目里第一天就配了“邮件发送必须人工确认”的策略一周内拦下了四次子Agent误触发的群发操作。这个机制对于给Agent上生产环境的人真的能保命。2.4 审计信息整个交互过程可回放PAP协议在信封里强制携带session_id、request_id、delegation信息这些字段不是给程序看的是给审计系统看的。日志系统可以通过这些ID把一次完整操作串起来形成一条链路用户请求 → 主Agent决策 → 子Agent执行 → 工具调用 → 返回结果。有一次我们排查故障定位到一个Agent半夜在调用另一个Agent的导数据接口就是因为策略日志里完整记录了request_id的链路用户A在下午4点启动了周期性任务任务调度器在半夜以用户A的名义发起了数据导出请求。如果没有这套审计字段这种问题很难快速复现。3. 从零接入PAP实操记录3.1 初始化身份和凭证我在模拟项目X里用的是一套开源的PAP参考实现整个接入流程比预期顺畅。第一步是初始化身份pap init --identifier assistant-production \ --key-type ed25519 \ --output ./credentials执行完会生成一对密钥同时生成一个身份标识文件。随后把公钥注册到身份注册中心pap register \ --did did:pap:agent:assistant-production \ --public-key ./credentials/pub.pem \ --resolver https://identity.example.internal注意这里注册的不是简单的“把公钥存一下”注册中心会返回一条“身份注册证明”后面Agent对外通信时对方可以拿这个证明去验证。如果你们公司已经有内部的公钥基础设施PAP身份注册完全可以挂在现有体系上不需要另起炉灶。实操里有个容易忽略的点Agent的私钥文件最好单独用一个服务账号去读不要放在普通业务代码能访问的目录里。我把私钥放到专门的密钥服务后CFT扫描和日志泄露的担子轻了很多。3.2 建立会话与请求响应流程初始化完成后接入方需要实现“建立会话”这个动作。参考实现里提供了Python客户端代码很简洁import pap client pap.PAPClient( identitydid:pap:agent:assistant-production, credential_path./credentials ) # 发现目标Agent的能力 target client.discover(did:pap:agent:calendar-service) print(target.capabilities) # 以Person Alice的授权身份建立会话 session target.connect( persondid:pap:person:alice, scope[calendar:read], ttl300, certificatealice_credential ) resp session.send({ intent: list_events, params: {date: 2025-06-14} }) session.close()这里面scope[calendar:read]的选择很关键它决定了这次会话的权限边界。我一开始图省事把该Agent可能用到的所有权限都写进了scope结果策略引擎每次都是放行虽然功能正常但完全失去了权限控制的意义。后来改成按需申请的最小权限每次任务只申请本任务需要的权限安全性改善非常明显。3.3 策略文件怎么写得稳PAP的策略文件用YAML编写挂在网关上做仲裁。下面是一个我调试了多次才稳定的最小策略示例version: 0.9 name: calendar-policy targets: - did:pap:agent:calendar-service rules: - id: allow-read-own effect: allow actions: [calendar:read] resources: [did:pap:person:alice] condition: time: between: [09:00, 18:00] - id: deny-event-overlap effect: deny actions: [calendar:write] condition: expression: resource.calendar.busy true写策略文件有几点经验规则顺序很重要。策略引擎采用“先匹配拒绝再匹配允许”的顺序会更安全。我踩过坑先写了宽泛的allow后写的deny根本没生效。许多实现里同一条规则冲突时是按顺序先到先得防呆做法是给每个允许规则都加严格的资源限定。condition字段支持时间窗、资源状态判断。我建议至少加一个工作时段限制不要允许Agent在凌晨三点任意改线上数据。策略文件一定要纳入版本管理。我见过直接把网关策略文件改在服务器上、没有任何评审流程的团队那是等着出事。3.4 工程落地的几个配置细节接入过程中有几个参数配置直接影响实际体验列出来供参考配置项推荐值说明会话TTL300秒单次Agent任务内多个调用够用太长容易扩大泄露面凭证有效期24小时配合刷新机制不推荐长期凭证吊销缓存60秒吊销后最多60秒内旧凭证还能用可以接受最大scope数10超过就报警基本能发现Agent权限膨胀的趋势高风险操作二次确认开启写操作类全部开启宁可多一步确认这里推荐“会话TTL300秒”很多人觉得短但Agent在几分钟内完成工具调用链绰绰有余。如果需要跑长任务可以走“会话续期”流程而不是一开始就给很长的时间窗口。4. 踩坑记录常见问题与排查思路4.1 身份校验失败先查时钟接入PAP后我遇到的第一个线上问题是“身份验证签名无效”。代码和配置检查了一遍都没问题最后发现是两台服务器之间的系统时间偏差超过了30秒。PAP的签名里带了时间戳接收方校验时会检查时间窗偏差过大就会判定无效。这个问题的隐蔽性在于不是每次都失败而是一会儿好一会儿坏。解决办法也很简单在所有运行PAP的节点上统一启用时间同步服务并在协议SDK层面对系统时间做启动时检查。我后来养成了习惯凡是Agent身份校验报错第一件事就是看各节点时间差。4.2 权限配置了但不生效另一个高频问题是“策略文件里写了allow但Agent调用还是被拒绝”。排查到最后大部分情况是scope传递出了问题用户给Agent的scope是calendar:read但Agent在子调用时用的scope写成了calendar:read:tmp这个子集在策略引擎里无法匹配任何规则。PAP的scope匹配是精确匹配加前缀匹配不是模糊包含。写策略时最好把自己用的scope清单完整列出来不要想当然。用“最小够用原则”逐条列出每加一个工具调用就补一条策略反而比一次性写一大堆稳定得多。4.3 调试协议的最佳路径PAP协议刚接入时排查问题会比较痛苦因为涉及身份、会话、策略三个层次。我发现最好用的调试手段是“结构化回放”把一次失败的请求完整打印出来包括信封头、scope、证书引用然后逐层检查。另外大多数PAP实现都有pap debug命令可以模拟一次请求做本地校验。我在网关前部署了这个工具每次策略调整后先跑一遍本地校验确认没有问题再同步线上基本把“改了策略反而搞挂服务”的概率降到了零。4.4 几个值得记下来的经验踩过几次坑之后我总结了几条感受会话凭证不要写死在配置文件里用动态签发、动态刷新的方式。Agent越多权限膨胀越快要定期做“最小权限审计”看看哪些Agent实际持有的权限超过了日常工作所需。线上环境记录策略变更日志每次改动要能追溯到人和时间。多Agent协作场景里每个Agent尽量用独立身份不要共用一个服务账号否则出了问题很难界定责任。5. PAP协议带来的连锁反应5.1 多Agent协作的秩序问题如果Agent生态继续野蛮生长我觉得协议层迟早会成为比模型能力更关键的基础设施。PAP这类协议把“身份、权限、会话、审计”四件套做成标准后多Agent协作才真正谈得上“有秩序”。我之前设计多Agent系统的时候最头疼的不是Agent不会干活而是不敢让它们互相能调用。一旦允许A调用B你就必须回答A能对B做什么、有效期多久、出事怎么追溯到源头这些麻烦问题。PAP相当于把“能调用”和“有权限调用”拆开系统设计清晰很多。5.2 我们项目里的实际变化模拟项目X接入PAP后最大的变化不是性能而是安全审查效率。以前每周做权限复核要翻一堆日志现在直接在策略台账上按Agent查已经授予的scope一眼就能看出谁权限过大。另一个变化是跨团队协作容易了两个团队各自维护自己的Agent只要双方都暴露了标准的PAP接口不需要互相给对方开数据库账号也不需要共享密钥各自签发的身份凭证就能建立信任关系。5.3 后续值得关注的方向我个人比较关注三个方向一是PAP与现有云平台身份体系的融合如果和单点登录打通企业接入成本会大幅下降二是跨组织Agent通信的可信市场未来也许会出现“Agent按身份互相开放能力”的生态三是协议对“人机协作回路”的支持深度目前的人为确认机制还比较粗粒度更细腻的人工介入方式值得期待。最后分享一个我实际操作中的体会协议刚出来的时候很多人纠结“要不要等生态成熟了再上”。我的建议是先在内部小范围试一个非核心链路把身份签发、会话、策略这三条基本链路跑通一遍比讨论十遍架构都管用。PAP这样偏“治理”的协议越早引入后面需要重构的地方就越少等Agent规模大了再补这层才是真正的伤筋动骨。