Hello Agents 项目实战:TerminalTool 安全沙箱机制与命令执行防护深度解析
2026/9/12 20:20:39 网站建设 项目流程

Hello Agents 项目实战:TerminalTool 安全沙箱机制与命令执行防护深度解析

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

本篇文章围绕 Hello Agents 开源教程仓库中 code/chapter9/project/README.md 所阐述的 TerminalTool 安全特性展开。该目录是第九章"上下文工程"中用于演示 TerminalTool 沙箱能力的示例项目:智能体可以通过它安全地探索文件系统、分析日志与代码库,而不会被恶意命令或越权路径访问拖垮系统。读完本文,你将掌握 TerminalTool 的命令白名单、工作目录限制与路径逃逸保护三层核心防护,理解其背后的源码级实现原理,并能直接运行仓库中的示例代码进行验证。

项目演示目录:TerminalTool 安全特性的验证现场

在 code/chapter9/project/ 目录下,仓库提供了一个专门用于演示 TerminalTool 安全特性的示例项目,其中 project/README.md 开门见山地说明:

这个目录用于演示 TerminalTool 的安全特性。

该目录结构非常简单,包含两个文件:

  • project/README.md:安全特性说明文档,即本篇文章的主体依据;
  • project/main.py:一个极简的应用主入口,仅打印启动时间与问候信息,用于充当"待探索的项目代码"。

按照 chapter9/README.md 的目录结构规划,project/codebase/(示例代码库)、data/(示例销售数据)、logs/(模拟应用日志)共同构成了上下文工程一章的演示素材,而project/目录的特殊定位就是安全攻击测试靶场:用最小的项目体量,集中验证 TerminalTool 在面临危险命令、越权文件访问与路径逃逸时的拦截行为。

TerminalTool 的三大核心安全特性

根据 project/README.md,TerminalTool 具备以下安全特性:

  1. 命令白名单:只允许执行特定的安全命令;
  2. 工作目录限制:不能访问工作目录之外的文件;
  3. 路径逃逸保护:防止通过..等方式逃逸工作目录。

这三大特性在设计上形成纵深防御:白名单从"命令来源"上卡住破坏性操作,工作目录限制从"访问边界"上划定活动范围,路径逃逸保护则堵住绕过沙箱边界的具体手段。

特性一:命令白名单

TerminalTool 内部维护了一份允许执行的命令集合,只放行安全的只读型命令,完全禁止任何可能修改系统的操作。第九章主文档 docs/chapter9/第九章 上下文工程.md 中给出了白名单的典型构成:

ALLOWED_COMMANDS = { # 文件列表与信息 'ls', 'dir', 'tree', # 文件内容查看 'cat', 'head', 'tail', 'less', 'more', # 文件搜索 'find', 'grep', 'egrep', 'fgrep', # 文本处理 'wc', 'sort', 'uniq', 'cut', 'awk', 'sed', # 目录操作 'pwd', 'cd', # 文件信息 'file', 'stat', 'du', 'df', # 其他 'echo', 'which', 'whereis', }

注意其中刻意排除了rmmvchmoddd等可能对系统造成不可逆修改的命令。仓库中另一处独立实现 Co-creation-projects/YYHDBL-HelloCodeAgentCli/tools/builtin/terminal_tool.py 也印证了这一设计取向,其注释明确写道:"不包含可能修改系统或造成安全风险的命令(如 rm、mv、chmod 等)",并在实现中进一步把rmchmod列为需要人类确认的高风险命令(DANGEROUS_BASE_COMMANDS),将git reset --hard等破坏性子命令列入DANGEROUS_GIT_SUBCOMMANDS。这说明"白名单 + 危险命令识别"是该项目一贯坚持的安全底线。

特性二:工作目录限制(沙箱)

TerminalTool 初始化时通过workspace参数指定工作目录,所有命令都只能在该目录及其子目录内执行。例如在 code/chapter9/05_terminal_tool_examples.py 中,安全演示部分以project/目录为沙箱:

terminal = TerminalTool(workspace=str(SCRIPT_DIR / "project"))

此后即使智能体发起cat /etc/passwd这类读取系统敏感文件的请求,也会被沙箱机制拦截——因为目标路径不在工作目录内。

特性三:路径逃逸保护

沙箱的关键难点在于防止路径拼接绕过。TerminalTool 在实现目录导航时,会先解析出目标路径的绝对路径,再用relative_to校验其是否仍位于工作目录内:

new_dir = (self.current_dir / target_dir).resolve() # 检查是否在工作目录内 try: new_dir.relative_to(self.workspace) except ValueError: return f"❌ 不允许访问工作目录外的路径: {new_dir}"

这正是 project/README.md 中"防止通过..等方式逃逸工作目录"的源码级落地:cd ../../../etc这类层层上跳的路径会被解析为工作目录之外的绝对路径,从而被relative_to校验拦截。

测试场景:三个危险操作如何被拦截

project/README.md 列出了三个标准测试场景,而它们与 code/chapter9/05_terminal_tool_examples.py 中demo_security_features()函数的三段演示代码一一对应:

测试场景对应演示命令预期拦截结果
尝试执行危险命令rm -rf /触发命令白名单,提示"不允许的命令: rm"
尝试访问工作目录外的文件cat /etc/passwd触发工作目录限制,拒绝访问沙箱外路径
尝试通过相对路径逃逸cd ../../../etc触发路径逃逸保护,拒绝越界切换目录
def demo_security_features(): """演示安全特性""" terminal = TerminalTool(workspace=str(SCRIPT_DIR / "project")) # 尝试执行不允许的命令 print("1. 尝试执行危险命令 (rm):") result = terminal.run({"command": "rm -rf /"}) print(result) # 尝试访问工作目录外的文件 print("\n2. 尝试访问工作目录外的文件:") result = terminal.run({"command": "cat /etc/passwd"}) print(result) # 尝试逃逸工作目录 print("\n3. 尝试通过 .. 逃逸工作目录:") result = terminal.run({"command": "cd ../../../etc"}) print(result)

要复现这些拦截行为,进入 chapter9 目录运行(该示例无需 LLM,仅依赖hello_agents.tools中的 TerminalTool 实现):

cd code/chapter9 python 05_terminal_tool_examples.py

纵深防御:主文档中的四层安全机制

虽然 project/README.md 只列了三大特性,但第九章主文档 docs/chapter9/第九章 上下文工程.md 的 9.5 节将其扩展为完整的四层安全机制,前三层即上述三大特性,第四层补充了资源消耗防护:

  • 第一层:命令白名单——只放行安全只读命令,rm -rf /会被立即拒绝;
  • 第二层:工作目录限制(沙箱)——只允许访问workspace及其子目录;
  • 第三层:超时控制——每个命令有执行时限(默认 30 秒),防止死循环或资源耗尽,超时后返回"命令执行超时";
  • 第四层:输出大小限制——默认限制输出为 10MB(max_output_size=10 * 1024 * 1024),超出部分截断并附警告,防止内存溢出。

后两层在初始化参数上体现为:

terminal = TerminalTool( workspace="./project", timeout=30, # 30秒超时 max_output_size=10 * 1024 * 1024 # 输出上限 10MB )

从源码实现看,命令执行核心_execute_command使用subprocess.run并显式传入cwdtimeoutcapture_output,返回码非零时会在输出前附加警告标记,超时与异常均被捕获为可读字符串而非抛给智能体崩溃——这种"容错设计"保证了即使命令异常,智能体主流程也不会中断(参见 docs/chapter9/第九章 上下文工程.md 的 9.5.2 节)。

在上下文工程中的定位:JIT 即时文件访问

TerminalTool 之所以被放在第九章"上下文工程"中,是因为它实现了 9.2.2 节提出的"即时(Just-in-time, JIT)上下文"理念:智能体不需要把整个代码库预先加载进上下文窗口,而是在需要时按需lscatgrep,只在关键时刻拉取少量高价值信息,从而显著降低 token 消耗。

chapter9/README.md 中列出了 TerminalTool 的四种典型使用模式,均可直接从仓库中运行验证:

  1. 探索式导航ls -lacd srcfind . -name '*service*.py'cat user_service.py,像人类开发者一样逐步摸清项目结构;
  2. 数据文件分析head -n 5 sales_2024.csvwc -l *.csvtail -n +2 ... | cut -d',' -f3 | sort | uniq -c快速预览 data/sales_2024.csv;
  3. 日志文件分析tail -n 50 app.log | grep ERRORgrep ERROR app.log | awk '{print $4}' | sort | uniq -c | sort -rn定位错误类型分布;
  4. 代码库分析grep -rn 'TODO' --include='*.py'grep -rn 'def process_data' --include='*.py'辅助代码审查。

主文档 9.5.4 节还展示了 TerminalTool 与 MemoryTool、NoteTool、ContextBuilder 的协同:探索结果可存入语义记忆(memory_type="semantic"),重要发现可写成结构化 blocker 笔记,命令输出可封装为ContextPacket注入上下文——这正是 code/chapter9/codebase_maintainer.py 所集成的完整长程智能体方案(其中TerminalTool(workspace=codebase_path, timeout=60)以 60 秒超时运行代码库维护任务)。

安全边界提醒与常见问题

  • 白名单是硬约束:若智能体尝试执行白名单外的命令,工具会返回"不允许的命令"提示。遇到此类提示,应改用白名单内的等价命令,如文件查看用cat/head/tail,搜索用find/grep,文本处理用awk/sed/cut/sort/uniq/wc(参见 chapter9/README.md 的 FAQ Q4)。
  • 沙箱不可绕过:无论是绝对路径(/etc/passwd)还是相对路径(cd ../../../etc)指向工作目录之外,都会被relative_to校验拒绝。
  • 超时与输出限制:长时间运行的命令与超大输出会被自动截断,这是资源保护而非功能缺陷。
  • 运行环境前提:TerminalTool 依赖hello_agents.tools工具包,需在项目配置好hello_agents依赖后运行;本章示例的运行顺序建议(先跑无需 LLM 的03_note_tool_operations.py05_terminal_tool_examples.py,再配置嵌入模型与 LLM 跑完整工作流)详见 chapter9/README.md。

通过 code/chapter9/project/README.md 这个最小演示项目,可以完整观察 TerminalTool 在"命令白名单、工作目录限制、路径逃逸保护"三重防护下的拦截行为;结合 docs/chapter9/第九章 上下文工程.md 的四层安全机制设计与 code/chapter9/05_terminal_tool_examples.py 的可运行示例,你就能在自己的智能体项目中安全地开放文件系统探索能力,让 Agent 既能"看得见"代码与数据,又无法"越界"破坏系统。

【免费下载链接】hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询