先讲一个真事。
去年夏天,朋友所在的公司上线了一款办公Agent,能干不少事:帮人发消息、拉群、改文档权限、甚至自动审批请假。上线第一周,大家直呼“解放了”。
第二周的周三下午,出了个不大不小的事故。
一名运营同事在群里对Agent说:“帮我清理一下上周的临时文件夹。”
Agent理解成了:删除整个团队共享盘的“历史归档”目录。
三秒钟后,三个月的项目资料从网盘里消失了。幸好有备份,但恢复花了四个小时,全组骂娘。
事后复盘发现:这个Agent用的token拥有网盘的“全部读写删除”权限,而且没有任何操作需要二次确认。更离谱的是,没有人知道谁在什么时候让它干过这件事——因为压根没有审计日志。
朋友苦笑:“我们造的哪里是Agent,分明是一个没有刹车和行车记录仪的玩具。”
这个故事就是今天这篇文章的起点。我会用一个真实的工程视角,告诉你怎么给办公Agent装上“刹车”和“黑匣子”——不堆理论,只讲我踩过的坑和填坑的方案。
一、从“什么都能干”到“只能干该干的”:权限管理三原则
为什么很多办公Agent刚上线很爽,两周后就开始闯祸?因为初始设计时,我们总想“先跑起来再说”,给Agent的API token往往是一把万能钥匙。
想要避开“玩具陷阱”,第一条铁律就是:默认拒绝,按需授权。
1.1 最小权限原则:只能读,不能写;只能写自己的,不能写别人的
我维护的办公Agent目前连接了七个系统:飞书、网盘、GitLab、Jira、HR系统、审批系统、知识库。给每个系统的权限都是单独申请的,遵循这张表:
系统 需要的最小权限 坚决不给的权限
飞书 发送消息、读取@我的消息、创建任务 删除消息、修改群成员、读取所有私聊
网盘 读取指定目录、上传文件到指定临时目录 删除、移动、修改他人文件
Jira 创建任务、添加评论、读取指派给我的任务 删除任务、修改状态、编辑他人任务
审批系统 读取待审批单、返回初审结果(通过/驳回) 直接批准、跳过终审、修改金额
举个例子:审批Agent看到一张报销单,它可以标注“格式校验通过”或“发票金额不符”,但最终批准按钮必须由真实的人点击。Agent只做建议,不做决策。
这就是“最小权限”在业务层面的落地:Agent可以替人跑腿,但不能替人签字。
1.2 角色分离:不同部门的Agent穿不同颜色的“马甲”
我们早期犯过一个错误:全公司共享一个Agent账号。销售的Agent能看HR的工资表吗?不能,但当时的技术实现就是不能——因为用的是同一个token。
后来我们把Agent拆成了三个“分身”:
通用助手:只能读公共知识库、发公告、拉会议
职能助理:可访问HR/财务系统,但只能操作与自己部门相关的单据
研发助理:可访问Git、Jira、流水线,但无权修改生产配置
每个分身用独立的服务账号,权限互斥。销售在群里@通用助手问“我这个月提成怎么算”,通用助手会回复:“请咨询HR助理。”——这不是敷衍,是权限隔离的必然结果。
1.3 临时提权 + 双人确认:让Agent做危险的“大事”前必须请示
有些操作无法提前预知权限范围,比如“帮我把今天所有新上传的合同归档到对应客户文件夹”。这需要Agent临时拥有写权限。
我们的方案是:临时提权 + 人工确认。
流程如下:
Agent收到指令,识别出需要的权限超出当前范围。
Agent向安全管理员(一个固定的审批群)发送请求:“张三申请Agent执行合同归档操作,涉及文件数23个,申请临时写权限30分钟”。
至少两名审批人在群里回复“同意”,Agent才继续执行。
操作完成后,权限自动收回,并生成一条高等级审计日志。
这个机制看起来很啰嗦,但实际使用中触发频率很低(一周不到两次)。而它避免过一次真实事故:有人企图让Agent批量修改所有人的绩效分数——因为需要临时提权+双人确认,请求被拦截了。
二、没有日志等于没做:审计日志到底要记什么?
回到开头的故事,那个删文件的Agent之所以成为“玩具”,是因为连谁、在什么时间、让它干了什么都查不到。
一个合格的办公Agent,审计日志至少要包含五个维度:
Who:谁发起的指令(用户ID+真实姓名)
What:Agent执行了什么操作(API名称+关键参数)
When:精确到毫秒的时间戳
Where:哪个Agent实例、哪个IP、哪个会话
Result:操作成功/失败,失败原因,返回了什么数据
我们用的日志格式(实际简化版):
{
"timestamp": "2025-05-08T14:23:11.342Z",
"user": "zhang.wei@company.com",
"session_id": "sess_abc123",
"action": "file.delete",
"target": "/shared/archive/2024",
"agent_decision": "request_permission",
"result": "denied_need_dual_approval",
"trace_id": "trace_xyz789"
}
我强调两条最容易忽略的:session_id 和 trace_id。没有它们,你无法把“用户说的一句话”和“背后调用的5次API”串联起来。
2.1 存哪儿?怎么存不被改?
我们试过三种方案:
普通数据库表(MySQL)—— 管理员可以随意删改行,pass。
只读数据库账号 + 应用层禁止更新 —— 仍能让DBA直接改,不够。
外部日志系统(如阿里云SLS/AWS CloudTrail)+ 写后不可变 —— 最终选了这个。
关键设计:Agent没有任何删除或修改日志的API。日志一经写入,只能追加,不能回溯编辑。哪怕你是系统管理员,想删一条日志也必须走云平台的审计通道,而那又会生成新的审计日志。
这就形成了一个闭环:没人能悄无声息地抹掉Agent的作案记录。
2.2 日志不是越多越好,但要“够破案”
初期我们犯了另一个极端:什么鸡毛蒜皮都记。Agent每收到一条消息、每做一次embedding、每调一次prompt,全写日志。结果一周产生100GB,查询慢得要死,真正要找问题的时候却找不到关键字段。
后来的优化:
只记录“对外操作”:调用第三方API、发消息、改文档、创建任务、访问敏感数据。
不记录“内部计算”:prompt组装、向量检索、模型推理过程。
敏感字段脱敏:日志里如果有人名、工号、金额,自动替换为[REDACTED],原始数据单独加密存储。
破案测试:如果一个用户投诉“Agent把我的报销单驳回了,但我的发票没问题”,你能不能在5分钟内找出当时Agent看到了什么、为什么驳回?如果日志里没有当时的发票校验结果,就破不了案。所以我们专门记了audit.attachments_hash和validation_rules_failed。
三、三个躲不过的“坑”以及怎么填
下面这三个坑,几乎每个做办公Agent的团队都会踩。我直接把填坑方案给你。
坑1:权限缓存导致的“越权”
现象:用户A让Agent读取了文件X,当时A有权限。后来A被移出了项目组,但Agent因为缓存了A的token,依然能读X。
填坑方案:短期token + 实时鉴权,不信任任何缓存。每次操作前,Agent重新调用权限系统的接口问一下:“当前用户还有没有这个权限?”缓存只做性能优化,有效期不超过30秒。
坑2:日志太大,一查就超时
现象:你要查上个月的某次异常操作,结果几十亿条日志,你的查询跑了三分钟超时了。
填坑方案:分层存储 + 预聚合。
热数据(7天内):存ES或ClickHouse,秒级查询。
冷数据(7天以上):压缩后存对象存储,但定期生成摘要日志——按用户、按动作、按失败率做成统计表。日常排查先用摘要定位大致时间范围,再去冷存储拉详情。
坑3:用户把Agent的指令通道当作“玩笑场”
现象:有人对Agent说“帮我删掉老板的文档”,Agent回复“权限不足”。这人连续说了十几次,Agent每次都试图执行,虽然没有成功,但生成了大量无效日志和权限请求,干扰正常审计。
填坑方案:对触发“高危意图”但连续失败的会话,自动降级。同一个session内,如果用户连续触发3次权限不足的高危操作,Agent进入“静默模式”并通知安全员,不再尝试执行,只回复:“该操作需要更高权限,已记录本次请求。”
四、一个完整的“刹车+黑匣子”流程演示
让我用一个真实场景把上面所有的点串起来。
场景:销售经理李丽对办公Agent说:“帮我把合同CA-2025-001的附件移动到客户的专属文件夹。”
系统内部发生的事:
身份识别:Agent从会话中拿到李丽的user_id,查得她的部门是销售部、角色是经理。
意图解析:识别出动作=移动文件,源文件=/合同库/CA-2025-001/附件,目标=/客户/A公司/资料。
权限校验:
李丽对源文件有“读”权限(合同库所有人可读),对目标文件夹有“写”权限吗?
权限系统返回:销售经理可以对“客户文件夹”写入,但移动操作属于高风险(等同于删除源文件)。
临场决策:Agent配置的规则是“移动文件属于高危操作,需要二次确认”。
Agent生成一条待确认消息:“是否确认将附件从原位置移动到客户文件夹?[确认] [取消]”
李丽点击确认。
执行与日志:
执行移动API。
立即写入审计日志:user=李丽, action=file.move, source=合同库/..., target=客户/..., risk=high, confirm_method=user_click, result=success, trace_id=...
事后可查:三周后财务审计问“为什么合同附件不在原位置了?”安全员输入李丽的名字和时间范围,在审计系统里2秒钟定位到那条移动记录,附带了李丽的确认截图(二次确认时的界面快照)。
整个过程,Agent既完成了工作,又没造成失控,还留下了完整证据链。
五、总结:避开“玩具陷阱”的四条铁律
如果你只记住四句话,那就是:
权限不是越多越好,而是越少越好。Agent能读的绝不让他写,能写的绝不让他删。每一次“写”操作都要有业务理由和可追溯性。
高危操作必须二次确认,甚至双人确认。Agent可以提醒、可以建议,但别让它扣扳机。
审计日志是最后的防线,不能被攻破。不可变存储、全链路追踪、敏感字段脱敏,三者缺一不可。
永远假设Agent会犯错。你的权限和日志设计,要能回答三个问题:谁干的?干了什么?能恢复吗?
回到开头那个删文件的“玩具Agent”。其实后来朋友把它重写了,加入了上面说的所有机制。最近一次我再问他,他说:“现在Agent权限小了很多,能干的事少了,但再也没出过事。团队反而更敢用它了。”
你看,真正的生产力工具,不是功能最强的那个,而是让人放心的那个。
如果你的办公Agent还处在“想删就删、想发就发、没人知道”的阶段,不妨从这个周末开始,给它装上刹车和行车记录仪。你会发现:少一些“无所不能”,多一些“靠谱可控”,才是最值钱的工程实践。