跳转至

第四章:脚本与资源

脚本设计(scripts/)

何时使用脚本

场景 是否使用脚本
相同代码反复重写 ✅ 是
需要确定性可靠性 ✅ 是
复杂数据处理 ✅ 是
简单文本指令可完成 ❌ 否
需要灵活判断 ❌ 否

脚本模板

Python 脚本

#!/usr/bin/env python3
"""
脚本用途简述。

用法:
    python script.py --input <file> --output <file>
"""

import argparse
import sys
from pathlib import Path


def main():
    parser = argparse.ArgumentParser(description='脚本描述')
    parser.add_argument('--input', required=True, help='输入文件')
    parser.add_argument('--output', required=True, help='输出文件')
    parser.add_argument('--option', default='default', help='可选参数')

    args = parser.parse_args()

    # 验证输入
    input_path = Path(args.input)
    if not input_path.exists():
        print(f"错误: 输入文件不存在: {input_path}")
        sys.exit(1)

    # 执行处理
    try:
        result = process(input_path, args.option)
        write_output(result, args.output)
        print(f"成功: 输出已保存到 {args.output}")
    except Exception as e:
        print(f"错误: {e}")
        sys.exit(1)


def process(input_path: Path, option: str) -> dict:
    """核心处理逻辑"""
    # 实现处理逻辑
    return {"status": "success"}


def write_output(result: dict, output_path: str):
    """写入输出"""
    Path(output_path).write_text(str(result))


if __name__ == '__main__':
    main()

Shell 脚本

#!/bin/bash
# 脚本用途简述
#
# 用法: ./script.sh <input> <output>

set -e  # 遇错退出

# 参数检查
if [ $# -lt 2 ]; then
    echo "用法: $0 <input> <output>"
    exit 1
fi

INPUT="$1"
OUTPUT="$2"

# 验证输入
if [ ! -f "$INPUT" ]; then
    echo "错误: 输入文件不存在: $INPUT"
    exit 1
fi

# 执行处理
echo "处理 $INPUT..."
# 实现处理逻辑

echo "完成: $OUTPUT"

脚本最佳实践

# ✅ 好的脚本设计

# 1. 清晰的参数
parser.add_argument('--input', required=True, help='输入文件路径')

# 2. 输入验证
if not input_path.exists():
    sys.exit(1)

# 3. 错误处理
try:
    process()
except Exception as e:
    print(f"错误: {e}")
    sys.exit(1)

# 4. 成功反馈
print(f"成功: 输出已保存到 {output}")
# ❌ 不好的脚本设计

# 1. 硬编码路径
input_file = "/fixed/path/input.pdf"  # 不灵活

# 2. 无错误处理
result = process(data)  # 可能崩溃

# 3. 无输出反馈
# 用户不知道是否成功

# 4. 隐式依赖
import some_custom_module  # 未说明依赖

脚本文档化

在 SKILL.md 中说明脚本用法:

## 可用脚本

### rotate_pdf.py

旋转 PDF 页面。

```bash
python scripts/rotate_pdf.py --input file.pdf --degrees 90

参数: - --input: 输入 PDF 文件 - --output: 输出文件(可选,默认覆盖) - --degrees: 旋转角度(90/180/270)

merge_pdfs.py

合并多个 PDF。

python scripts/merge_pdfs.py --files file1.pdf file2.pdf --output merged.pdf
## 参考文档(references/)

### 何时使用 references

| 内容类型 | 是否放 references |
|----------|------------------|
| 详细 API 文档 | ✅ 是 |
| 数据 Schema | ✅ 是 |
| 公司政策 | ✅ 是 |
| 领域知识 | ✅ 是 |
| 核心工作流 | ❌ 否(放 SKILL.md) |
| 快速示例 | ❌ 否(放 SKILL.md) |

### references 组织
references/ ├── schema.md # 数据结构 ├── api-reference.md # API 文档 ├── examples.md # 详细示例 ├── policies.md # 政策规范 └── domain-knowledge.md # 领域知识
### schema.md 示例

```markdown
# 数据 Schema

## 用户表

| 字段 | 类型 | 说明 |
|------|------|------|
| id | integer | 主键 |
| name | string | 用户名 |
| email | string | 邮箱 |
| created_at | timestamp | 创建时间 |

## 订单表

| 字段 | 类型 | 说明 |
|------|------|------|
| id | integer | 主键 |
| user_id | integer | 用户 ID(外键) |
| amount | decimal | 金额 |
| status | string | 状态 |

## 关系
用户 (1) ──────< (N) 订单

api-reference.md 示例

# API 参考

## 认证

### POST /auth/login

登录获取令牌。

**请求:**
```json
{
  "email": "user@example.com",
  "password": "password"
}

响应:

{
  "token": "jwt_token",
  "expires_in": 3600
}

用户

GET /users

获取用户列表。

参数: - page: 页码(默认 1) - limit: 每页数量(默认 20)

### examples.md 示例

```markdown
# 使用示例

## 示例 1:基础查询

```python
from client import APIClient

client = APIClient(token="your_token")
users = client.get_users()

示例 2:分页查询

users = client.get_users(page=2, limit=50)
for user in users:
    print(user.name)

示例 3:创建记录

new_user = client.create_user({
    "name": "张三",
    "email": "zhangsan@example.com"
})
### 在 SKILL.md 中引用

```markdown
# SKILL.md

## 快速开始

基础用法:
```python
client = APIClient(token)
users = client.get_users()

详细文档

  • API 参考: 见 references/api-reference.md
  • 数据结构: 见 references/schema.md
  • 更多示例: 见 references/examples.md
    ## 输出资源(assets/)
    
    ### 何时使用 assets
    
    | 资源类型 | 是否放 assets |
    |----------|--------------|
    | 模板文件 | ✅ 是 |
    | 图片/图标 | ✅ 是 |
    | 字体文件 | ✅ 是 |
    | 样板代码 | ✅ 是 |
    | 参考文档 | ❌ 否(放 references) |
    | 可执行脚本 | ❌ 否(放 scripts) |
    
    ### assets 组织
    
    assets/ ├── templates/ │ ├── report.html │ └── invoice.html ├── images/ │ ├── logo.png │ └── icons/ ├── fonts/ │ └── custom-font.ttf └── boilerplate/ └── project-template/
    ### 使用 assets
    
    在 SKILL.md 中说明用法:
    
    ```markdown
    ## 模板
    
    ### 报告模板
    
    使用 `assets/templates/report.html` 生成报告:
    
    ```python
    from pathlib import Path
    
    template = Path("assets/templates/report.html").read_text()
    html = template.replace("{{title}}", "月度报告")
    

品牌资源

  • Logo: assets/images/logo.png
  • 图标: assets/images/icons/
    ## 资源加载机制
    
    ### 加载顺序
    
  • SKILL.md 元数据(始终加载) └── name + description

  • SKILL.md 正文(触发后加载) └── 工作流、指令、示例

  • references/(按需加载) └── Agent 决定是否需要

  • scripts/(可执行但不加载) └── 直接执行,不占用上下文

  • assets/(不加载) └── 用于输出,不进入上下文

    ### 上下文优化
    
    ```markdown
    # 优化策略
    
    ## 策略 1:脚本优先
    对于重复执行的确定性任务,使用脚本:
    - 不占用上下文
    - 确定性执行
    - 可复用
    
    ## 策略 2:引用分离
    详细文档放 references/:
    - SKILL.md 保持精简
    - 按需加载详情
    - 避免上下文膨胀
    
    ## 策略 3:资产外置
    输出资源放 assets/:
    - 不进入上下文
    - 直接用于输出
    - 支持大文件
    

小结

本章介绍了脚本和资源的设计:

  • scripts/ 用于可执行代码
  • references/ 用于参考文档
  • assets/ 用于输出资源
  • 理解加载机制优化上下文
  • 遵循最佳实践编写脚本

下一章将介绍进阶设计模式。