Skip to content

Skills 上下文与状态管理

Claude 的每次 API 调用都是无状态的,它不会自动记住上一次会话的内容。

但在一次连续对话中,所有历史消息都在上下文窗口里。理解这一点,能帮助你写出在对话中表现稳定的 Skill。


Skills 的状态存在于哪里

状态类型存储位置有效范围
对话历史上下文窗口当前会话,关闭后消失
中间文件/home/claude/当前会话,任务完成后可能清除
输出文件/mnt/user-data/outputs/持久化,用户可下载
已安装的 Skill/mnt/skills/跨会话持久化

Skills 本身不具备数据库或持久存储能力。需要跨会话保存的数据,应由用户自己保存(如下载文件),或写入持久化输出目录。


在 SKILL.md 中管理多轮对话状态

对于需要多轮交互的 Skill,应在 SKILL.md 中明确定义对话状态的流转逻辑。

实例

bash

## 多轮交互流程

 Skill 分三个阶段运行:

### 阶段一:信息收集

询问用户提供以下信息:

1. 数据文件路径

2. 分析目标

在获得全部信息前,不执行分析。

将已收集的信息以列表形式展示,告知用户还缺少什么。

### 阶段二:确认执行

收集完成后,展示执行计划,等待用户确认:

> 我将对 {文件名} 执行 {分析目标},预计需要约 {时间} 秒。确认继续吗?

### 阶段三:执行并输出

用户确认后执行,实时告知进度,完成后输出结果。

如果用户在任意阶段说"重新开始",清除当前收集的信息,回到阶段一。

使用文件保存中间状态

对于复杂的多步骤任务,可以将中间状态写入 JSON 文件,实现步骤间的状态传递。

实例

bash

# 文件路径:scripts/state_manager.py

import json

import os

from datetime import datetime

# 状态文件存储路径(当前会话工作目录)

STATE_FILE = "/home/claude/skill_state.json"

def save_state(state: dict) -> None:

    """保存当前执行状态到文件"""

    state["updated_at"] = datetime.now().isoformat()

    with open(STATE_FILE, "w", encoding="utf-8") as f:

        json.dump(state, f, ensure_ascii=False, indent=2)

    print(f"状态已保存:{STATE_FILE}")

def load_state() -> dict:

    """加载上次保存的状态,若不存在则返回初始状态"""

    if not os.path.exists(STATE_FILE):

        return {

            "phase":      "collecting",  # 当前阶段:collecting / confirming / executing / done

            "file_path":  None,

            "target":     None,

            "result":     None,

            "created_at": datetime.now().isoformat()

        }

    with open(STATE_FILE, "r", encoding="utf-8") as f:

        return json.load(f)

def clear_state() -> None:

    """清除状态(用于"重新开始"场景)"""

    if os.path.exists(STATE_FILE):

        os.remove(STATE_FILE)

    print("状态已清除,重新开始")

# 使用示例

if __name__ == "__main__":

    # 加载或初始化状态

    state = load_state()

    print(f"当前阶段:{state['phase']}")

    # 更新状态:已收集文件路径

    state["file_path"] = "/mnt/user-data/uploads/runoob_data.csv"

    state["phase"]     = "confirming"

    save_state(state)
bash
状态已保存:/home/claude/skill_state.json
当前阶段:collecting
状态已保存:/home/claude/skill_state.json

防止上下文污染

当用户在同一对话中多次触发 Skill,历史对话中的旧参数可能"污染"新的执行。

在 SKILL.md 中明确规定优先级,可以避免这类问题。

实例

bash

## 参数优先级规则

同一次对话中若存在多组参数,按以下优先级处理:

1. **用户最新消息中明确指定的参数** 最高优先级,始终使用

2. **本次请求中上传的文件** 高优先级

3. **对话历史中提到的参数** 低优先级,仅在当前消息未指定时使用

4. **Skill 定义的默认值** 兜底

若对参数来源有疑问,在执行前向用户确认:"我将使用 runoob_v2.csv(您刚上传的文件),而非之前的 runoob_v1.csv,是否正确?"

上下文长度与性能的关系

随着对话变长,上下文窗口中的内容越来越多,Claude 处理的成本也会增加。

对于长时间运行的多轮 Skill,应当注意以下优化策略:

策略做法效果
避免重复输出大块内容引用之前输出的文件路径,而非重新输出内容减少上下文占用
使用文件传递中间数据将大型数据集写入文件,对话中只传递路径避免大数据占满上下文
及时告知用户阶段性完成每个阶段结束后明确说"第一步完成"让用户知道进度,减少追问

上下文窗口是有限的资源。Skill 中传递的数据量越大,剩余给推理和生成的空间就越少,响应质量可能下降。对于大文件,始终通过文件路径而非内容传递。

AI 思考中...

Skills 错误处理与容错

Skills 多步骤流程设计

基于 VitePress 构建,部署于 GitHub Pages