Promptfoo: 生成 的 代码 先 关 进 Docker, 再 谈 通过 率
Promptfoo 这篇教程用 epicbox 在 python:3.9-alpine 里跑模型写出的函数,CPU 限 1 秒、内存限 64。三道题分别期望 120、True 和 9;退出码非 0 或输出不符都记 0 分。

本文目录
在沙箱里评测大模型生成的代码
你在用大语言模型生成代码片段、函数,甚至整个程序。在生产环境里——甚至在开发环境里——盲目信任并执行这些生成的代码,可能是严重的安全风险。
沙箱评测就是为此准备的。沙箱是把待测代码放进隔离环境里运行,使它碰不到宿主系统。把大语言模型生成的代码放在受控、隔离的环境里运行,我们可以:
- 安全地评估代码是否正确。
- 给不同的大语言模型或提示词做基准,找出哪一种产出最可靠的代码。
- 在无限循环或耗费资源的操作影响到宿主系统之前,抓住潜在错误。
在这篇教程里,我们用 promptfoo 搭一条自动流水线:用大语言模型生成 Python 代码,用 epicbox 在安全沙箱里执行,再评测结果。promptfoo 是一个用配置文件驱动的大语言模型评测命令行工具。epicbox 是一个在 Docker 容器里按资源限制执行代码的 Python 库。
前置条件
确认已经安装:
- Node.js 和 npm
- Python 3.10 及以上
- Docker
- promptfoo(
npm install -g promptfoo)
在 Windows 上,请在 WSL 2 里运行本教程,并打开 Docker Desktop 的 WSL 集成。在 WSL 里安装 Node.js 和 Python;Epicbox 不支持原生 Windows 上的 Python。
在项目目录里创建虚拟环境,并安装示例的 Python 依赖。
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r https://raw.githubusercontent.com/promptfoo/promptfoo/main/examples/integration-docker/code-generation-sandbox/requirements.txt跑评测时,让这个虚拟环境在同一个 shell 里保持激活。
这些依赖使用 Epicbox 1.1.1 的官方 GitHub 发布,并用 SHA-256 哈希核验,同时保留传输安全的最低要求。PyPI 上的 Epicbox 1.1.0 与 urllib3 2 不兼容。
把要用的 Docker 镜像拉到本地,这样它就在本机可用。本教程使用一个通用的 Python 镜像,你也可以换成自定义镜像:
docker pull python:3.9-alpine配置
创建 promptfoo 配置文件
创建名为 promptfooconfig.yaml 的文件:
prompts: file://code_generation_prompt.txt
providers:
- openai:gpt-5
- ollama:chat:llama4:scout
tests:
- vars:
problem: 'Write a Python function to calculate the factorial of a number'
function_name: 'factorial'
test_input: '5'
expected_output: '120'
- vars:
problem: 'Write a Python function to check if a string is a palindrome'
function_name: 'is_palindrome'
test_input: "'racecar'"
expected_output: 'True'
- vars:
problem: 'Write a Python function to find the largest element in a list'
function_name: 'find_largest'
test_input: '[1, 5, 3, 9, 2]'
expected_output: '9'
defaultTest:
assert:
- type: python
value: file://validate_and_run_code.py这份配置做了几件重要的事:
- 它告诉 promptfoo 使用我们的提示词模板。
- 我们在测试 GPT-5 和 Llama 4(你可以换成自己选择的 provider。provider 是 promptfoo 用来调用某一个模型的适配器。Promptfoo 同时支持本地和商业 provider)。
- 它定义编码题目。每道题指定函数名、一个测试输入和期望输出。
- 它设置一条基于 Python 的断言,对每个测试用例运行,用来校验生成的代码。断言是判定该条测试通过或失败的检查。
创建提示词模板
创建名为 code_generation_prompt.txt 的文件,内容如下:
You are a Python code generator. Write a Python function to solve the following problem:
{{problem}}
Use the following function name: {{function_name}}
Only provide the function code, without any explanations or additional text. Wrap your code in triple backticks.这条提示词会发给大语言模型,{{variables}} 会按对应值替换(这条提示词是兼容 Jinja 的模板)。
准备 Python 断言脚本
创建名为 validate_and_run_code.py 的文件。这是一条 Python 断言,它用 epicbox 在 Docker 容器里运行,从而给每道编码题动态打分。
```python
import epicbox
import r
Replace with your preferred Docker image
DOCKER_IMAGE = 'python:3.9-alpine'
def get_assert(output, context):
Extract the Python function from the LLM output
function_match = re.search(r'``python\s*\n(def\s+.*?)\n`', output, re.DOTALL)
if not function_match:
return {'pass': False, 'score': 0, 'reason': 'No function definition found'
function_code = function_match.group(1)
epicbox.configure( profiles=[ epicbox.Profile('python', DOCKER_IMAGE) ] )
function_name = context['vars']['function_name'] test_input = context['vars']['test_input'] expected_output = context['vars']['expected_output']
Create a Python script to call the LLM-written function
test_code = f""" {function_code}
Test the function
result = {function_name}({test_input}) print(result) """
files = [{'name': 'main.py', 'content': test_code.encode('utf-8')}] limits = {'cputime': 1, 'memory': 64}
Run it
result = epicbox.run('python', 'python main.py', files=files, limits=limits)
Check the result
if result['exit_code'] != 0: return {'pass': False, 'score': 0, 'reason': f"Execution error: {result['stderr'].decode('utf-8')}"}
actual_output = result['stdout'].decode('utf-8').strip() if actual_output == str(expected_output): return {'pass': True, 'score': 1, 'reason': f'Correct output: got {expected_output}'} else: return {'pass': False, 'score': 0, 'reason': f"Incorrect output. Expected: {expected_output}, Got: {actual_output}"} ````
运行评测
在终端执行:
promptfoo eval这条命令会:
- 用大语言模型为每道题生成 Python 代码
- 抽出生成的代码
- 在 Docker 沙箱环境里运行它
- 判定输出是否正确
分析结果
评测跑完后,打开网页查看器:
promptfoo view它会显示结果摘要。你可以分析:
- 生成代码的总体通过率
- 大语言模型成功或失败的具体测试用例
- 失败测试的错误信息或不正确输出
图:promptfoo 网页查看器里的代码生成评测结果。
接下来
若要继续看 promptfoo 能做什么,可以考虑:
- 测试不同的大语言模型 provider
- 修改你的提示词
- 扩大编码题目和测试用例的范围
更多信息见官方 指南。你也可以看 持续集成 以及和其他工具的集成。
Promptfoo,Sandboxed Evaluations of LLM-Generated Code,2026-09-27,https://www.promptfoo.dev/docs/guides/sandboxed-code-evals/,MIT
觉得有用,转给同事
微信扫码
用微信扫一扫,在手机上打开后即可转发。