−25%

Windows 按年付费,截至 10 月 31 日。 查看套餐

EQVPS
开始使用

在沙箱中完成第一个智能体任务:LLM 写代码,微虚拟机来运行

搭建最小可用的 AI 代码执行循环:模型写一个 Python 脚本,Firecracker 沙箱运行它,出错就把错误交还给模型,直到脚本跑通。约 40 行代码,另附完全不写代码、通过 MCP 完成同一任务的方法。

会写代码的智能体,只有在有东西能安全运行这些代码并汇报结果时才真正有用。本教程从头到尾搭建这个循环:模型写一个 Python 脚本,沙箱运行它,失败了就把错误交还给模型。然后用 MCP 完成同一任务,一行代码都不用写。

你需要 Python 3.8+、一个 EQVPS 账户令牌(见连接账户),以及某个模型的 API 密钥。

1. 先设置消费上限

智能体会自己创建沙箱,所以开始前先给它定个上限。做实验的话,每天 2 美元、每月 20 美元绰绰有余:

curl -X PUT https://api.eqvps.com/api/v1/eqvps/sandboxes/budget \
  -H "Authorization: Bearer $EQVPS_API_KEY" -H "Content-Type: application/json" \
  -d '{"daily_usd": 2, "monthly_usd": 20}'

达到上限后,新沙箱会收到 429 budget_exceeded,正在运行的临时沙箱会被删除。详情见沙箱限制与计费。

2. 安装两个库

pip install eqvps anthropic
export EQVPS_API_KEY="your-eqvps-token"
export ANTHROPIC_API_KEY="your-model-key"

示例使用了一家模型服务商,但没有任何部分依赖它。只有 ask() 函数与模型通信。

3. “编写-运行-修复”循环

把下面的内容保存为 agent.py:

import re
import anthropic
from eqvps import Sandbox

TASK = "Count the prime numbers below 1,000,000 and print only the number."
client = anthropic.Anthropic()

def ask(messages):
    msg = client.messages.create(model="claude-sonnet-5", max_tokens=2000, messages=messages)
    return msg.content[0].text

def extract_code(text):
    m = re.search(r"`{3}(?:python)?\n(.*?)`{3}", text, re.S)
    return m.group(1) if m else text

messages = [{"role": "user", "content": "Write a Python 3 script for this task. "
             "Reply with a single code block and nothing else.\n\nTask: " + TASK}]

with Sandbox.create(tariff="small", idle_timeout=120) as sb:
    for attempt in range(1, 4):
        reply = ask(messages)
        r = sb.run(extract_code(reply), timeout=55)
        print(f"attempt {attempt}: exit code {r.exit_code}")
        if r.ok:
            print(r.stdout.strip())
            break
        messages += [
            {"role": "assistant", "content": reply},
            {"role": "user", "content": f"The script failed with exit code {r.exit_code}.\n"
             f"stderr:\n{r.stderr[-3000:]}\nFix it. Reply with a single code block."},
        ]

运行:

python3 agent.py

一次典型的运行会先打印 attempt 1: exit code 0,再打印 78498。如果第一个脚本失败,你会看到第二次尝试修复了错误。

各部分的作用:

  • Sandbox.create(..., idle_timeout=120) 约 1 秒启动一台微虚拟机。即使你的脚本中途退出,沙箱也会在空闲 2 分钟后自行删除。
  • sb.run(code, timeout=55) 运行代码,返回退出码、stdout 和 stderr。代码崩溃是正常结果而不是异常,所以循环可以把它展示给模型。
  • r.stderr[-3000:] 只发送错误的末尾部分。大型脚本的完整 traceback 会浪费模型大量上下文。
  • 最多 3 次是有意设定的限制。三次都修不好脚本的模型,通常需要更好的任务描述,而不是第四次尝试。

4. 任务需要超过 55 秒时

一次同步调用最多 55 秒。更长的工作请放到后台运行并等待:

task = sb.run(code, background=True)
result = task.wait(timeout=1800)

即使你的 wait 超时,任务也会继续运行,之后可以用 sb.task(task_id) 接着处理。

5. 通过 MCP 完成同一任务,无需代码

如果你在 Claude Desktop 或 Cursor 等 MCP 客户端中使用 EQVPS MCP 服务器,智能体已经拥有沙箱工具:create_sandbox、run_code、exec_command、upload_file、download_file 和 kill_sandbox。一条提示词就够了:

创建一个小型临时沙箱。写一个 Python 脚本统计 1,000,000 以内的质数个数,在沙箱里运行,失败就修复,把结果告诉我,然后删除沙箱。

智能体会执行和上面脚本相同的调用。哪些工具可以免确认放行,见 MCP 防护措施。

花了多少钱

沙箱存在的时间远不到一分钟,按最低 60 秒计费:small 上 0.00055 美元。调用模型的花费比沙箱还高。新账户 1 美元的试用额度大约够这样运行 1,800 次。

接下来

常见问题

为什么不直接在自己的机器上运行模型生成的代码?

因为你不知道它会做什么。生成的代码可能删除文件、读取你的密钥,或陷入死循环。在沙箱里,它运行在带独立内核的单独微虚拟机中,用完后沙箱被删除。

除了示例里的模型,其他模型也能用吗?

能。这个循环只需要一个接收消息、返回文本的函数。把 ask() 换成任何聊天 API 都行,包括本地模型。

怎样防止智能体无休止地创建沙箱?

开始前设置每日和每月消费上限。达到上限后,新沙箱会被 429 budget_exceeded 拒绝。此外每个账户同时只能运行两条命令,失控的循环也无法成倍扩张。

生成的代码能访问互联网吗?

能,沙箱可以访问外网,这样代码才能安装软件包、下载数据。沙箱没有入站端口。不要把密钥写进提示词或代码;脚本确实需要的,用环境变量传入。

评论

暂无评论。来做第一个吧。

发表评论

评论在显示前会经过审核。