← 返回文章列表

用 uv 交付一个研究脚本:依赖、样本、命令一起带走

作者:杨轩

怎样让别人拿到研究脚本后,能从同一个起点重跑?

用一个能运行的合成实验台账练习,说明uv内联依赖、脚本锁文件和预期结果怎样一起交付,附可下载脚本与样本。

拿到一个Python脚本,最容易卡住的地方有时不是算法:不知道用哪个Python、缺什么包,也不知道跑完该看到什么。把这些说明和脚本一起交付,下一位读者才有机会从同一个起点重跑。

这篇用uv做一个小练习:读取六条合成实验记录,用DuckDB汇总状态,输出JSON。重点是把依赖、输入和执行命令带走。学会后,可以给数据检查教程和前视偏差练习的脚本补上同样的依赖头与锁文件。

先跑出一个结果

先按uv官方安装说明安装工具,然后下载脚本与样本包,解压、进入文件夹,运行:

uv run --locked --script report.py --input sample.csv --out report-01.json
uv run --no-project --python 3.12 check_report.py report-01.json

第一条生成报告,第二条核对样本哈希、汇总和DuckDB版本,成功时显示OK。首次需要联网准备依赖;本机没有匹配Python时,uv还可能下载解释器。真正的CSV汇总只在本地执行。

包内已经附了report.py.lock,读者无需先重新锁依赖。输出目录须已存在,结果文件不会被覆盖,再跑一次请改成report-02.json。这让上次结果可以留着比较。

你应该看到什么

样本里的六条记录全部是人为编写的,passed、failed、pending只是练习标签。脚本不会真正运行数据检查,也不会判断实验结论是否成立。

阶段 总记录 passed failed pending
data-check 3 2 1 0
lookahead-check 3 1 1 1

report-01.json还会记录输入CSV的SHA256、Python和DuckDB实际版本。汇总相同但输入哈希不同,就不能说使用了同一份样本;Python补丁版本不同则会如实显示,不要求整份报告逐字节相同。

拿来管理自己的实验时,可以把每次运行作为一行,填上阶段和状态。check_report.py专门核对本包样本;换数据后,应自行编写预期结果并调整核对脚本,不能继续用六行样本的答案。这里汇总的是你记录的标签,不代表框架性能比较或研究质量排名。

脚本开头写清依赖

打开report.py,最前面有这几行:

# /// script
# requires-python = ">=3.12,<3.13"
# dependencies = ["duckdb==1.5.6"]
# ///

这是PEP 723内联元数据。uv据此选择Python并准备脚本环境;用这份元数据运行时,不使用所在项目的依赖。格式与操作见uv脚本指南。本例限制Python 3.12,是为了缩小练习范围,不表示其他版本不能做研究。

脚本通过Python读取CSV,再将三列值作为参数写进DuckDB内存表,按阶段计数。它不拼接输入为SQL,不创建持久数据库,也不连接行情接口。想看这部分API,可对照DuckDB Python文档。

依赖头和锁文件,各解决一步

依赖头告诉别人“需要什么”;锁文件保存解析后的具体发行包与哈希。即使本例只有一个直接依赖,也保留锁文件,方便以后增加依赖时沿用同一做法。

当你修改依赖时,在自己工作副本里重新生成:

uv lock --script report.py

生成的是紧挨脚本的report.py.lock。多文件项目常用的uv.lock是另一种组织方式,不要把两者混用。把新锁文件与代码一同交付,再用前面的--locked命令运行。这个参数要求锁与依赖声明匹配,需要更新时会报错;脚本锁见脚本指南的锁定章节,参数说明见uv命令参考。

锁住环境仍有边界:接口返回的数据可能变、随机过程可能变,操作系统也可能影响结果。输入快照、参数、预期输出仍要单独保留;一份锁文件不能证明研究判断正确。

真正交给别人时,至少带这几样

文件 作用
report.py 脚本和依赖头
report.py.lock 已解析的依赖锁
sample.csv 可以公开的小样本
expected-summary.json、check_report.py 预期结果和核对命令
README.md、manifest.json 运行说明、实测范围和文件哈希

本包另外附了源代码与样本的MIT许可,方便复制修改。第三方依赖仍使用各自许可,ZIP里没有打包Python或DuckDB环境。换成自己的资料时,可用合成样本说明接口和计算,不需要为了分享脚本公开整份研究数据库。

一两个独立脚本可以先这样交付。模块越来越多、需要共同开发或打包时,再整理成pyproject.toml项目;可以从uv项目指南继续学,不必在这个练习里搭完整工程。

三个常见卡点

提示锁文件需要更新。 先确认report.py与report.py.lock来自同一份交付包。如果是自己改了依赖,重新锁定并测试;直接去掉--locked,uv会在需要时重新解析依赖并更新脚本锁文件,运行的就可能不是交付时那组依赖。

下载失败,或者找不到Python。 先区分解释器准备与包下载失败,再按报错处理网络或安装问题。--offline只适用于所需资源已缓存的情况,下载包自身不保证离线启动。

提示已有输出文件。 换一个新的输出名即可。若输入列名、状态值或run_id有问题,脚本会停止;不要把失败时残留的旧报告误认为新结果。

这次实际验证了什么

在macOS arm64、uv 0.11.21、Python 3.12.2、DuckDB 1.5.6下,用独立脚本目录和隔离环境重建运行环境(复用已有依赖缓存),实际跑出了上表,并核对输入哈希。另检查了旧输出拒绝覆盖、重复run_id拒绝、依赖头与旧锁不一致时拒绝运行,以及缓存准备后的离线重跑。

空缓存首次下载在两分钟内未完成,未将其记为成功。这是同一台机器上的隔离环境验证,未在全新操作系统、Linux或Windows上实测。使用真实数据之后,还需要自己的预期结果,不能继续套用本包六行样本的答案。

下一次分享研究代码,可以先做到:别人拿到文件后,知道运行哪条命令、结果放在哪里,以及怎样判断跑出了预期结果。再把这套交付方式用于量化Agent的实验交接或AI研究工作流,沟通会具体得多。

本文为工具教程与AI辅助整理,脚本和合成样本由本站编写;不作为本人交易经验或收益记录。

本文代码与样本:资料与下载 →

让分享,成为交流的开始。

关于文章、AI 实践或阅读,有想法欢迎来信。