第 6 课:交互式会话——ClaudeSDKClient
query() vs ClaudeSDKClient
前面用的 query() 是"一锤子买卖"——发一个任务,等 AI 做完。但 DevOps 场景经常需要来回交流:
query()(一次性):
你: "跑测试"
AI: [测试结果]
结束。
ClaudeSDKClient(多轮对话):
你: "看看日志"
AI: [日志分析结果]
你: "第 42 行那个错误是什么原因?"
AI: [分析错误原因]
你: "帮我修一下"
AI: [修改代码]
你: "再跑一次测试"
AI: [测试通过!]
ClaudeSDKClient 就是为这种"聊天式"工作流设计的。
基本用法
import anyio
from claude_agent_sdk import (
ClaudeSDKClient, ClaudeAgentOptions,
AssistantMessage, ResultMessage, TextBlock
)
async def main():
options = ClaudeAgentOptions(
system_prompt="你是 DevOps 助手,帮我管理服务器和代码。",
allowed_tools=["Bash", "Read", "Write"],
)
# async with 确保资源正确清理
async with ClaudeSDKClient(options=options) as client:
# 第一轮对话
await client.query("看看当前目录有什么文件")
async for msg in client.receive_response():
if isinstance(msg, AssistantMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(f"AI: {block.text}")
# 第二轮对话(AI 记得上一轮的内容)
await client.query("刚才看到的 py 文件,帮我检查一下代码质量")
async for msg in client.receive_response():
if isinstance(msg, AssistantMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(f"AI: {block.text}")
anyio.run(main)
关键区别:
- query() 每次调用都是独立的
- ClaudeSDKClient 的多次 client.query() 共享对话历史
交互式命令行
做一个真正的"对话式 DevOps 助手":
import anyio
from claude_agent_sdk import (
ClaudeSDKClient, ClaudeAgentOptions,
AssistantMessage, ResultMessage, TextBlock, ToolUseBlock
)
async def devops_chat():
options = ClaudeAgentOptions(
system_prompt="""你是 DevOps 助手。你能帮用户:
- 执行命令和检查系统状态
- 分析日志和代码
- 管理 Git 和部署
请用中文回复。""",
allowed_tools=["Bash", "Read", "Write", "Grep"],
)
print("🤖 DevOps 助手已启动!输入 'quit' 退出。\n")
async with ClaudeSDKClient(options=options) as client:
while True:
user_input = input("你: ").strip()
if user_input.lower() in ['quit', 'exit', 'q']:
print("👋 再见!")
break
if not user_input:
continue
await client.query(user_input)
async for msg in client.receive_response():
if isinstance(msg, AssistantMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(f"\n🤖 {block.text}")
elif isinstance(block, ToolUseBlock):
print(f" 🔧 {block.name}")
elif isinstance(msg, ResultMessage):
if msg.total_cost_usd and msg.total_cost_usd > 0:
print(f" 💰 ${msg.total_cost_usd:.4f}")
print()
anyio.run(devops_chat)
高级功能
动态切换权限
async with ClaudeSDKClient(options=options) as client:
# 分析阶段:只读权限
await client.set_permission_mode("default")
await client.query("分析一下这个错误日志")
async for msg in client.receive_response():
pass
# 修复阶段:开放编辑权限
await client.set_permission_mode("acceptEdits")
await client.query("帮我修复刚才分析出的问题")
async for msg in client.receive_response():
pass
这在 DevOps 中很有用:先让 AI 分析(只读),确认没问题后再让它修改(读写)。
动态切换模型
async with ClaudeSDKClient(options=options) as client:
# 简单任务用便宜模型
await client.set_model("haiku")
await client.query("列出所有 Python 文件")
async for msg in client.receive_response():
pass
# 复杂任务用强力模型
await client.set_model("sonnet")
await client.query("深入分析这些文件的架构设计")
async for msg in client.receive_response():
pass
文件检查点和回滚
async with ClaudeSDKClient(options=options) as client:
# AI 做了一些修改
await client.query("重构这个函数")
async for msg in client.receive_response():
# 记住这条消息的 ID
if isinstance(msg, AssistantMessage):
checkpoint_id = msg.uuid
pass
# 发现改坏了?回滚!
await client.rewind_files(checkpoint_id)
print("文件已回滚到修改前的状态")
rewind_files() 是 DevOps 场景的救命稻草——AI 改坏了文件,一键恢复。
中断正在执行的任务
async with ClaudeSDKClient(options=options) as client:
await client.query("跑一个很长的测试")
# AI 正在执行...
# 你发现它在做错误的事情
await client.interrupt() # 紧急中断!
print("已中断 AI 的操作")
检查 MCP 服务器状态
async with ClaudeSDKClient(options=options) as client:
status = await client.get_mcp_status()
print(f"MCP 服务器状态: {status}")
# 确认你的自定义工具是否正常运行
Client 的完整 API 一览
async with ClaudeSDKClient(options=options) as client:
# 核心对话
await client.query("你的问题") # 发送消息
async for msg in client.receive_response(): # 接收回复
pass
# 控制
await client.interrupt() # 中断执行
await client.set_permission_mode("mode") # 切换权限
await client.set_model("model") # 切换模型
# 状态管理
await client.rewind_files(msg_id) # 回滚文件
status = await client.get_mcp_status() # MCP 状态
本课小结
- ClaudeSDKClient 支持多轮对话,适合交互式 DevOps 工作
async with确保资源正确清理- 动态切换权限:先分析(只读)→ 再修改(读写)
- 动态切换模型:简单任务用便宜模型,复杂任务用强模型
rewind_files()回滚文件,interrupt()紧急中断
课后练习
- 跑一下上面的交互式命令行 DevOps 助手
- 试试
set_permission_mode()在 "default" 和 "acceptEdits" 之间切换 - 让 AI 修改一个文件,然后用
rewind_files()回滚,验证文件恢复了