Claude Code & Agent SDK 常见 FAQ¶
Q1: 生产级别如何用 SDK 实现多轮对话?¶
核心机制:SDK 通过 Session 持久化对话历史(JSONL 格式),每次 query() 产生的 prompt、工具调用、工具结果、响应都被记录。后续调用通过 resume 或 continue 恢复完整上下文。
三种实现方式:
| 方式 | 适用场景 | 特点 |
|---|---|---|
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 环境如何恢复会话?¶
两种方案:
-
SessionStore 适配器(推荐):实现
append+load接口,SDK 自动双写(本地磁盘 + 外部存储)。官方提供 S3/Redis/Postgres 参考实现。 -
搬运文件:将
~/.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: 会话恢复失败的常见原因?¶
- cwd 不匹配:会话存储路径编码了工作目录,从不同目录 resume 会找不到
- 文件不存在:跨主机时本地没有 JSONL 文件
- session_id 错误:ID 打错或已过期
- 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_sessions、delete、list_subkeys(支持子代理恢复)。
SDK 附带 InMemorySessionStore 用于开发测试,生产用 S3/Redis/Postgres 参考实现。
Q10: 双写架构的注意事项?¶
- Store 是镜像不是替代,本地磁盘总是先写
append()失败时 SDK 最多重试 2 次,失败后记录错误并丢弃该批次,查询继续- 重试可能导致重复投递,需在适配器内按
entry.uuid去重 sessionStore不能与persistSession: false或enableFileCheckpointing组合- 监控
mirror_error事件检测 store 数据丢失