Pi :内置四工具源码拆解——文件锁、变更快照与 bash 隔离
源码目录packages/agent/src/harness/tools/。〇、先看共同底座ExecutionToolContext/env四个工具没有一个直接碰 Node 的fs或child_process。它们全部通过注入的envExecutionEnv操作文件系统、执行命令// tools 看到的操作面env.readTextFile(path,signal)env.readBinaryFile(path,signal)env.writeFile(path,content,signal)env.fileInfo(path,signal)env.absolutePath(path,signal)env.canonicalPath(path)env.runCommand(...)// bash 工具走的命令执行这个抽象有三个直接收益可测试单测注入内存版 env不碰真实文件系统可隔离Gondolin 模式专项四把read/write/edit/bash全部路由进微 VM靠的就是工具只认 env 接口不认 OS——换一个远端 env 实现工具代码一行不改可审计所有文件操作都过一个口可以在 env 层统一打点。这是工具层与操作系统解耦的标准姿势——你的 Java 工具也应该定义FilePort/CommandPort接口而不是直接在工具里new FileOutputStream()。一、readoffset/limit 分页 图片 输出有界read的 schematool-read.tsconstreadSchemaType.Object({path:Type.String({description:Path to the file to read (relative or absolute)}),offset:Type.Optional(Type.Number({description:Line number to start reading from (1-indexed)})),limit:Type.Optional(Type.Number({description:Maximum number of lines to read})),});三个细节值得抄① 输出有界且明确告诉模型怎么读完。工具描述原话For text files, output is truncated to 2000 lines or 50KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.“输出截断 指引模型用 offset 继续读完”——Pi 把怎么处理大文件写进工具描述模型按指引自动分页。② 图片是一等输入。read支持 jpg/png/gif/webp/bmp读图走imageProcessor转成{type:image, data, mimeType}内容块直接作为附件发给模型。返回的提示里甚至带hints图片处理器的建议比如这张图可能被裁剪了。③ 路径解析做了 Unicode 容错path-utils.tsconstvariants[resolved,resolved.replace(/(AM|PM)\./gi,${NARROW_NO_BREAK_SPACE}$1.),// 全角空格resolved.normalize(NFD),// 音标字符分解resolved.replace(//g,’),// 直引号→弯引号];模型可能把文件路径里的全角空格、直引号、Unicode 组合字符搞混read会逐个变体尝试。模型输出文件路径是不可靠的工具端要做模糊匹配 容错。二、write创建父目录 字节数回执writetool-write.ts很薄但有一个行为值得注意description:Write content to a file. Creates the file if it doesnt exist, overwrites if it does. Automatically creates parent directories.自动创建父目录返回Successfully wrote ${content.length} bytes to ${path}。content.length是字符数不是字节数但这不耽误模型理解写入了多少。write 是整个工具集里最直白的它真正的复杂度在锁。三、edit精确文本替换附带变更快照edittool-edit.ts是四个工具里工程含量最高的。schemaconsteditSchemaType.Object({path:Type.String(...),edits:Type.Array(Type.Object({oldText:Type.String({description:Exact text for one targeted replacement. It must be unique in the original file...}),newText:Type.String({description:Replacement text for this targeted edit.}),}),{description:One or more targeted replacements. Each edit is matched against the original file, not incrementally...}),});执行流水线去掉样板后const{bom,text:content}stripBom(readResult.value);// ① 去 BOMconstoriginalEndingdetectLineEnding(content);// ② 检测换行符constnormalizedContentnormalizeToLF(content);// ③ 统一成 LFconst{baseContent,newContent}applyEditsToNormalizedContent(normalizedContent,edits,path);constfinalContentbomrestoreLineEndings(newContent,originalEnding);// ④ 还原换行符awaitenv.writeFile(absolutePath,finalContent,signal);constdiffResultgenerateDiffString(baseContent,newContent);// ⑤ 生成 diff 快照return{content:...,details:{diff,patch:generateUnifiedPatch(...),firstChangedLine}};五个要点先规范化再编辑编辑完还原BOM、CRLF/LF 先剥掉/统一替换完再还原。否则模型用 LF 的 oldText 匹配 CRLF 文件会失败。每个 oldText 必须唯一、且互不重叠“It must be unique in the original file and must not overlap with any other edits[].oldText”——schema 层就挡住模糊替换。edits 全部针对原文件匹配不增量匹配“Each edit is matched against the original file, not incrementally”——避免前一个编辑改变行号影响后一个。返回 diff/patch/firstChangedLine这就是文件变更快照。模型、UI、审计都能看到这次编辑到底改了什么。generateUnifiedPatch给出统一 difffirstChangedLine定位首行变化。兼容层prepareArguments老格式的{oldText, newText}被折叠成新的edits数组——工具 schema 演进不破坏历史调用。对比很多 Agent 用整文件重写改文件Pi 的 edit 是精确补丁 快照——副作用最小、可 diff、可回滚。四、文件锁按规范路径串行化变更file-mutation-queue.ts实现的是同一文件上的变更串行化——这是文件锁的 Promise 版本constkeyawaitgetMutationQueueKey(env,path);// 规范路径作为锁 keyconstcurrentQueuestate.queues.get(key)??Promise.resolve();// 排队当前队列完成后才轮到下一个constchainedQueuecurrentQueue.then(()nextQueue);state.queues.set(key,chainedQueue);awaitcurrentQueue;try{returnawaitfn();}finally{releaseNext();...}细节锁粒度 规范路径canonical path不是传进来的字符串。../a.md和a.md、符号链接和真实路径会归到同一个锁——按规范路径加锁才挡得住同文件不同路径的并发编辑。锁作用域 单个envWeakMapExecutionEnv, ...。不同 env比如 Gondolin 的远端 env各归各的。为什么需要它一个 turn 里可能有多个工具调用batch两个 edit 同时改同一个文件读-改-写会互相覆盖。文件锁把读原文件 → 应用编辑 → 写回变成同一路径上的原子操作。这是Agent 改代码场景最容易翻车的地方并发写同一文件。你在 Java 里做工具层时务必有同款按规范路径串行化文件变更的机制。五、bash隔离、捕获、会话环境注入bash 工具tools/bash.tsshell-output.ts是权限最大、最需要防护的工具。它的设计① 输出捕获 双限截断。命令输出边跑边攒超限即截断constmaxOutputBytesDEFAULT_MAX_BYTES*2;// 100KB 上限// 截断到尾部 N 行 / N KB谁先到算谁截断结果带完整元信息truncate.ts的TruncationResulttruncated / truncatedBy / totalLines / totalBytes / outputLines / lastLinePartial并且完整输出落临时文件fullOutputPath——模型需要时再读全文主上下文只留尾部。② 输出净化sanitizeBinaryOutput过滤掉二进制控制字符只保留 tab/换行/回车防止二进制输出污染上下文。③ 超时显性化timeout 可选、无默认但受MAX_TIMEOUT_SECONDS硬上限约束超时以错误返回“Command timed out after N seconds”——模型能看到并决定怎么办。④ 会话环境注入environment-variables.mdbash 工具运行的命令会拿到当前会话状态PI_SESSION_ID 当前会话 ID PI_SESSION_FILE 会话 JSONL 路径临时会话为空 PI_PROVIDER 当前 provider PI_MODEL 当前模型 PI_REASONING_LEVEL 当前推理级别命令可以据此自查“我在哪个会话、用什么模型跑的”——这是 agent 自我感知能力的底座。spawnHook可以再改 env比如注入 CI1exposeSessionEnvironment: false关闭注入。⑤ 命令执行本身走 env 抽象runCommand所以 bash 同样可以被 Gondolin 路由进 VM——这就是工具隔离的实现路径bash 不是在进程里开 shell而是向 env 端口提交一个命令。六、对照你的工程四工具的移植清单Pi 的机制你要不要做说明env 抽象FilePort/CommandPort必须可测试 可隔离 可审计的根源read 分页 输出有界必须防止大文件灌爆上下文edit 精确替换 diff 快照强烈建议副作用最小、可回滚、可审计文件锁规范路径串行化必须并发改同一文件会互相覆盖bash 输出双限截断 临时文件必须命令输出是上下文杀手会话环境注入建议命令能感知自己在哪、用什么模型路径 Unicode 容错建议模型给的文件路径不可靠知识卡片本节体系归档┌──────────────────────────────────────────────────────────┐ │ 知识节点内置四工具env 抽象 文件锁 bash 隔离 │ │ │ │ What env 抽象FilePort/CommandPortread 分页/图片 │ │ edit 精确替换/BOM/diff 快照规范路径文件锁 │ │ bash 输出双限截断 会话 env 注入 │ │ │ │ Why 一般原理工具层与 OS 解耦。不变量 │ │ ① 工具只认 env 接口可测试/可隔离/可审计 │ │ ② 同文件变更按规范路径串行化 │ │ ③ 输出必须有界完整内容落临时文件 │ │ │ │ How 校验动作 │ 画四工具结构 PaiFlow 文件操作换 FilePort 接口 │ │ │ │ Pits 坑点 │ 并发写文件 / 输出灌爆 / 模型给的路径不可靠 │ │ │ │ Transfer 到 PaiFlowFilePort 规范路径锁 输出截断 │ └──────────────────────────────────────────────────────────┘源码与文档出处packages/agent/src/harness/tools/{read,write,edit,bash,file-mutation-queue,path-utils,tool-context}.ts、packages/agent/src/harness/utils/{truncate,shell-output}.ts、packages/coding-agent/docs/environment-variables.md。

相关新闻

5分钟免费激活Adobe全家桶:GenP 3.0完整破解指南

5分钟免费激活Adobe全家桶:GenP 3.0完整破解指南

5分钟免费激活Adobe全家桶:GenP 3.0完整破解指南 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP 还在为Adobe Creative Cloud的高额订阅费而烦恼吗&…

2026/10/31 12:22:16 阅读更多 →
构建个人知识工作流:从信息收集到任务管理的自动化实践

构建个人知识工作流:从信息收集到任务管理的自动化实践

1. 项目概述:从“Claude Code 源码”到个人效率工具箱的蜕变最近在开发者社区和效率工具圈里,“Claude Code”这个词的热度居高不下。很多人都在搜索它的安装教程、使用技巧,甚至探讨它与Codex等工具的区别。但当我深入研究这些讨论和网络上的…

2026/10/22 19:40:18 阅读更多 →
MAIGateway,魔芋企业级AI网关的安全基建化设计

MAIGateway,魔芋企业级AI网关的安全基建化设计

8月12日,界面新闻发了一条消息:字节跳动成立"AI数据与安全"一级部门,与Seed、Flow、抖音平行。 在互联网大厂的组织架构里,"一级部门"意味着集团级预算、编制和决策权。字节把数据治理和AI安全从分散在各业务…

2026/10/26 1:43:48 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/31 10:20:19 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/31 10:20:23 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/31 10:30:19 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/31 9:29:43 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 17:32:24 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 11:00:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →