上下文感知与文件操作:让 Skill 读懂你的代码

前面的章节中,我们开发的 Skill 主要是“单向”的——用户给指令,Skill 执行命令。但在真正的编程场景中,我们需要 Skill 能够看到我们的代码,理解当前的上下文,甚至帮我们修改文件。

本章将探讨 Agent Skills 的上下文感知(Context Awareness)能力和文件操作(File I/O)

1. 什么是上下文感知?

Q: AI 怎么知道我现在打开了哪个文件?

A: 大多数 AI 编程助手(如 Claude Code)会自动将当前打开的文件、选中的代码片段作为上下文(Context)发送给模型。

但是,当你编写一个自定义 Skill 时,你可能需要更主动地获取特定的文件内容,而不是依赖 AI 默认的上下文窗口。

两种获取方式

  1. 被动接收:用户在对话中引用文件(例如:“优化 app.js”)。AI 会读取该文件内容并传给你的 Skill(通常作为参数)。
  2. 主动读取:你的 Skill 脚本主动去读取文件系统。

2. 实战:开发“自动文档生成器”

Q: 我想做一个 Skill,它能读取我的 Python 代码,然后自动生成 docstring。

A: 这是一个非常经典的场景。我们需要一个脚本,它能接收文件名,读取内容,然后利用 AI(或者简单的规则)生成文档。

注意:在 Skill 内部调用 AI 模型生成文档比较复杂,这里我们简化为“Skill 读取文件 -> 提取函数名 -> 生成骨架文档”。真正的 AI 生成通常由助手本身完成,Skill 负责数据准备

场景设计

  1. 用户说:“给 utils.py 生成文档。”
  2. Skill 读取 utils.py
  3. Skill 分析代码结构。
  4. Skill 将带注释的代码写回文件(或输出到屏幕)。

步骤 1:编写分析脚本 (doc_gen.py)

import sys
import ast

def generate_docs(filename):
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            source = f.read()
        
        tree = ast.parse(source)
        functions = [node for node in tree.body if isinstance(node, ast.FunctionDef)]
        
        print(f"Found {len(functions)} functions in {filename}.\n")
        
        for func in functions:
            print(f"--- Function: {func.name} ---")
            # 简单的文档模板
            doc = f'''
def {func.name}({", ".join(arg.arg for arg in func.args.args)}):
    """
    TODO: Add documentation for {func.name}
    """
    ...
'''
            print(doc)
            
    except FileNotFoundError:
        print(f"Error: File {filename} not found.")
    except Exception as e:
        print(f"Error parsing file: {e}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        generate_docs(sys.argv[1])
    else:
        print("Please provide a filename.")

步骤 2:编写 SKILL.md

# Auto Doc Skeleton

## Description
用于为 Python 文件生成文档骨架的工具。当用户需要“生成文档”、“添加注释”或“查看函数结构”时使用。

## Usage
读取指定文件的路径,并运行分析脚本:
python doc_gen.py "{file_path}"

## Examples
User: 给 `src/utils.py` 生成一下文档结构。
Assistant: (Executes python doc_gen.py "src/utils.py")
Output: Found 2 functions...
Assistant: 我为你生成了 `utils.py` 的文档骨架,你可以参考以下结构...

3. 安全地进行文件写入

Q: 如果我想让 Skill 直接修改文件(比如把文档写入文件),有什么风险吗?

A: 风险非常大!

让自动化脚本直接覆写用户代码是危险操作。如果脚本出错,用户的代码可能就丢了。

最佳实践

  1. 只读不写:Skill 只负责读取和分析,将建议的代码输出到对话框,由用户决定是否应用(Copy/Paste 或 Apply)。
  2. 创建新文件:生成 utils_docs.py 而不是覆盖 utils.py
  3. 使用 Git 保护:在执行写入操作前,检查 Git 状态是否干净(Dirty Check),强迫用户先提交。

安全写入示例

# 安全写入:先备份
import shutil
shutil.copy(filename, f"{filename}.bak")
# 然后再写入...

4. 处理相对路径与绝对路径

Q: 用户说“读取 utils.py”,但脚本在 skills/ 目录下,代码在 src/ 目录下,路径怎么算?

A: 这是一个常见的坑。

  • AI 的视角:AI 看到的通常是项目根目录。
  • 脚本的视角:取决于在哪里执行命令。

解决方案
始终要求 AI 传递相对于项目根目录的路径,或者绝对路径

SKILL.md 中强化这一点:

## Usage
...
注意:请传入文件的绝对路径或相对于项目根目录的路径。

5. 进阶:结合 grepcat 的原生能力

Q: 有时候我不需要写 Python 脚本,直接用 Linux 命令不行吗?

A: 完全可以!很多时候,组合原生命令更高效。

示例:TODO 扫描器

# TODO Scanner

## Description
扫描项目中所有待办事项(TODO)的技能。

## Usage
使用 grep 递归搜索代码库:
grep -r "TODO" . --exclude-dir=node_modules --exclude-dir=.git

这样,你不需要写任何代码,就拥有了一个强大的 TODO 管理工具。AI 会执行 grep 并把结果整理给你看。


总结

通过本章,我们学会了:

  1. 文件读取:编写脚本解析代码结构。
  2. 安全原则:在修改文件时保持谨慎,优先使用“输出建议”而非“直接覆写”。
  3. 路径管理:处理 Skill 执行上下文中的路径问题。
  4. 原生工具:利用 grep 等系统工具快速实现上下文感知。

拥有了逻辑控制文件操作能力后,你的 Skill 已经非常强大了。但在处理极复杂的任务时,单一的 Skill 可能不够用。下一章,我们将学习如何链接多个 Skill,构建自动化的工作流。


参考资源:

« 上一篇 进阶开发:参数处理与复杂逻辑控制 下一篇 » 技能链与自动化工作流:构建 AI 流水线