统一skill命名
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
## 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项目不友好
|
||||
|
||||
**实现细节:**
|
||||
```bash
|
||||
# 检测当前目录是否为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命令,无需额外的辅助脚本
|
||||
- 简化实现,减少维护成本
|
||||
- 避免辅助脚本的版本管理问题
|
||||
|
||||
**实现细节:**
|
||||
```bash
|
||||
# 使用大模型的命令行工具执行项目检测
|
||||
uv sync --dry-run
|
||||
```
|
||||
|
||||
- 如果命令返回exit code 0,则当前目录是有效的uv项目
|
||||
- 如果命令返回非零退出码,则当前目录不是uv项目
|
||||
- 检测结果直接由大模型判断,无需解析辅助脚本输出
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### 风险1:uv项目检测失败
|
||||
|
||||
**描述:** `uv sync --dry-run`在某些情况下可能误判(如网络问题、依赖解析错误)
|
||||
|
||||
**缓解措施:**
|
||||
- 检测失败时回退到非uv项目模式(使用`--with`语法)
|
||||
- 记录检测失败日志,但不阻塞脚本执行
|
||||
- 用户可以手动指定使用项目环境(通过注释或显式指令)
|
||||
|
||||
### 风险2:依赖解析不完整
|
||||
|
||||
**描述:** 大模型可能遗漏某些import语句或误判标准库模块
|
||||
|
||||
**缓解措施:**
|
||||
- 在SKILL.md中提供常见标准库列表供参考
|
||||
- 当脚本执行失败时,检查是否为缺失依赖,提示用户
|
||||
- 允许用户手动指定依赖(通过参数或注释)
|
||||
|
||||
### 风险3:路径冲突和权限问题
|
||||
|
||||
**描述:** 用户指定的路径可能不存在、无写入权限或与现有文件冲突
|
||||
|
||||
**缓解措施:**
|
||||
- 写入前检查目录是否存在,不存在则创建(如果允许)
|
||||
- 写入前检查文件权限,失败时提示用户
|
||||
- 支持覆盖提示(如果文件已存在)
|
||||
|
||||
### 风险4:跨平台路径处理复杂
|
||||
|
||||
**描述:** Windows和Unix系统的路径分隔符、路径长度限制不同
|
||||
|
||||
**缓解措施:**
|
||||
- 使用Python的`pathlib`或`os.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字符限制如何处理?
|
||||
- 建议:使用长路径前缀(\\?\)或尽量使用相对路径
|
||||
Reference in New Issue
Block a user