NASA 支出数据表 `spending` 全解析:openai-agents-python Text-to-SQL 示例的 schema 设计、列语义与查询陷阱
发布时间:2026/9/12 11:11:55来源:尧图网络
NASA 支出数据表spending全解析openai-agents-python Text-to-SQL 示例的 schema 设计、列语义与查询陷阱【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-pythonspending是 openai-agents-python 仓库中 NASA Spending Text-to-SQL Agent 示例的核心数据表每一行代表 NASA 联邦奖励prime award上的一次资金交易初始义务、修改、修订或冲销 de-obligation全表以一表平铺的宽表设计服务自然语言问答。本文以 schema/tables/spending.md 为骨架结合 setup_db.py、sql_capability.py 与 agent.py 的源码实现逐列讲解字段语义、合同/资助专有列划分、聚合与模糊匹配的查询陷阱并给出可直接运行的 SQL 模式——读完你将能够独立编写针对该表的准确聚合查询理解义务额 vs 合同上限等预算口径差异并为 Text-to-SQL Agent 编写高质量 schema 文档。一、表定位一行为一笔交易而非一个奖励spending表的数据来源是 USAspending.gov默认抓取 FY2021–FY2025可通过setup_db.py的--start-fy/--end-fy调整。它的建模粒度是整个示例中最关键的设计决策每行是一条 prime award transaction——可能是初始义务initial obligation、修改modification、修订amendment或冲销de-obligation一个奖励award对应多行award_id相同的多行共享同一个唯一奖励标识代表该奖励生命期内的多次资金动作数据库只包含一个spending表其余聚合按年度、按中心、按承接方全部通过 SQL 在查询时完成而不是预聚合。这一宽表 查询时聚合的设计与 overview.md 中的描述一致也是 agent 的run_sql工具sql_capability.py被设计为优先使用 GROUP BY、SUM、COUNT、AVG 聚合而非返回大量原始行的根本原因。二、完整列定义39 列以下为spending表的全部列。该表结构在 setup_db.py 中以CREATE TABLE IF NOT EXISTS spending (...)定义与本文档完全对应ColumnTypeDescriptionrowidINTEGER PK自增行标识award_idTEXT唯一奖励标识。一个奖励有多个交易时多行共享同一 award_idaward_piid_fainTEXT人类可读的奖励编号合同为 PIID如 NNJ13ZBG001资助为 FAINparent_award_piidTEXT父级 IDV 合同编号将任务/交付订单关联到其父合同载体仅合同award_typeTEXT分类contract、grant、idv 或 otherdescriptionTEXT交易或奖励用途的自由文本描述action_dateTEXT本次交易日期ISO 8601YYYY-MM-DDfiscal_yearINTEGER联邦财年10 月至次年 9 月FY2024 2023 年 10 月 - 2024 年 9 月federal_action_obligationREAL本笔交易的美元金额。冲销de-obligation时可为负数total_obligationREAL截至本笔交易时该奖励的累计义务额base_and_all_options_valueREAL合同含全部未行使期权的潜在上限总额。仅合同资助为 NULLrecipient_nameTEXT承接方组织的法定名称recipient_parent_nameTEXT母公司名称如 Lockheed Martin Space 等子公司归并到 Lockheed Martin Corporation。仅合同资助为空recipient_stateTEXT承接方地址的两位美国州代码。境外承接方为空recipient_cityTEXT承接方所在城市recipient_countryTEXT国家名称如 UNITED STATES、UNITED KINGDOMawarding_officeTEXT授出奖励的 NASA 中心/办公室如 GODDARD SPACE FLIGHT CENTER、JET PROPULSION LABORATORY值为大写funding_officeTEXT提供资金的 NASA 中心/办公室通常与 awarding 相同值为大写naics_codeTEXT北美行业分类系统代码。主要用于合同资助可能为空naics_descriptionTEXTNAICS 的人类可读描述psc_codeTEXT合同使用产品/服务代码PSC资助使用 CFDA 编号。同一列存放两套不同分类体系psc_descriptionTEXTPSC合同或 CFDA 项目资助的人类可读描述place_of_performance_stateTEXT履约地所在州。合同为两位代码资助为全名。可能与 recipient_state 不同place_of_performance_cityTEXT履约地所在城市period_of_perf_startTEXT奖励履约期开始日期YYYY-MM-DDperiod_of_perf_endTEXT奖励履约期结束日期YYYY-MM-DD。为当前结束日期可能反映延期extent_competedTEXT竞争程度取值如 Full and Open Competition、Not Available for Competition、Not Competed 等。仅合同资助为空type_of_set_asideTEXT小企业预留类型如 Small Business Set-Aside、8(a) Set-Aside、HUBZone Set-Aside、Service-Disabled Veteran-Owned Small Business Set-Aside、Women-Owned Small Business 等。仅合同number_of_offersINTEGER收到的报价/投标数量。1 表示即使技术上经过竞争也实质上为单一来源。仅合同资助为 NULLcontract_pricing_typeTEXT定价结构Firm Fixed Price、Cost Plus Fixed Fee、Cost No Fee、Time and Materials 等。仅合同business_typesTEXT资助奖励的承接方组织类型非营利、大学、州政府、部落等。仅资助合同为空三、列的三层结构通用列、合同专有列与资助专有列从上表可以提炼出该 schema 的核心设计模式——多套奖励体系共存于一张表通过空值 专有列区分通用列两类 CSV 都填充award_id、award_piid_fain、award_type、description、action_date、fiscal_year、federal_action_obligation、total_obligation、recipient_name、recipient_state/city/country、awarding_office、funding_office、place_of_performance_state/city、period_of_perf_start/end。合同/IDV 专有列base_and_all_options_value、recipient_parent_name、parent_award_piid、extent_competed、type_of_set_aside、number_of_offers、contract_pricing_type仅在合同/IDV 中填充。资助专有列business_types仅在资助奖励中填充。这种空值约定在源码中有直接体现setup_db.py 的_TYPE_COLUMNS映射表为 contracts 与 assistance 分别定义了列映射——例如合同的psc_code来自product_or_service_code而资助的psc_code来自cfda_number合同的recipient_parent_name来自recipient_parent_name而资助的该列映射为空字符串不填充。_SHARED_COLUMNS同文件 L329-L344则列出两类 CSV 共用的列名。这意味着查询时必须牢记同一列名在不同 award_type 下语义可能完全不同尤其psc_code/psc_description这是该表最容易被 Agent 误解的地方。四、award_type的取值与派生规则award_type只有四个值contract、grant、idv、other由 USAspending 的类型码派生而来。源码 setup_db.py 定义了映射合同码A/B/C/D→contract资助码02/03/04/05→grantIDV 码IDV_A/IDV_B/IDV_B_A/IDV_B_B/IDV_B_C/IDV_C/IDV_D/IDV_E→idv此外 classify_award_type 有一个兜底逻辑当类型码不在预期集合中时若award_id以CONT_IDV_前缀开头则判为idv否则为other。这解释了为什么表中可能出现other——它是类型码无法识别时的兜底值查询时应予以留意。五、查询陷阱与正确聚合模式Notes 详解5.1 聚合到奖励级必须 GROUP BY award_id要得到每个奖励的总支出必须使用GROUP BY award_id配合SUM(federal_action_obligation)。total_obligation只是各交易时点的快照snapshot不代表最终总额SELECT award_id, award_piid_fain, SUM(federal_action_obligation) AS total_spent FROM spending GROUP BY award_id ORDER BY total_spent DESC LIMIT 10;5.2 合同上限 vs 义务额两个数字口径完全不同base_and_all_options_value是合同潜在最大值含未行使期权total_obligation是实际承诺金额。文档明确指出一份合同可能是 500M 上限、仅义务了 10M。查询合同金额时务必先确认口径-- 对比各合同的上限与累计义务 SELECT award_piid_fain, MAX(base_and_all_options_value) AS ceiling_value, SUM(federal_action_obligation) AS obligated FROM spending WHERE award_type contract GROUP BY award_id ORDER BY ceiling_value DESC LIMIT 10;5.3 母公司归并COALESCE NULLIF 惯用法承接方分析最常用的技巧是用COALESCE(NULLIF(recipient_parent_name, ), recipient_name)将子公司归并到母公司名下该列仅合同填充SELECT COALESCE(NULLIF(recipient_parent_name, ), recipient_name) AS entity, SUM(federal_action_obligation) AS total FROM spending GROUP BY entity ORDER BY total DESC LIMIT 10;5.4 承接方名称不一致模糊匹配同一实体在不同行的recipient_name可能有细微差异如 BOEING CO vs THE BOEING COMPANY。文档建议使用LIKE或UPPER()做模糊匹配而不是精确等值比较。5.5 负义务额冲销与修正federal_action_obligation可以为负de-obligation、修正。求和SUM得到的是净支出。在做金额聚合时不应剔除负值否则会高估真实支出。这也是 agent.py 的DEVELOPER_INSTRUCTIONS中要求 Agent 注意的数据陷阱之一同文件还提示部分承接方因隐私被掩码为 MULTIPLE RECIPIENTS 或 REDACTED DUE TO PII。5.6 分类体系的错位NAICS 与 PSC/CFDAnaics_code/naics_description仅合同填充资助为空psc_code对合同是产品/服务代码对资助是 CFDA 编号psc_description对应描述。两套分类体系存在同一列查询时最好先按award_type过滤避免把 CFDA 编号误当 PSC 统计。六、开箱即用的常用查询模式overview.md 给出了五组面向该表的典型分析查询可以直接在run_sql中使用-- 按财年统计总支出 SELECT fiscal_year, SUM(federal_action_obligation) AS total FROM spending GROUP BY fiscal_year ORDER BY fiscal_year; -- 按母公司归并后的 Top 承接方 SELECT COALESCE(NULLIF(recipient_parent_name, ), recipient_name) AS entity, SUM(federal_action_obligation) AS total FROM spending GROUP BY entity ORDER BY total DESC LIMIT 10; -- 按奖励类型统计 SELECT award_type, COUNT(*), SUM(federal_action_obligation) AS total FROM spending GROUP BY award_type; -- 竞争 vs 单一来源合同 SELECT extent_competed, COUNT(DISTINCT award_id) AS awards, SUM(federal_action_obligation) AS total FROM spending WHERE award_type contract GROUP BY extent_competed ORDER BY total DESC; -- 按 NASA 中心统计 SELECT awarding_office, SUM(federal_action_obligation) AS total FROM spending GROUP BY awarding_office ORDER BY total DESC;七、源码级佐证表结构、索引与建库流程7.1 建表与索引setup_db.py 中的SCHEMA_SQL除了建表还创建了 12 个索引覆盖了该表最频繁的查询路径idx_spending_award_id按奖励聚合、idx_spending_fiscal_year按财年聚合idx_spending_award_type按类型过滤、idx_spending_recipient/idx_spending_recipient_parent承接方分析idx_spending_state、idx_spending_action_date、idx_spending_naics、idx_spending_obligation金额排序、idx_spending_extent_competed、idx_spending_perf_start、idx_spending_awarding_office按中心统计索引设计与上述查询模式一一对应说明GROUP BY 聚合 维度过滤是该表的标准访问形态。7.2 建库流程与幂等性数据库在沙箱内首次运行时由setup_db.py自动构建需沙箱联网通过 USAspending bulk download API 按财年逐个提交下载请求API 限制 date_range 最大 1 年解析合同与资助两类 CSV 后写入spending表并同步抓取官方术语表生成 schema/glossary.md149 个术语。脚本是幂等的数据库已存在且覆盖全部请求财年则跳过可通过--force重建--start-fy/--end-fy控制财年范围默认 2021–2025。7.3 只读查询护栏与行数限制Agent 执行 SQL 的唯一入口是run_sql工具sql_capability.py对spending表的查询受到五层防护连接层SQLite 以?moderoURI 只读打开PRAGMAquery_only ON即使校验被绕过也无法写入语句校验仅允许SELECT、WITH、EXPLAIN、PRAGMA开头行数限制默认最多展示 100 行max_display_rows同时最多保存 10,000 行到可下载 CSVmax_csv_rows超出会标记truncated超时查询超过 30 秒timeout_seconds即被终止并提示Try a simpler query or add a LIMIT。其中展示限制与 CSV 限制分离的设计同文件_QUERY_RUNNER_SCRIPT与文档中展示最多 100 行、最多 10,000 行可下载的说明完全一致。查询结果以 JSON 返回columns/rows/row_count/truncated字段便于 Agent 判断是否需要补充说明完整结果可通过下载链接获取。八、schema 文档在 Text-to-SQL Agent 中的消费方式spending.md不是孤立的参考文档而是整个示例两层 schema 知识设计的一部分紧凑摘要层overview.md含关键列与 5 组查询模式在 agent.py 中被直接读入系统提示词随每轮对话常驻模型上下文按需详情层schema/tables/spending.md与schema/glossary.md作为工作区文件随 Manifest 注入沙箱agent.py的build_agent中通过LocalDir(srcSCHEMA_DIR)挂载Agent 需要列级细节或官方术语定义时用 Shell 能力按需读取。因此本文档的价值不仅在于人工查阅它同时也是 LLM 生成准确 SQL 的列语义说明书。文档中Contracts-only columnsGrants-only columns的显式划分、负义务额提示、母公司归并惯用法等都是为了让 Agent 避免生成语义错误的聚合查询。若你想为其他数据集复刻该示例为每张表编写一份类似spending.md的列级文档是提升 Text-to-SQL 准确率最直接的手段。九、运行与复现完整的端到端示例位于 examples/sandbox/extensions/daytona/usaspending_text2sql其整体架构与运行方式见该目录下的 README.md。简要复现步骤从仓库根目录执行# 安装带 Daytona 支持的依赖 uv sync --extra daytona # 设置必需环境变量LLM 与沙箱 export OPENAI_API_KEYsk-... export DAYTONA_API_KEY... # 启动交互式问答首次运行会在沙箱内自动建库 uv run python -m examples.sandbox.extensions.daytona.usaspending_text2sql.agent启动后可以直接对spending表提问例如What are NASAs top 10 contractors by total spending?、Which NASA centers award the most contracts?、Show me grants to universities in California。Agent 会通过run_sql执行上述模式的聚合查询并在终端中以带高亮的 SQL 与结果表格形式回显所有 SQL 及其结果还会以 JSONL 结构化事件写入.audit_log.jsonl便于事后核查 Agent 实际执行的查询是否符合本文档描述的语义。十、小结spending表用一个 39 列的宽表承载了 NASA 合同、资助与 IDV 三类奖励的完整交易历史其核心使用法则可归结为四句话聚合永远按award_id分组并对federal_action_obligation求和区分合同上限与实际义务两个金额口径用COALESCE(NULLIF(recipient_parent_name,), recipient_name)归并母公司牢记合同专有列与资助专有列的空值边界。掌握这些规则无论是人工编写分析 SQL还是为 Text-to-SQL Agent 提供 schema 提示都能避免最常见的口径错误。【免费下载链接】openai-agents-pythonA lightweight, powerful framework for multi-agent workflows项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网