学会用 query() 给 Claude 发消息、收回复。这是最基础的操作,就像学开车先学踩油门。

第3课:第一次对话 —— 学会 query()

本课目标

学会用 query() 给 Claude 发消息、收回复。这是最基础的操作,就像学开车先学踩油门。


最简代码

code
"""
03_basic_query.py
最简单的一问一答
"""
import anyio
from claude_agent_sdk import query


async def main():
    async for message in query(prompt="什么是人工智能?用3句话解释"):
        print(message)


anyio.run(main)

运行:uv run python 03_basic_query.py

就这么几行,你已经在调用 Claude 了。


等一下,这代码在干嘛?

一行一行拆:

code
import anyio                    # 异步运行库(Claude SDK 是异步的)
from claude_agent_sdk import query   # 导入 query 函数

async def main():               # 异步函数,SDK 要求必须是异步的
    async for message in query(prompt="你的问题"):
        #     ↑ query() 返回的是一个"异步迭代器"
        #       意思是:消息不是一次性全给你的,而是一条一条蹦出来的
        print(message)

anyio.run(main)                 # 启动异步事件循环

关键概念:异步(async)

为什么非要用 async?因为调用 Claude API 需要等网络响应,异步能让你的程序在等待时不卡死。你暂时不用完全理解 async,只要记住:凡是调 SDK 的代码,都包在 async def 里,用 anyio.run() 启动


消息类型:Claude 回的到底是什么?

上面的代码把 message 直接 print 了,看起来乱七八糟的。让我们解析一下:

python
"""
03_parse_messages.py
解析消息类型
"""
import anyio
from claude_agent_sdk import query, AssistantMessage, ResultMessage, TextBlock


async def main():
    async for message in query(prompt="Python 和 JavaScript 哪个更适合初学者?"):

        # Claude 的回复
        if isinstance(message, AssistantMessage):
            print("【Claude 说】")
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)

        # 最终结果(包含花费信息等)
        elif isinstance(message, ResultMessage):
            print(f"\n--- 对话结束 ---")
            print(f"会话ID: {message.session_id}")
            # 如果有花费信息,可以在这里看到


anyio.run(main)

SDK 返回的消息有几种类型:

类型 是什么 你什么时候会遇到
AssistantMessage Claude 的回复 最常见,里面有文字内容
UserMessage 用户消息的回显 偶尔出现
SystemMessage 系统消息 初始化时可能出现
ResultMessage 对话结束的总结 每次对话结束时

AssistantMessage 里面的内容(content)也分几种 Block:

Block 类型 是什么
TextBlock 普通文字回复(最常见)
ToolUseBlock Claude 想要调用工具
ThinkingBlock Claude 的思考过程

现在只需要关注 TextBlock,其他的后面会用到。


给 Claude 加设定:system_prompt

光问问题有点无聊,我们给 Claude 设定一个角色:

code
"""
03_system_prompt.py
给 Claude 设定角色
"""
import anyio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock


async def main():
    options = ClaudeAgentOptions(
        system_prompt="你是一个资深的科技行业分析师,擅长用数据说话,回答简洁有力。",
        max_turns=1  # 只跑一轮(问一次答一次)
    )

    async for message in query(
        prompt="分析一下 2025 年 AI 芯片市场的竞争格局",
        options=options
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)


anyio.run(main)

ClaudeAgentOptions 是一个配置对象,相当于"设置面板"。这里我们用了两个设置:

  • system_prompt — 告诉 Claude "你是谁",决定它的回答风格
  • max_turns — 最多跑几轮对话。设成 1 就是一问一答

控制对话的长度和花费

在正式项目里,你肯定不想 Claude 无限制地跑下去。几个有用的参数:

code
options = ClaudeAgentOptions(
    system_prompt="你是一个研究助手",
    max_turns=3,            # 最多 3 轮对话
    max_budget_usd=0.50,    # 最多花 0.5 美元
)

max_budget_usd 特别重要——设个上限,防止 Claude 跑飞了把你的余额烧光。


选模型

Claude 有不同的模型,能力和价格不同:

code
options = ClaudeAgentOptions(
    model="haiku",    # 快又便宜,适合简单任务
    # model="sonnet",   # 中等水平,性价比高(默认)
    # model="opus",     # 最强但最贵,适合复杂推理
)

做研究平台时,组长可以用 sonnet,搜索员用 haiku(便宜快速),这样省钱。


本课小结

这节课你学到了:

  1. query(prompt="...") — 给 Claude 发消息的基本姿势
  2. 消息类型AssistantMessage 里的 TextBlock 是你最常用的
  3. ClaudeAgentOptions — 配置面板,控制角色、轮次、预算、模型
  4. 异步写法 — 记住 async def + anyio.run() 的套路就行

query() 适合"一锤子买卖"——问一个问题,拿到答案就走。但如果你想跟 Claude 来回聊天呢?那就需要下一课的 ClaudeSDKClient


课后练习

  1. 修改 system_prompt,让 Claude 扮演一个美食博主,问它推荐菜谱
  2. 试试不同的 model 参数(haiku / sonnet),对比回答质量和速度
  3. 设置 max_budget_usd=0.01,看看 Claude 在极低预算下还能不能正常回答

沿着当前专题继续,或返回课程目录重新整理阅读顺序。

返回课程目录