搭建一个轻量 Agent Harness——让 AI Agent 安全地执行命令、读写文件

搭建一个轻量 Agent Harness------让 AI Agent 安全地执行命令、读写文件、调用 API

Agent 不只是调用 LLM,还需要执行命令、读写文件、调 API。但让 AI 直接操作你的电脑是有风险的。Agent Harness 就是解决这个问题的------给 Agent 一个受限的"沙箱"。

Harness 做什么

复制代码
Agent 想做什么 → Harness 检查和审批 → 执行 → 返回结果

核心能力:
├─ 🛡️ 沙箱执行:限制 Agent 只能操作指定目录
├─ 📋 命令白名单:只允许安全的命令
└─ ✅ 人工审批:危险操作需要确认

核心代码

python 复制代码
# harness.py
import subprocess, os, shlex
from pathlib import Path

class AgentHarness:
    """Agent 安全执行环境。"""

    ALLOWED_COMMANDS = {"ls", "cat", "head", "tail", "grep", "wc",
                        "find", "echo", "date", "python", "pip", "git"}

    def __init__(self, workspace="./agent_workspace", require_confirm=True):
        self.workspace = Path(workspace).resolve()
        self.workspace.mkdir(parents=True, exist_ok=True)
        self.require_confirm = require_confirm
        self.history = []

    def execute(self, command: str) -> dict:
        """在沙箱中执行命令。"""
        cmd_parts = shlex.split(command)
        if not cmd_parts:
            return {"error": "Empty command"}

        # 安全检查
        base_cmd = cmd_parts[0]
        if base_cmd not in self.ALLOWED_COMMANDS:
            return {"error": f"命令 {base_cmd} 不在白名单中"}

        # 危险操作需要确认
        dangerous = any(k in command for k in ["rm ", "delete", "DROP", ">", ">>"])
        if dangerous and self.require_confirm:
            print(f"\n⚠️ 危险操作:{command}")
            ok = input("确认执行?[y/N] ").strip().lower()
            if ok != "y":
                return {"error": "用户取消"}

        try:
            result = subprocess.run(
                command, shell=True, capture_output=True, text=True,
                timeout=30, cwd=str(self.workspace),
            )
            output = result.stdout.strip()
            if result.returncode != 0:
                output = result.stderr.strip() or output

            self.history.append({"command": command, "output": output[:500]})
            return {"output": output[:2000], "code": result.returncode}
        except subprocess.TimeoutExpired:
            return {"error": "命令执行超时(30s)"}
        except Exception as e:
            return {"error": str(e)}

    def read_file(self, path: str) -> dict:
        """安全读取文件。"""
        full_path = (self.workspace / path).resolve()
        if not str(full_path).startswith(str(self.workspace)):
            return {"error": "不能读取工作目录以外的文件"}

        try:
            content = full_path.read_text(encoding="utf-8", errors="ignore")
            return {"content": content[:5000]}
        except Exception as e:
            return {"error": str(e)}

    def write_file(self, path: str, content: str) -> dict:
        """安全写入文件。"""
        full_path = (self.workspace / path).resolve()
        if not str(full_path).startswith(str(self.workspace)):
            return {"error": "不能写入工作目录以外的文件"}

        if self.require_confirm:
            print(f"\n📝 即将写入:{path}({len(content)} 字符)")
            ok = input("确认写入?[y/N] ").strip().lower()
            if ok != "y":
                return {"error": "用户取消"}

        try:
            full_path.parent.mkdir(parents=True, exist_ok=True)
            full_path.write_text(content, encoding="utf-8")
            return {"status": "ok", "path": str(full_path.relative_to(self.workspace))}
        except Exception as e:
            return {"error": str(e)}

Agent + Harness 组合使用

python 复制代码
# agent_with_harness.py
from openai import OpenAI
from harness import AgentHarness
import os, json
from dotenv import load_dotenv
load_dotenv()

client = OpenAI(api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com/v1")
harness = AgentHarness("./workspace")

TOOLS = [
    {"type": "function", "function": {
        "name": "execute_command", "description": "在沙箱中执行命令。可用命令:ls, cat, grep, find, python, git",
        "parameters": {"type": "object", "properties": {"command": {"type": "string"}}, "required": ["command"]}
    }},
    {"type": "function", "function": {
        "name": "read_file", "description": "读取工作目录中的文件",
        "parameters": {"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]}
    }}
]

def run_agent(task):
    messages = [{"role": "system", "content": f"你是一个编程助手。工作目录:{harness.workspace}"}]
    messages.append({"role": "user", "content": task})

    while True:
        resp = client.chat.completions.create(
            model="deepseek-chat", messages=messages, tools=TOOLS, tool_choice="auto"
        )
        msg = resp.choices[0].message

        if not msg.tool_calls:
            return msg.content

        for tc in msg.tool_calls:
            name = tc.function.name
            args = json.loads(tc.function.arguments)

            if name == "execute_command":
                result = harness.execute(args["command"])
            elif name == "read_file":
                result = harness.read_file(args["path"])
            else:
                result = {"error": "Unknown tool"}

            messages.append(msg)
            messages.append({"role": "tool", "tool_call_id": tc.id, "content": json.dumps(result)})

# 使用
result = run_agent("在当前目录创建一个 hello.py,内容为打印 Hello World,然后运行它")
print(result)

总结

一个轻量的 Agent Harness,三个核心能力:

  1. 命令白名单:限制 Agent 只能执行安全命令
  2. 目录隔离:Agent 只能操作工作目录内的文件
  3. 危险操作确认:删除、覆盖等需要人工审批

几十行代码实现,让你的 Agent 既强大又安全。

本文由 Zyentor(智元界)原创发布


本文发布于 Zyentor(智元界) ------ AI 开发者社区 原文链接:www.zyentor.com/news/4324

相关推荐
雪隐2 小时前
个人电脑玩AI-09让5060 Ti给你打工——让 AI 读懂你的资料
人工智能·后端
大模型真好玩2 小时前
LangChain DeepAgents 速通指南(十)—— DeepAgents Code 智能体服务核心源码解读
人工智能·langchain·agent
网易云信2 小时前
「帝王蟹」企业AI落地实战营西安站落幕:共探“人工智能+”落地深水区
人工智能·agent·产品
阿虎儿2 小时前
本地构建的自定义sandbox-extra镜像推送到沙盒daytona的snapshot列表中
人工智能
网易云信3 小时前
Agent在客服和营销领域走到哪一步了?深度解析3个挑战和5大趋势
人工智能·agent
网易云信3 小时前
AI 融入协作场景,Hermes 接入云信 IM
人工智能·agent
vivo互联网技术3 小时前
ICLR 2026 | 基于后验采样的图像恢复方法LearnIR:人脸去阴影、去雾
人工智能·算法·aigc
饼干哥哥4 小时前
ChatGPT会员掉了,代充黑幕藏不住了
人工智能·操作系统·产品
ZzT4 小时前
Claude Sonnet 5 来了:Opus 级的能力,Sonnet 的价
人工智能·ai编程·claude