https://github.com/openai/preparedness/tree/main/project/paperbench
项目概述
PaperBench是一个用于评估AI代理复现学术论文能力的综合框架。它提供了完整的工具链,从论文数据管理、代理执行、结果监控到评分系统,旨在自动化和标准化AI代理复现学术研究的过程。通过PaperBench,研究人员可以系统地测试不同AI代理在理解、实现和验证学术论文中的方法和结果方面的能力。
整体架构设计
PaperBench采用模块化设计,主要由以下核心层次组成:
- 数据层:负责论文数据的结构化管理和访问
- 代理层:实现各种AI代理及其执行环境
- 评估层:协调代理执行和结果收集
- 评判层:对代理复现结果进行评分和分析
- 展示层:提供用户界面和可视化功能
- 工具层:提供通用工具和基础设施支持
架构图
┌─────────────────────────────────────────────────────────────┐
│ 展示层 (GUI) │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┼─────────────────────────────────┐
│ 评判层 (Judge) │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┼─────────────────────────────────┐
│ 评估层 (Nano) │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┼─────────────────────────────────┐
│ 代理层 (Agents) │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┼─────────────────────────────────┐
│ 数据层 (Registry) │
└───────────────────────────┬─────────────────────────────────┘
│
┌───────────────────────────┼─────────────────────────────────┐
│ 工具层 (Utils) │
└─────────────────────────────────────────────────────────────┘
核心组件详解
1. 数据层
数据层主要由paper_registry.py
和agents/registry.py
文件实现,负责管理论文数据和代理配置。
PaperRegistry类
@dataclass
class PaperRegistry:
papers: dict[str, Paper] = field(default_factory=dict)
paper_dir: Path = field(default_factory=get_paperbench_data_dir)
def __post_init__(self) -> None:
self._load_papers()
def _load_papers(self) -> None:
for paper_dir in self.paper_dir.iterdir():
if not paper_dir.is_dir():
continue
try:
paper = Paper.from_dir(paper_dir)
self.papers[paper.id] = paper
except Exception as e:
logger.warning(f"Failed to load paper from {paper_dir}: {e}")
def get_paper(self, paper_id: str) -> Paper:
if paper_id not in self.papers:
raise ValueError(f"Paper with id {paper_id} not found")
return self.papers[paper_id]
def get_paper_ids(self) -> list[str]:
return list(self.papers.keys())
这个类负责加载和管理所有可用的论文数据,提供统一的接口来访问论文信息。类似地,AgentRegistry
类负责管理代理配置。
Paper数据类
@dataclass(frozen=True)
class Paper:
id: str
title: str
pdf_path: Path
md_path: Path
config_path: Path
blacklist: Path
repro_dir: Path
judge_dir: Path
rubric_path: Path
@classmethod
def from_dir(cls, paper_dir: Path) -> "Paper":
# 实现从目录加载论文数据的逻辑
...
2. 代理层
代理层实现了AI代理的核心逻辑,位于agents
目录下。以aisi-basic-agent
为例,它提供了基本的AI代理功能。
代理启动脚本
@task
def pb_task():
if ITERATIVE_AGENT:
solver = basic_agent_iterative(
tools=[bash(), read_file_chunk()],
max_attempts=1,
disallow_submit=DISALLOW_SUBMIT,
real_time_limit=int(float(MAX_TIME_IN_HOURS) * 60 * 60),
)
else:
solver = basic_agent_plus(
tools=[bash(), python(), read_file_chunk(), search_file()] + web_browser(),
max_attempts=1,
disallow_submit=DISALLOW_SUBMIT,
real_time_limit=int(float(MAX_TIME_IN_HOURS) * 60 * 60),
)
return Task(
dataset=[Sample(input=instructions)],
solver=solver,
sandbox="local",
)
这段代码定义了代理任务,配置了代理可以使用的工具(bash、python、文件操作、网页浏览器等),并设置了时间限制和其他参数。
代理配置
代理配置存储在agents/aisi-basic-agent/config.yaml
文件中,包含了模型设置、环境变量和启动脚本等信息。
3. 评估层
评估层由nano
目录下的文件实现,负责协调代理执行和结果收集。核心类是PaperBench
和ExternalPythonCodingSolver
。
PaperBench类
@chz.chz
class PaperBench(PythonCodingEval):
reproduction: ReproductionConfig = chz.field(default_factory=ReproductionConfig)
judge: JudgeConfig = chz.field(default_factory=JudgeConfig)
# task args
paper_split: Literal["debug", "dev", "human", "testing", "all"] = chz.field(
default="all",
doc="Paper split to use. One of 'testing' (lca-on-the-line only), 'debug' (rice only), 'dev' (two papers), 'human' (papers used in human baseline), 'all' (full set)",
)
# 其他配置参数...
@override
async def get_instances(self) -> list[PBTask]:
# 创建评估任务实例的逻辑
...
这个类定义了评估的整体配置和流程,包括论文选择、复现设置和评判配置等。
ExternalPythonCodingSolver类
@chz.chz
class ExternalPythonCodingSolver(PythonCodingSolver):
name: str = "PaperBenchSolver"
agent_id: str
is_nvidia_gpu_env: bool = chz.field(
default=False, doc="Whether to make the local NVIDIA GPU available to the agent"
)
# 其他配置参数...
@asynccontextmanager
async def _start_computer(self, task: PBTask) -> AsyncGenerator[ComputerInterface, None]:
# 启动计算环境的逻辑
...
@override
async def run(self, task: ComputerTask) -> AsyncGenerator[Step | FinalResult, None]:
# 运行代理并收集结果的逻辑
...
这个类负责启动计算环境、运行代理并收集结果,是评估流程的核心实现。
4. 评判层
评判层位于judge
目录下,负责对代理的复现结果进行评分。核心类是Judge
抽象基类和各种具体的评判实现。
Judge抽象基类
class Judge(ABC):
def __init__(self, paper: Paper, submission_dir: Path, max_depth: int = 999):
self.paper = paper
self.submission_dir = submission_dir
self.max_depth = max_depth
self.rubric = self._load_rubric()
self.graded_task_tree: GradedTaskNode | None = None
@abstractmethod
async def grade(self) -> GradedTaskNode:
raise NotImplementedError
def _load_rubric(self) -> TaskNode:
# 加载评分标准的逻辑
...
这个抽象类定义了评判系统的基本接口,具体的评判实现(如SimpleJudge
)需要继承并实现grade
方法。
评分任务树
评分系统使用TaskNode
数据结构来表示评分标准,定义在rubric/tasks.py
文件中:
@dataclass(frozen=True, kw_only=True)
class TaskNode:
id: str
requirements: str
weight: int
sub_tasks: Sequence[Self] = field(default_factory=list)
task_category: str | None = None
finegrained_task_category: str | None = None
# 各种方法...
5. 展示层
展示层由gui
目录下的文件实现,提供了Web界面来可视化和编辑评分任务树。
Flask应用
@app.route("/")
def index() -> str | Response:
with lock: # Use lock to support concurrent requests
try:
with open(app.config["PATH_TO_PAPER"] / app.config["RUBRIC_FILE_NAME"], "r") as f:
data = json.load(f)
task_node = app.config["NODE_TYPE"].from_dict(data)
if app.config.get("GRADED", False):
task_node = update_all_grades(task_node)
with open(app.config["PATH_TO_PAPER"] / app.config["RUBRIC_FILE_NAME"], "w") as f:
json.dump(task_node.to_dict(), f, indent=4)
template = "rubric.html"
return render_template(
template,
task_node=task_node,
valid_task_categories=VALID_TASK_CATEGORIES,
use_api=app.config["USE_API"],
)
except Exception as e:
return jsonify(
{
"status": "error",
"message": f"Error fetching the task tree: {e}",
}
)
这个Flask应用提供了RESTful API来操作评分任务树,并使用HTML模板渲染界面。
6. 监控系统
监控系统位于monitor
目录下,负责监控代理的执行过程,检查是否存在违规行为。
BasicMonitor类
class BasicMonitor(Monitor):
"""Simple implementation that checks for occurrences of blacklisted terms with git clone, curl, or wget commands in agent logs."""
def check_log(self, log_file: str) -> MonitorResult:
# 检查日志文件的逻辑
...
def _contains_command(self, context: list[str]) -> bool:
"""Check if the context contains git clone, curl, or wget commands."""
commands = ["git clone", "curl", "wget"]
for line in context:
for cmd in commands:
if cmd in line:
return True
return False
这个类实现了基本的监控功能,检查代理日志中是否存在使用黑名单URL和命令的情况。
7. 脚本工具
项目提供了多个脚本工具来简化常见操作,如run_reproduce.py
和run_judge.py
。
复现脚本
async def reproduce(
computer: ComputerInterface,
submission_path: Path,
logger: BoundLogger,
timeout: float | None = None,
use_py3_11: bool = False,
make_venv: bool = False,
) -> ReproductionMetadata:
# 复现论文的逻辑
...
这个脚本负责在指定的计算环境中运行复现脚本,并收集复现结果。
评判脚本
async def main(
submission_path: Path,
paper_id: str,
judge_type: str,
max_depth: int,
out_dir: Path,
code_only: bool,
completer_config: TurnCompleter.Config | None = None,
resources_provided: bool = False,
) -> None:
# 运行评判的逻辑
...
这个脚本负责对代理的复现结果进行评分,并保存评分结果。
数据结构设计
PaperBench定义了多种数据结构来表示系统中的关键实体:
- Paper:表示一篇论文及其相关信息
- Agent:表示一个AI代理及其配置
- TaskNode:表示评分任务树中的一个节点
- GradedTaskNode:表示已评分的任务节点
- ReproductionMetadata:存储复现过程的元数据
- PaperBenchResult:存储评估结果
- PaperBenchGrade:存储评分结果
这些数据结构使用Python的dataclasses模块定义,提供了类型安全和清晰的接口。
工作流程
PaperBench的典型工作流程如下:
- 准备阶段:加载论文数据和代理配置
- 评估阶段:启动代理,执行复现任务
- 监控阶段:监控代理执行过程,检查违规行为
- 评判阶段:对复现结果进行评分
- 展示阶段:展示和分析评分结果
详细工作流程图
┌─────────────────────────────┐
│ 准备阶段 │
│ (加载论文和代理配置) │
└───────────┬─────────────────┘
↓
┌─────────────────────────────┐
│ 评估阶段 │
│ (启动代理,执行复现任务) │
└───────────┬─────────────────┘
↓
┌─────────────────────────────┐
│ 监控阶段 │
│ (监控代理执行过程) │
└───────────┬─────────────────┘
↓
┌─────────────────────────────┐
│ 评判阶段 │
│ (对复现结果进行评分) │
└───────────┬─────────────────┘
↓
┌─────────────────────────────┐
│ 展示阶段 │
│ (展示和分析评分结果) │
└─────────────────────────────┘
技术栈分析
PaperBench使用了以下关键技术:
- Python:主要编程语言
- Asyncio:异步编程支持
- Flask:Web界面开发
- Docker:容器化执行环境
- Structlog:日志管理
- OpenAI API:LLM集成
- Chz:配置管理
- Blobfile:文件系统抽象
扩展性和定制化
PaperBench的设计考虑了扩展性和定制化需求:
- 插件式代理系统:支持多种AI代理的集成
- 可扩展的评判系统:支持多种评判方法的实现
- 配置驱动:通过配置文件定制系统行为
- 模块化设计:各组件之间松耦合,易于替换和扩展
使用示例
运行评估
python -m paperbench.nano.entrypoint --solver.agent_id aisi-basic-agent --paper_split debug
运行复现
python -m paperbench.scripts.run_reproduce --submission-path /path/to/submission --paper-id paper1
运行评判
python -m paperbench.scripts.run_judge --submission-path /path/to/submission --paper-id paper1 --judge simple --model gpt-4
启动Web界面
python -m paperbench.gui.app --path-to-paper /path/to/paper --rubric-file-name rubric.json
总结
PaperBench提供了一个全面的框架来评估AI代理复现学术论文的能力。通过模块化设计和灵活的配置系统,它支持多种代理类型和评判方法,能够适应不同的评估需求。无论是研究人员希望测试AI代理的能力,还是开发人员希望改进AI代理的复现性能,PaperBench都是一个强大的工具。
随着AI技术的不断发展,PaperBench也在不断演进,未来可能会添加更多功能,如支持更多代理类型、改进评判算法、增强可视化功能等。通过开源社区的贡献,PaperBench有望成为AI复现学术研究领域的标准工具。