六维教程

EdgeOne Makers Agents 沙箱工具

Agent 不只是聊天,还能执行代码、调用工具。这篇讲怎么用沙箱环境安全地让 Agent 执行任务。

什么是沙箱

沙箱就是一个隔离的执行环境。Agent 在里面跑代码,不会影响外部系统。

场景 不用沙箱的风险
Agent 执行用户提交的代码 可能删库、访问敏感数据
Agent 调用外部 API 可能泄露密钥、被滥用
Agent 处理文件 可能覆盖系统文件

沙箱的作用就是让 Agent 能做事,但不会闯祸。

沙箱的能力

EdgeOne Makers 的沙箱提供这些能力

能力 说明
代码执行 运行 JavaScript、Python 等代码
文件操作 读写临时文件,有大小限制
网络请求 可以调用外部 API
超时控制 自动终止长时间运行的任务
资源限制 内存、CPU 使用有上限

简单沙箱示例

eval 执行代码,但加上严格的限制。

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    if (url.pathname === '/execute') {
      const { code, language } = await request.json();
      
      // 简单的安全检查
      const forbidden = ['process', 'require', 'import', 'fs'];
      for (const keyword of forbidden) {
        if (code.includes(keyword)) {
          return Response.json({ 
            error: `不允许使用 ${keyword}` 
          }, { status: 400 });
        }
      }
      
      try {
        // 设置超时(5秒)
        const timeout = new Promise((_, reject) => {
          setTimeout(() => reject(new Error('执行超时')), 5000);
        });
        
        // 执行代码
        const execute = new Promise((resolve) => {
          const result = eval(code);
          resolve(result);
        });
        
        const result = await Promise.race([execute, timeout]);
        
        return Response.json({ 
          success: true, 
          result: String(result) 
        });
      } catch (error) {
        return Response.json({ 
          success: false, 
          error: error.message 
        });
      }
    }
  }
};

这个例子很简单,只是演示思路。实际生产环境需要更严格的隔离。

工具调用

Agent 可以调用预定义的工具。用 JSON Schema 描述工具,模型 decides 什么时候调用。

定义工具

const tools = [
  {
    name: 'get_weather',
    description: '获取指定城市的天气',
    parameters: {
      type: 'object',
      properties: {
        city: {
          type: 'string',
          description: '城市名称,比如"北京"'
        }
      },
      required: ['city']
    }
  },
  {
    name: 'search_web',
    description: '搜索网页信息',
    parameters: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: '搜索关键词'
        }
      },
      required: ['query']
    }
  }
];

处理工具调用

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    if (request.method === 'POST') {
      const { message } = await request.json();
      
      // 调用模型,传入工具定义
      const response = await env.AI.chat('deepseek-v3', {
        messages: [
          { role: 'system', content: '你是一个助手,可以查询天气和搜索网页' },
          { role: 'user', content: message }
        ],
        tools: tools
      });
      
      // 检查是否需要调用工具
      if (response.tool_calls) {
        const results = [];
        
        for (const toolCall of response.tool_calls) {
          const { name, arguments: args } = toolCall.function;
          
          // 执行对应的工具
          let result;
          if (name === 'get_weather') {
            result = await getWeather(args.city);
          } else if (name === 'search_web') {
            result = await searchWeb(args.query);
          }
          
          results.push({
            tool_call_id: toolCall.id,
            result
          });
        }
        
        // 把工具结果传回模型,生成最终回复
        const finalResponse = await env.AI.chat('deepseek-v3', {
          messages: [
            { role: 'system', content: '你是一个助手' },
            { role: 'user', content: message },
            { role: 'assistant', content: null, tool_calls: response.tool_calls },
            ...results.map(r => ({
              role: 'tool',
              tool_call_id: r.tool_call_id,
              content: JSON.stringify(r.result)
            }))
          ]
        });
        
        return Response.json({ 
          reply: finalResponse.message.content,
          tools_used: response.tool_calls.map(t => t.function.name)
        });
      }
      
      return Response.json({ reply: response.message.content });
    }
  }
};

// 工具实现
async function getWeather(city) {
  // 调用天气 API
  return {
    city,
    temperature: '22°C',
    weather: '晴',
    humidity: '45%'
  };
}

async function searchWeb(query) {
  // 调用搜索 API
  return {
    query,
    results: [
      { title: '结果1', url: 'https://example.com/1' },
      { title: '结果2', url: 'https://example.com/2' }
    ]
  };
}

工具调用流程

步骤 说明
1. 用户提问 “北京今天天气怎么样”
2. 模型判断 需要调用 get_weather 工具
3. 返回工具调用 tool_calls 包含函数名和参数
4. 执行工具 调用 getWeather(‘北京’)
5. 返回结果 把工具结果传回模型
6. 生成回复 模型根据结果生成自然语言回复

自定义工具开发

你可以封装任何能力成工具。比如查数据库、调 API、处理文件。

// 数据库查询工具
const dbTool = {
  name: 'query_database',
  description: '查询产品数据库',
  parameters: {
    type: 'object',
    properties: {
      table: { type: 'string' },
      condition: { type: 'string' }
    }
  }
};

async function executeDbQuery(table, condition, env) {
  // 简单的 SQL 构造(实际要用参数化查询防注入)
  const sql = `SELECT * FROM ${table} WHERE ${condition}`;
  
  // 调用数据库
  const result = await env.DB.prepare(sql).all();
  
  return {
    table,
    count: result.results.length,
    data: result.results
  };
}

// 文件处理工具
const fileTool = {
  name: 'process_file',
  description: '处理上传的文件',
  parameters: {
    type: 'object',
    properties: {
      action: { 
        type: 'string',
        enum: ['analyze', 'convert']
      },
      format: { type: 'string' }
    }
  }
};

async function processFile(action, format, env) {
  // 从存储读取文件
  const fileData = await env.KV.get('uploaded_file', 'arrayBuffer');
  
  if (action === 'analyze') {
    return {
      size: fileData.byteLength,
      type: 'image',
      metadata: { width: 800, height: 600 }
    };
  } else if (action === 'convert') {
    // 转换格式(这里只是示例)
    return {
      original: 'png',
      converted: format,
      url: '/converted/file.jpg'
    };
  }
}

沙箱安全

沙箱不是万能的,还需要额外的安全措施。

措施 说明
输入校验 检查工具参数,防止注入
权限控制 限制工具能访问的资源
执行超时 自动终止长时间任务
资源限制 内存、CPU 使用上限
日志审计 记录所有工具调用
// 带权限检查的工具调用
async function callToolWithAuth(toolName, args, userId, env) {
  // 检查用户权限
  const userPerms = await env.KV.get(`user:${userId}:permissions`, 'json');
  
  const toolPerms = {
    'get_weather': 'public',
    'query_database': 'admin',
    'process_file': 'user'
  };
  
  const requiredPerm = toolPerms[toolName];
  if (!userPerms.includes(requiredPerm)) {
    throw new Error('没有权限执行此操作');
  }
  
  // 记录调用日志
  await env.KV.put(`log:${Date.now()}`, JSON.stringify({
    userId,
    tool: toolName,
    args,
    timestamp: Date.now()
  }));
  
  // 执行工具
  return await executeTool(toolName, args, env);
}

速查卡片

要点 说明
沙箱作用 隔离执行环境,防止 Agent 闯祸
沙箱能力 代码执行、文件操作、网络请求
工具定义 用 JSON Schema 描述工具参数
工具调用流程 模型判断 → 返回调用 → 执行 → 返回结果 → 生成回复
安全检查 输入校验、权限控制、超时、资源限制
自定义工具 可以封装任何能力成工具
日志审计 记录所有工具调用,便于追踪
上一篇
EdgeOne Makers Agents 对话存储
下一篇
EdgeOne Makers Agents 可观测性