openai-agents-python 沙箱实战:基于 SandboxAgent 构建带源码引用的 10-K 金融问答 Agent
openai-agents-python 沙箱实战基于 SandboxAgent 构建带源码引用的 10-K 金融问答 Agent【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python导读本文围绕 openai-agents-python 仓库中的dataroom_qa沙箱教程示例完整讲解如何构建一个检索优先retrieval-first的金融问答 Agent它在一个有界的合成 10-K 年报语料包上运行借助沙箱内的bash与文件检索能力查找证据并以可点击的源码级引用文本按行号、PDF 按页码回答财务问题。读完本文你将掌握沙箱 manifest 的加载方式、SandboxAgent的配置要点、Unix-local 与 Docker 两种运行模式以及如何为自己的金融语料设计可验证的引用协议。一、示例目标在合成 10-K 数据包上做有依据的金融问答examples/sandbox/tutorials/dataroom_qa/README.md开宗明义本示例的目标是Answer grounded financial questions over a synthetic 10-K packet即基于一个合成 10-K 数据包回答有依据grounded的财务问题。这里的数据包使用合成公司数据但文档形态完全模仿真实年报节选MDA管理层讨论与分析文本使用 10-K 的Part II, Item 7结构财务报表 PDF 与脚注文本使用Part II, Item 8结构。合成公司名为HelioCart, Inc.财务口径保持一致性设计例如 MDA 中注明净收入与收入可互换使用、分部脚注注明订阅与交易平台收入与平台分部收入是同一指标这些细节都用于考验 Agent 在交叉引用多个文件时是否能保持口径统一。该模式的价值在于在一个有界的金融语料上做检索优先的 Agent 工作流让每一个指标和解释都与源文件保持绑定。相比直接依赖模型记忆作答这种设计天然支持审计、追责与二次核验。二、数据准备运行 fixture 生成器示例的输入数据并不是预置在仓库中的静态文件而是由生成器脚本产出。从仓库根目录执行uv run python examples/sandbox/tutorials/data/dataroom/setup.pyexamples/sandbox/tutorials/data/dataroom/setup.py负责生成全部 8 个 fixture 文件文件内容对应 10-K 章节10-k-mdna-overview.txt收入、毛利率、营业利润的年度对比Part II, Item 710-k-mdna-liquidity.txt经营现金流、资本开支、自由现金流Part II, Item 710-k-note-segments.txt分部收入Platform / ServicesPart II, Item 8, Note 410-k-note-geography.txt地区收入Americas / EMEA / APACPart II, Item 8, Note 510-k-note-balance-sheet.txt现金、递延收入等资产负债表指标Part II, Item 8, Note 710-k-statements-of-operations.pdf经营成果表净收入/毛利/营业利润单页 PDF10-k-balance-sheets.pdf资产负债表现金/应收/递延收入单页 PDF10-k-statements-of-cash-flows.pdf现金流量表经营现金流/资本开支/自由现金流单页 PDF2.1 fixture 生成器的实现要点生成器本身就是一个值得学习的小工具它展示了如何在不依赖任何第三方 PDF 库的情况下手工构造可检索的合成 PDFwrite_plain_pdf()直接按 PDF 1.4 规范手工拼装对象Catalog / Pages / Page / Contents / Font用 Helvetica Type1 字体逐行写出文本并生成合法的xref交叉引用表与trailerwrite_financial_pdf()将表格行用 | .join(row)拼成纯文本行写入 PDF保证每行内容可被文本抽取工具读取pdf_escape()负责转义 PDF 字符串中的\、(、)等特殊字符。从源码结构看这样设计的目的是让每个 PDF 恰好是单页纯文本方便 Agent 用pypdf等工具按页码定位证据与 README 中约定的n引用格式一一对应。三、运行方式Unix-local 与 Docker 双模式3.1 前置条件运行前需要在 shell 环境中设置OPENAI_API_KEY并先生成 fixture 数据见上一节。main.py启动时会校验数据文件是否存在若缺失会直接提示先运行setup.py。3.2 Unix-local 模式默认uv run python examples/sandbox/tutorials/dataroom_qa/main.py这是默认运行方式直接在本机以 Unix-local 沙箱执行无需 Docker。首次回答完成后示例会保持沙箱会话打开通过 Rich 渲染的交互提示符接收追问终端会提示 Enter follow-up prompts. Press Ctrl-D or Ctrl-C to finish.。3.3 一次性运行非交互uv run python examples/sandbox/tutorials/dataroom_qa/main.py --no-interactive传入--no-interactive后脚本只执行预设的问答回合并退出适合 CI、批量验证或自动化场景。3.4 Docker 模式要复用同一个 manifest 在 Docker 中运行需要先构建共享教程镜像再传入--dockerdocker build --tag sandbox-tutorials:latest examples/sandbox/tutorials uv run python examples/sandbox/tutorials/dataroom_qa/main.py --dockerexamples/sandbox/tutorials/Dockerfile揭示了镜像的依赖构成基础镜像python:3.14-slim内置uv安装ca-certificates、git、poppler-utilsPDF 文本抽取、ripgrep证据检索通过uv pip install安装pypdf用于解析 PDF 文本。这些工具正是沙箱 Agent 在运行时执行检索命令所需的运行时依赖。3.5 命令行参数速查main.py通过argparse暴露了 4 个参数参数默认值说明--modelgpt-5.4-mini使用的模型名称--question见下文默认问题发送给 Agent 的提示词--dockerFalse使用 Docker 沙箱替代 Unix-local--imagesandbox-tutorials:latest与--docker搭配使用的镜像名--no-interactiveFalse只跑脚本回合跳过终端追问默认问题DEFAULT_QUESTION本身就是一份很好的追问设计范例覆盖了利润表与现金流两个维度的交叉验证How did revenue, gross margin, operating income, and operating cash flow change in FY2025 versus FY2024, and which segment contributed the most revenue?要回答这个问题Agent 至少需要检索 MDA 概览收入/毛利率/营业利润、流动性 MDA经营现金流、分部脚注收入贡献最大的分部并核对 PDF 中的经营成果表体现了多文件交叉检索的设计意图。四、核心实现拆解main.py 的五层结构examples/sandbox/tutorials/dataroom_qa/main.py是示例的全部实现其结构可以拆解为五个关键环节4.1 第 1 层指令加载README 中 How instructions are loaded 一节说明启动时wrapper 将本文件夹的AGENTS.md加载进 Agent 指令。在代码中AGENTS.md的内容以dedent字符串硬编码在main.py中AGENTS_MD常量内容为# AGENTS.md Answer the users financial question using only the synthetic 10-K packet in data/. ## Evidence citations - Cite every material claim with markdown links in these formats (no bare links): - 1 for text sources - 2 for PDF sources (each synthetic PDF is one page) - Use rg and sed to find and quote exact evidence; do not use data/setup.py. Keep the final answer direct and finance-oriented.这段指令有三个关键约束只用data/目录内的合成 10-K 数据包作答防止模型凭记忆编造每一条实质性主张都必须带引用且规定了两种精确格式文本按行号、PDF 按页码禁止裸链接明确工具使用方式用rg和sed查找并引用精确证据且禁止调用data/setup.py防止 Agent 重新生成或篡改语料。4.2 第 2 层manifest 构建manifest Manifest( entries{ AGENTS.md: File(contentAGENTS_MD.encode(utf-8)), data: LocalDir(srcDATAROOM_DATA_DIR), } )这对应 README 中 builds a hard-coded manifest that maps the shared SEC packet ... into the sandbox asdata/... 的描述将共享的 SEC 数据包从examples/sandbox/tutorials/data/dataroom/映射进沙箱的data/目录同时在沙箱根目录注入一份AGENTS.md。其中LocalDir来自agents.sandbox.entries表示把宿主机目录作为整体挂载进沙箱File用于在沙箱内直接创建文本文件。Manifest类型定义在 src/agents/sandbox/manifest.py它支持文件、目录、挂载、快照等多种条目类型并在校验失败时抛出InvalidManifestPathError。4.3 第 3 层SandboxAgent 配置agent SandboxAgent( nameDataroom Analyst, modelmodel, instructionsAGENTS_MD, capabilities[Shell()], )SandboxAgent定义在 src/agents/sandbox/sandbox_agent.py是Agent的沙箱专用子类。从源码注释可以确认一个重要设计原则沙箱的传输细节client、client options、会话不存储在 Agent 上而是在运行时通过RunConfig(sandbox...)注入。这使 Agent 定义与沙箱环境解耦同一个 Agent 可以复用于不同后端。capabilities[Shell()]为该 Agent 启用了 bash shell 能力Shell来自agents.sandbox.capabilities。README 的 Demo shape 一节明确示例的运行时原语就是sandbox-local bash / file search——即模型通过沙箱内的 bash 工具执行rg/sed等命令来完成证据检索而非依赖云端 RAG 工具。4.4 第 4 层沙箱客户端与会话client, sandbox await create_sandbox_client_and_session( manifestmanifest, use_dockeruse_docker, imageimage, )该辅助函数定义在 examples/sandbox/tutorials/misc.py非 Docker 模式UnixLocalSandboxClient()来自agents.sandbox.sandboxes.unix_local在宿主机本地创建沙箱Docker 模式通过docker.from_env()构造DockerSandboxClient并传入DockerSandboxClientOptions(imageimage)build_docker_environment()会探测当前 Docker 上下文包括 Docker Desktop、Colima 等自动设置DOCKER_HOST避免硬编码某个具体守护进程提供商。会话创建后进入async with sandbox:生命周期块finally中调用await client.delete(sandbox)确保清理。4.5 第 5 层流式运行与交互循环result Runner.run_streamed( agent, conversation, max_turns20, run_configRunConfig( sandboxSandboxRunConfig(sessionsandbox), tracing_disabledTrue, workflow_nameDataroom QA example, ), ) return await print_streamed_result(result)要点使用Runner.run_streamed进行流式运行max_turns20限制最大工具调用轮数防止检索循环失控通过RunConfig(sandboxSandboxRunConfig(sessionsandbox))把已创建的沙箱会话注入本次运行对应第 4.3 节提到的运行时注入设计tracing_disabledTrue关闭 tracingworkflow_name标记工作流名print_streamed_result遍历result.stream_events()用print_event定义于misc.py基于 Rich 面板渲染逐条展示 reasoning、工具调用含exec_command的 bash 语法高亮、工具输出、消息输出最后以绿色面板打印最终回答首轮完成后run_interactive_loop进入追问循环除非--no-interactive每次追问都会带着完整对话历史再次走run_turn。五、预期产物流式回答中的源码级引用README 的 Expected artifacts 一节给出了可验证的验收标准在流式 Agent 回答中得到带直接引用的答案引用遵循固定格式文本摘录n—— 精确到行号合成 PDF单页n—— 精确到页码。这种每个数字背后都有源文件坐标的输出形态正是金融问答场景最看重的可审计性读者可以把回答中的任何一个指标如 FY2025 收入 1,284 百万美元、毛利率 71.4%、营业利润 186 百万美元直接回溯到对应文件的对应行/页快速完成人工核验。六、深入理解沙箱检索机制与镜像依赖6.1 为什么用沙箱内 bash 检索而非预置 RAG从main.py可以看到示例没有使用file_search等云端检索工具而是刻意把检索能力限定为sandbox-local bash/file searchcapabilities[Shell()]。结合 examples/sandbox/tutorials/Dockerfile 中预装ripgrep、poppler-utils、pypdf的事实可以推断设计意图是让检索逻辑完全透明、可复现——rg/sed是确定性的命令行工具让 Agent 的检索行为在受控沙箱内执行与宿主机隔离让 PDF 文本抽取能力pypdf与纯文本检索rg在同一声明式镜像内就绪Docker 与 Unix-local 两种模式行为一致。6.2 相关源码入口深入理解本示例可继续阅读以下文件examples/sandbox/tutorials/dataroom_qa/main.py示例主程序manifest、Agent、流式运行、参数解析examples/sandbox/tutorials/data/dataroom/setup.py合成 10-K 语料生成器examples/sandbox/tutorials/misc.py沙箱客户端/会话创建、Rich 事件渲染、交互循环examples/sandbox/tutorials/Dockerfile教程共享 Docker 镜像ripgrep / poppler-utils / pypdfsrc/agents/sandbox/sandbox_agent.pySandboxAgent定义与运行时注入沙箱的设计说明src/agents/sandbox/manifest.pyManifest类型与校验逻辑src/agents/sandbox/sandboxes/unix_local.py 与 src/agents/sandbox/sandboxes/docker.py两种沙箱后端实现。七、小结从示例迁移到自己的金融语料dataroom_qa虽然针对合成数据但其模式可直接迁移到真实场景语料准备把任意有界的金融文档集年报、招股书、季报整理为文本或单页 PDF保证可被rg与pypdf检索manifest 映射用Manifest把宿主机语料目录映射进沙箱的data/并注入一份约束明确的AGENTS.md指令约束在指令中强制只用data/作答 每条主张必须带n引用能力裁剪只开启Shell()能力让 Agent 用确定性命令检索证据运行与验收Unix-local 快速调试、Docker 保证环境一致用--no-interactive接入自动化回归。当你的业务需要每一个数字都能被追溯到源文件的可审计问答时这个检索优先 沙箱执行 源码级引用的组合就是一个开箱即用的参考实现。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考