Agent 可靠性工程实战(二):把工具调用从“模型想做”变成“宿主允许做”
📅 2026/7/30 15:57:31
👁️ 次浏览
本篇直接复用上一篇的Ledger.append()、load_events()与runs/demo-001/events.jsonl。上一篇最后一条model_proposed事件就是本篇授权器的输入本篇新增tools.json和policy.py输出tool_allowed或tool_denied事件。模型只描述意图真正的文件路径解析与权限判断由宿主完成。一、工具声明不是权限把read_file的 JSON Schema 发给模型只代表模型知道怎样构造参数不代表它获得了读取任意文件的能力。如果宿主直接执行模型给出的路径../../.ssh/id_rsa、符号链接和绝对路径都可能越出工作区。安全边界必须位于模型无法修改的确定性代码里。tools.json用数据描述每个工具的操作类别、允许根目录和单次输出上限。策略默认拒绝名称不存在、参数缺失、路径越界或操作类别不匹配都会产生明确原因码。原因码比自然语言稳定后续统计和回放不会因翻译变化而失效。{schema_version:1,tools:{read_file:{operation:read,roots:[workspace/src,workspace/tests],max_bytes:65536},run_tests:{operation:execute,commands:[[python,-m,unittest]]}}}运行输出loaded_tools2 schema_version1下面的路径判断先做词法拒绝再解析真实路径最后用relative_to验证所属关系。只用字符串前缀会把/work/app-copy误判成/work/app的子目录只删除..又挡不住指向外部的符号链接。from__future__importannotationsimportjsonfromdataclassesimportdataclassfrompathlibimportPathfromtypingimportAnyfromledgerimportLedger,load_eventsdataclass(frozenTrue)classDecision:allowed:boolreason:strnormalized:dict[str,Any]definside(path:Path,root:Path)-bool:try:path.relative_to(root)returnTrueexceptValueError:returnFalsedefauthorize(call:dict[str,Any],manifest:dict,project:Path)-Decision:specmanifest[tools].get(call.get(tool))ifspecisNone:returnDecision(False,unknown_tool,{})ifspec[operation]read:rawcall.get(path)ifnotisinstance(raw,str)orPath(raw).is_absolute():returnDecision(False,invalid_path,{})candidate(project/raw).resolve()roots[(project/root).resolve()forrootinspec[roots]]ifnotany(inside(candidate,root)forrootinroots):returnDecision(False,outside_roots,{path:str(candidate)})returnDecision(True,allowed,{path:str(candidate),max_bytes:spec[max_bytes]})returnDecision(False,unsupported_operation,{})defmain()-int:events_pathPath(runs/demo-001/events.jsonl)proposedload_events(events_path)[-1][payload]manifestjson.loads(Path(tools.json).read_text(encodingutf-8))decisionauthorize(proposed,manifest,Path.cwd())Ledger(events_path,demo-001).append(tool_allowedifdecision.allowedelsetool_denied,{reason:decision.reason,**decision.normalized},)print(fallowed{decision.allowed}reason{decision.reason})return0if__name____main__:raiseSystemExit(main())运行输出allowedTrue reasonallowed二、为什么规范化必须发生在执行前权限判断若针对原始字符串执行时再解析路径两阶段看到的可能不是同一个对象。攻击者可以让符号链接在判断后指向另一个位置这叫检查与使用之间的竞态。对高风险写操作仅靠resolve()仍不够需要使用支持目录文件描述符的系统调用、打开后核验 inode或把执行放进只挂载允许目录的隔离环境。本系列先把读工具限制在项目内并把规范化后的绝对路径写入授权事件。执行器只能消费授权事件里的路径不能重新使用模型原参数。记忆点是裁决输入可以来自模型执行输入必须来自裁决结果。两者看似重复实际切断了“审的是 A做的是 B”。三、拒绝也是正常控制流工具被拒绝不应抛出含糊的内部异常也不该自动把权限扩大后重试。宿主把outside_roots连同允许根目录反馈给下一轮模型可以选择合规路径。连续拒绝会消耗预算防止模型无限探测目录。不存在的文件与无权访问也应使用不同原因码前者可能通过选择其他文件恢复后者需要用户明确授权。输出上限同样属于权限。读取一个数百兆日志会挤掉上下文并增加费用即使路径合法也可能造成拒绝服务。执行器读取max_bytes 1个字节超限时返回摘要与截断标志而不是默默截断后假装得到完整文件。四、怎样验收策略没有形同虚设至少覆盖正常相对路径、绝对路径、..、相似目录名前缀和指向外部的符号链接。测试不能只断言布尔值还要检查账本追加的原因码与规范化路径。tools.json自身必须由人工控制不能放在 Agent 可写目录否则模型只需给自己增加一个shell工具。本篇输出仍是runs/demo-001/events.jsonl现在多了一条带规范化路径的授权事件。下一篇会读取run_started.payload.goal与这条授权事件生成contract.json把原始目标、允许修改范围和检查命令做成指纹防止重试过程中目标悄悄漂移。参考来源Python 文档pathlib — Object-oriented filesystem pathsOWASPPath Traversal 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《Agent可靠性工程实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。
很多 Agent 教程从模型、提示词和工具调用开始,演示效果很热闹,却跳过了最先该解决的问题:一次任务失败以后,我们能否准确回答模型看到了什么、调用了什么、工具返回了什么、为什么停止。普通文本日志只记录人类觉得重要的句子&am…
📅 2026/7/30 15:57:31
1. 项目概述:当动漫数据遇上Python可视化 去年帮朋友工作室处理一批动漫评分数据时,我用了三周时间手工整理Excel表格。看着密密麻麻的数字,突然意识到:为什么不用Python把这些数据变成会说话的图表?于是诞生了这个结合…
📅 2026/7/30 15:57:31
你们有没有那种感觉?就是看到某个东西特别火,直播间里一晚上卖几千单,评论区清一色“绝了”“回购N次”,但自己买回来一尝……emmm,也就那样吧。或者更惨一点,味道还行,但一看配料表,…
📅 2026/7/30 15:57:31
目录
简介:
1. 数据库表创建:
2. 编写文件记录标识接口:
3. 编写分片是否存在判断接口:
4. 编写文件分片上传接口:
5. 编写文件分片合并接口: 简介: 什么是分片上传?分片上传就是把一个大…
📅 2026/7/30 16:55:04
药品基本信息通用名称:pivekimab sunirine-pvzy商品名称:Decnupaz药品类型:靶向CD123的抗体药物偶联物(ADC)适应症本品为处方药,适用于治疗成年母细胞性浆细胞样树突状细胞肿瘤(BPDCN&…
📅 2026/7/30 16:55:04
终极Steam游戏数据提取指南:轻松获取DLC、成就和文件信息 【免费下载链接】GetDataFromSteam-SteamDB 项目地址: https://gitcode.com/gh_mirrors/ge/GetDataFromSteam-SteamDB
你是否曾经想要从Steam游戏中提取详细的DLC信息、成就数据或文件哈希值&#x…
📅 2026/7/30 16:55:04
HarmonyOS 应用实战 57:题库颜色迁移别让旧数据失色,给 colorKey 做兼容映射
题库颜色看起来只是一个视觉字段,但它一旦写进 Preferences,就变成了需要迁移的持久数据。旧版本如果保存的是 #8AA7FF 或已经废弃的颜色名,…
📅 2026/7/30 16:55:04
vue中nextTick的实际应用
简单来说就是:页面数据渲染完成之后再调用
在使用Vue框架的时候,有时候需要在Vue在页面数据渲染完成之后调用方法,不然获取不到准确的数据,特别是在获取列表的高度的时候,由于数据没有加载完…
📅 2026/7/30 16:55:04
1. 从“容器”到“关联容器”:为什么需要 map 和 set? 如果你写过 C,肯定用过 vector 或者 list 。这些顺序容器(Sequence Containers)帮我们解决了“存储一组数据”的问题,比如存一堆整数、存一堆字符…
📅 2026/7/30 16:54:04
本文关键词:geo2是共价化合物哎,说实话,每次看到化学题里那些弯弯绕绕的电子式,我就头大。特别是遇到那种非要让你判断是离子还是共价的,心里就发毛。今天咱不整那些虚头巴脑的定义,就聊聊二氧化硅,也就是大家常说的硅石、石英,很多人会误写成geo2,虽然化学式不对,但…
📅 2026/7/30 0:00:24
B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…
📅 2026/7/30 0:00:26
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer
您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…
📅 2026/7/30 0:00:26
更多请点击:
https://codechina.net
第一章:AI帮助理解数学概念 人工智能正以前所未有的方式重塑数学学习的路径。通过自然语言处理与符号计算的深度融合,AI不仅能解析抽象定义,还能将定理、证明和几何直觉转化为可交互、可验证的…
📅 2026/7/30 1:16:07
1. 项目背景与核心价值去年参与的一个短剧项目让我深刻体会到传统创作流程的痛点:编剧团队花了三周打磨剧本,角色设计反复修改了七版,最后成片时又因为演员档期问题不得不临时调整分镜。这种低效的创作模式在快节奏的内容行业越来越难以为继。…
📅 2026/7/30 1:16:07
remix-i18next TypeScript类型安全实践:确保翻译键与类型定义同步 【免费下载链接】remix-i18next The easiest way to translate your React Router framework mode apps 项目地址: https://gitcode.com/gh_mirrors/re/remix-i18next
在开发多语言应用时&am…
📅 2026/7/30 1:16:07
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/30 7:16:27
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/29 17:15:46
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/30 5:16:22