1
0
Files
2026-02-12 17:57:05 +08:00

9.0 KiB
Raw Permalink Blame History

Context

当前lyxy-runner-python skill要求用户在Python脚本顶部添加PEP 723元数据块来声明依赖这需要修改用户现有的脚本文件降低了使用便利性。此外现有实现总是使用临时文件即使在用户明确指定路径时也是如此。

该skill目前的工作流程

  1. 要求LLM生成包含PEP 723元数据的Python脚本
  2. 使用辅助脚本创建临时文件
  3. 写入脚本内容(包含元数据块)
  4. 使用uv run <temp_file_path>执行

现有实现的限制:

  • 用户必须修改现有脚本以添加PEP 723元数据
  • 总是使用临时文件,即使用户指定了存储路径
  • 无法智能识别uv项目每次都创建新的虚拟环境

Goals / Non-Goals

Goals:

  • 无需修改用户现有Python脚本即可使用uv执行
  • 自动解析脚本依赖并使用--with语法传递
  • 智能检测uv项目复用项目虚拟环境
  • 尊重用户指定的脚本路径,仅在未指定时使用临时文件
  • 保持跨平台兼容性Windows/macOS/Linux
  • 保持严格错误处理和调试支持

Non-Goals:

  • 不修改用户现有的脚本文件
  • 不实现复杂版本约束或依赖冲突解决交给uv
  • 不支持命令行参数或stdin输入保持现有限制
  • 不持久化虚拟环境(每次执行都是新的)

Decisions

决策1项目检测方法

选择: 使用uv sync --dry-run命令检测当前目录是否为uv项目

原因:

  • uv sync --dry-run是uv提供的官方方法能准确判断目录是否为有效的uv项目
  • 不仅检查pyproject.toml存在性还验证项目配置的有效性
  • 如果命令成功退出exit code 0则目录是有效的uv项目
  • 如果命令失败非零退出码则目录不是uv项目或配置无效

替代方案考虑:

  1. 仅检查pyproject.toml文件存在

    • 优点:简单快速
    • 缺点:无法验证文件有效性,可能误判
    • 拒绝理由:不够可靠,可能导致误判
  2. 检查.venv目录存在

    • 优点:可以检测已初始化的虚拟环境
    • 缺点uv项目可能尚未运行过sync没有.venv目录
    • 拒绝理由对未初始化的uv项目不友好

实现细节:

# 检测当前目录是否为uv项目
if uv sync --dry-run > /dev/null 2>&1; then
  # 是uv项目使用项目环境
  uv run <script_path>
else
  # 不是uv项目使用--with语法
  uv run --with package1 --with package2 <script_path>
fi

决策2依赖解析策略

选择: 使用大模型的分析能力直接从脚本内容提取import语句而非使用外部工具

原因:

  • 大模型已经理解脚本内容可以直接提取import语句
  • 避免引入新的依赖如ast模块解析工具
  • 大模型可以理解各种import语法变体import x, from x import y, import x as z等
  • 可以排除Python标准库模块只需检查是否为常见标准库名称

实现细节:

  1. 大模型分析脚本中的所有import语句
  2. 提取包名import pandas → pandas, from numpy import array → numpy
  3. 排除已知的标准库名称os, sys, json, pathlib, re等
  4. 去重后生成依赖列表

限制:

  • 大模型需要维护标准库列表可基于Python 3.10+标准库)
  • 对于动态导入(import)和条件导入,可能无法识别
  • 不支持解析requirements.txt或其他依赖文件只解析脚本内容

决策3路径处理策略

选择: 三层路径处理逻辑(用户指定 → 现有脚本 → 临时文件)

原因:

  • 优先尊重用户明确指定的路径
  • 对现有脚本直接执行,无需修改
  • 仅在大模型自主生成且未指定路径时使用临时文件

决策树:

用户是否指定脚本存储路径?
├─ 是:写入用户指定路径 → 执行
└─ 否:
    ├─ 用户是否指定现有脚本路径?
    │   ├─ 是:直接执行该脚本
    │   └─ 否:创建临时文件 → 执行

实现细节:

  • 用户指定路径示例:"在scripts/data.py中写入" → 写入scripts/data.py
  • 用户指定现有脚本:"运行analyze.py" → 执行analyze.py(读取内容解析依赖)
  • 大模型自主生成:使用get_temp_path.py辅助脚本创建临时文件

决策4执行命令构造

选择: 根据项目检测和依赖解析结果动态构造uv run命令

命令模式:

场景 命令格式
uv项目内脚本 uv run <script_path>
非uv项目有依赖 uv run --with pkg1 --with pkg2 <script_path>
非uv项目无依赖 uv run <script_path>

原因:

  • uv项目依赖已在pyproject.toml中管理不需要--with
  • 非uv项目使用--with逐个指定依赖uv自动处理隔离环境
  • 无依赖:不需要--with,使用标准库环境

决策5不使用辅助脚本进行项目检测

选择: 直接使用大模型的命令行工具执行uv sync --dry-run进行项目检测

原因:

  • 大模型可以直接执行bash命令无需额外的辅助脚本
  • 简化实现,减少维护成本
  • 避免辅助脚本的版本管理问题

实现细节:

# 使用大模型的命令行工具执行项目检测
uv sync --dry-run
  • 如果命令返回exit code 0则当前目录是有效的uv项目
  • 如果命令返回非零退出码则当前目录不是uv项目
  • 检测结果直接由大模型判断,无需解析辅助脚本输出

Risks / Trade-offs

风险1uv项目检测失败

描述: uv sync --dry-run在某些情况下可能误判(如网络问题、依赖解析错误)

缓解措施:

  • 检测失败时回退到非uv项目模式使用--with语法)
  • 记录检测失败日志,但不阻塞脚本执行
  • 用户可以手动指定使用项目环境(通过注释或显式指令)

风险2依赖解析不完整

描述: 大模型可能遗漏某些import语句或误判标准库模块

缓解措施:

  • 在SKILL.md中提供常见标准库列表供参考
  • 当脚本执行失败时,检查是否为缺失依赖,提示用户
  • 允许用户手动指定依赖(通过参数或注释)

风险3路径冲突和权限问题

描述: 用户指定的路径可能不存在、无写入权限或与现有文件冲突

缓解措施:

  • 写入前检查目录是否存在,不存在则创建(如果允许)
  • 写入前检查文件权限,失败时提示用户
  • 支持覆盖提示(如果文件已存在)

风险4跨平台路径处理复杂

描述: Windows和Unix系统的路径分隔符、路径长度限制不同

缓解措施:

  • 使用Python的pathlibos.path处理路径,而非字符串拼接
  • 保持辅助脚本使用标准库路径处理函数
  • 测试覆盖Windows、macOS、Linux三个平台

权衡1自动依赖解析 vs 用户显式声明

当前选择: 自动解析import语句

权衡:

  • 优点:用户无需手动声明依赖,开箱即用
  • 缺点:可能遗漏某些隐式依赖(如动态导入)

缓解: 支持用户通过参数或注释显式指定依赖

权衡2项目检测成本 vs 准确性

当前选择: 使用uv sync --dry-run(准确但较慢)

权衡:

  • 优点准确判断uv项目避免误判
  • 缺点:每次执行都需要运行检测命令(约几百毫秒)

缓解: 可以考虑缓存检测结果(在同一工作目录内)

Migration Plan

步骤1更新SKILL.md文档

  1. 移除PEP 723相关内容
  2. 添加依赖解析指导
  3. 添加项目检测流程
  4. 更新路径处理说明
  5. 更新执行命令示例
  6. 保持错误处理和调试支持部分

步骤2更新工作流示例

在SKILL.md中提供新的工作流示例

  • uv项目内执行脚本
  • 非uv项目执行脚本有依赖
  • 非uv项目执行脚本无依赖
  • 用户指定路径的执行流程

步骤4测试验证

在三个平台Windows/macOS/Linux上测试

  1. uv项目检测
  2. 依赖解析准确性
  3. 路径处理(临时/指定/现有)
  4. 跨平台兼容性
  5. 错误处理

回滚策略

如果新实现存在问题可以直接回退到旧版SKILL.md内容从git历史恢复

Open Questions

  1. 依赖解析准确性: 是否需要维护一个更完整的Python标准库模块列表以减少误判

    • 建议基于Python 3.10+标准库文档维护列表
  2. 项目检测缓存: 是否需要在同一工作目录内缓存项目检测结果,避免重复运行uv sync --dry-run

    • 建议:初期不实现,观察性能影响后再决定
  3. 隐式依赖处理: 如何处理通过__import__()或动态加载的隐式依赖?

    • 建议暂不支持在SKILL.md中说明限制
  4. 用户干预机制: 是否提供机制让用户在脚本中显式声明额外依赖(如通过特殊注释)?

    • 建议:初期不实现,通过错误提示引导用户
  5. Windows路径长度限制 Windows路径最大260字符限制如何处理

    • 建议:使用长路径前缀(\?\)或尽量使用相对路径