上下文感知与文件操作:让 Skill 读懂你的代码
前面的章节中,我们开发的 Skill 主要是“单向”的——用户给指令,Skill 执行命令。但在真正的编程场景中,我们需要 Skill 能够看到我们的代码,理解当前的上下文,甚至帮我们修改文件。
本章将探讨 Agent Skills 的上下文感知(Context Awareness)能力和文件操作(File I/O)。
1. 什么是上下文感知?
Q: AI 怎么知道我现在打开了哪个文件?
A: 大多数 AI 编程助手(如 Claude Code)会自动将当前打开的文件、选中的代码片段作为上下文(Context)发送给模型。
但是,当你编写一个自定义 Skill 时,你可能需要更主动地获取特定的文件内容,而不是依赖 AI 默认的上下文窗口。
两种获取方式:
- 被动接收:用户在对话中引用文件(例如:“优化
app.js”)。AI 会读取该文件内容并传给你的 Skill(通常作为参数)。 - 主动读取:你的 Skill 脚本主动去读取文件系统。
2. 实战:开发“自动文档生成器”
Q: 我想做一个 Skill,它能读取我的 Python 代码,然后自动生成 docstring。
A: 这是一个非常经典的场景。我们需要一个脚本,它能接收文件名,读取内容,然后利用 AI(或者简单的规则)生成文档。
注意:在 Skill 内部调用 AI 模型生成文档比较复杂,这里我们简化为“Skill 读取文件 -> 提取函数名 -> 生成骨架文档”。真正的 AI 生成通常由助手本身完成,Skill 负责数据准备。
场景设计:
- 用户说:“给
utils.py生成文档。” - Skill 读取
utils.py。 - Skill 分析代码结构。
- 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: 风险非常大!
让自动化脚本直接覆写用户代码是危险操作。如果脚本出错,用户的代码可能就丢了。
最佳实践:
- 只读不写:Skill 只负责读取和分析,将建议的代码输出到对话框,由用户决定是否应用(Copy/Paste 或 Apply)。
- 创建新文件:生成
utils_docs.py而不是覆盖utils.py。 - 使用 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. 进阶:结合 grep 和 cat 的原生能力
Q: 有时候我不需要写 Python 脚本,直接用 Linux 命令不行吗?
A: 完全可以!很多时候,组合原生命令更高效。
示例:TODO 扫描器
# TODO Scanner
## Description
扫描项目中所有待办事项(TODO)的技能。
## Usage
使用 grep 递归搜索代码库:
grep -r "TODO" . --exclude-dir=node_modules --exclude-dir=.git这样,你不需要写任何代码,就拥有了一个强大的 TODO 管理工具。AI 会执行 grep 并把结果整理给你看。
总结
通过本章,我们学会了:
- 文件读取:编写脚本解析代码结构。
- 安全原则:在修改文件时保持谨慎,优先使用“输出建议”而非“直接覆写”。
- 路径管理:处理 Skill 执行上下文中的路径问题。
- 原生工具:利用
grep等系统工具快速实现上下文感知。
拥有了逻辑控制和文件操作能力后,你的 Skill 已经非常强大了。但在处理极复杂的任务时,单一的 Skill 可能不够用。下一章,我们将学习如何链接多个 Skill,构建自动化的工作流。
参考资源: