Claude Code 参考资源

Claude Code & Agent SDK 常见 FAQ

Q1: 生产级别如何用 SDK 实现多轮对话?

核心机制:SDK 通过 Session 持久化对话历史(JSONL 格式),每次 query() 产生的 prompt、工具调用、工具结果、响应都被记录。后续调用通过 resumecontinue 恢复完整上下文。

三种实现方式

方式 适用场景 特点
ClaudeSDKClient (Python) / continue: true (TS) 单进程内多轮 SDK 自动管理 session ID
resume + session_id 跨进程/跨请求 手动捕获 session_id,显式传入恢复
SessionStore 适配器 跨主机/Serverless 镜像到 S3/Redis/Postgres

生产推荐架构

用户请求 → 你的后端 → SDK query(resume=session_id, sessionStore=store) → Claude Code 子进程

步骤:
1. 首次对话:query(prompt),从 ResultMessage.session_id 捕获 ID,存入数据库关联用户
2. 后续轮次:query(prompt, resume=session_id, sessionStore=store)
3. 跨主机恢复:通过 SessionStore 适配器(S3/Redis/Postgres)

Q2: SDK 和 CLI 的会话能互通吗?

可以。 二者共享同一套 JSONL 会话格式和存储路径约定。

会话存储位置:~/.claude/projects/<encoded-cwd>/<session-id>.jsonl

# SDK 产出的 session_id,直接用 CLI 继续
claude -p "继续之前的工作" --resume "$session_id"

# 交互模式接管
claude --resume "$session_id"

前提条件
- CLI 需要在相同的 cwd 下运行(session 路径与工作目录编码绑定)
- 会话 JSONL 文件需在本地存在

Q3: 跨主机/Serverless 环境如何恢复会话?

两种方案:

  1. SessionStore 适配器(推荐):实现 append + load 接口,SDK 自动双写(本地磁盘 + 外部存储)。官方提供 S3/Redis/Postgres 参考实现。

  2. 搬运文件:将 ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl 同步到新主机相同路径。

注意:SessionStore 是镜像而非替代,SDK 总是先写本地再 append 到 store。

Q4: continue vs resume vs fork 有什么区别?

操作 行为 何时用
continue 恢复当前目录最近的会话,不需要 ID 一次只有一个活跃对话
resume 按 session_id 恢复特定会话 多用户/多会话并行
fork 复制原始历史到新会话,原始不变 探索替代方案,保留主线

Q5: 单次 query() 内部已经是多轮了吗?

是的。 单个 query() 调用内,Agent 会根据任务需要执行多个 tool-use 轮次(读文件、执行命令、编辑文件等),直到任务完成。权限提示和 AskUserQuestion 在循环内处理,不会结束调用。

只有当你需要发送多个独立 prompt(如用户的多次输入)共享上下文时,才需要会话管理(continue/resume)。

Q6: 会话恢复失败的常见原因?

  1. cwd 不匹配:会话存储路径编码了工作目录,从不同目录 resume 会找不到
  2. 文件不存在:跨主机时本地没有 JSONL 文件
  3. session_id 错误:ID 打错或已过期
  4. CLAUDE_CONFIG_DIR 不同:如果设置了该环境变量,路径会变

Q7: 如何在 CI/CD 中使用多轮?

# 第一步:执行分析,捕获 session_id
session_id=$(claude -p "Review this PR for issues" \
  --output-format json --bare \
  --allowedTools "Read,Glob,Grep" | jq -r '.session_id')

# 第二步:基于分析结果继续
claude -p "Fix the issues you found" \
  --resume "$session_id" --bare \
  --allowedTools "Read,Edit,Write,Bash"

关键:两次调用需在同一 cwd,加 --bare 确保 CI 环境一致性。

Q8: Python SDK 多轮对话的最简示例?

import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock

async def main():
    options = ClaudeAgentOptions(allowed_tools=["Read", "Edit", "Glob", "Grep"])

    async with ClaudeSDKClient(options=options) as client:
        # 第一轮
        await client.query("分析 auth 模块")
        async for msg in client.receive_response():
            if isinstance(msg, AssistantMessage):
                for block in msg.content:
                    if isinstance(block, TextBlock):
                        print(block.text)

        # 第二轮:自动延续同一会话
        await client.query("重构为 JWT 方案")
        async for msg in client.receive_response():
            if isinstance(msg, AssistantMessage):
                for block in msg.content:
                    if isinstance(block, TextBlock):
                        print(block.text)

asyncio.run(main())

Q9: SessionStore 适配器的核心接口?

只需实现两个必需方法:

class SessionStore(Protocol):
    async def append(self, key: SessionKey, entries: list[SessionStoreEntry]) -> None: ...
    async def load(self, key: SessionKey) -> list[SessionStoreEntry] | None: ...

可选方法:list_sessionsdeletelist_subkeys(支持子代理恢复)。

SDK 附带 InMemorySessionStore 用于开发测试,生产用 S3/Redis/Postgres 参考实现。

Q10: 双写架构的注意事项?

  • Store 是镜像不是替代,本地磁盘总是先写
  • append() 失败时 SDK 最多重试 2 次,失败后记录错误并丢弃该批次,查询继续
  • 重试可能导致重复投递,需在适配器内按 entry.uuid 去重
  • sessionStore 不能与 persistSession: falseenableFileCheckpointing 组合
  • 监控 mirror_error 事件检测 store 数据丢失