📖 Day 5 学习页:阶段一综合实战:命令行 AI 助手

Day 5:阶段一综合实战——命令行 AI 助手

🎯 今日目标:把 Day 2-4 的三块积木(Pydantic 模型、工具注册、流式输出 + Function Calling) 拼装成一个完整程序。今天几乎没有新知识,考的是组装能力——这正是"能跑 demo"和"能写项目"的分水岭。

📚 本日资源:📝 练习模板 | ✅ 验收脚本

⏱ 今日安排(约 2 小时)

时间内容方式
15min架构梳理:看懂组件关系图阅读
90min动手实操:完成 7 个 TODO,拼出完整 Agent编码
15min验收 + 交互测试:跑验收脚本,玩一下自己的 CLI验收

📖 第一步:看懂架构(今天的"理论"就这一张图)

┌─────────────────────────── CLI_Agent ───────────────────────────┐
│                                                                  │
│  messages: List[ChatMessage]   ← 全部状态都在这(Pydantic 模型)  │
│                                                                  │
│  chat(user_input):                                               │
│    1. messages.append(user 消息)                                 │
│    2. for round in range(max_tool_rounds):        ← 有上限!     │
│         async for chunk in client.chat(messages, tools):         │
│              │                        ← StreamingLLMClient      │
│              ├─ chunk 是 [TOOL_CALL] 标记?                       │
│              │     └─ 解析 → execute_tool() → 追加 tool 消息     │
│              └─ 普通文本 → 累积 + (可选)实时打印                │
│         有工具调用 → continue 下一轮(LLM 会引用工具结果)        │
│         没有工具调用 → return 最终回答                            │
└──────────────────────────────────────────────────────────────────┘

数据流向:用户输入 → LLM(流式)→ [TOOL_CALL] → 执行工具 → tool 消息回传 → LLM 再流式 → 最终回答。 今天 mock 的流式客户端会在第一轮流式输出文字 + 一个 [TOOL_CALL] 工具名: {参数JSON} 标记, 在第二轮(messages 里已有 tool 消息时)输出引用工具结果的最终回答——你的主循环要正确处理这两个阶段。

🛠 第二步:动手实操

  1. 打开模板:day05_practice_template.py,7 个 TODO:
    • TODO 1.1:可以补充 ToolResult 等 Pydantic 模型(Day 2 功底)
    • TODO 2.2:get_tools_for_api()(Day 4 原题)
    • TODO 2.3:execute_tool()(Day 4 原题)
    • TODO 3.1:StreamingLLMClient.chat() 改造成异步生成器(Day 3 功底:async def + yield)
    • TODO 4.1:CLI_Agent.chat() 主循环(核心,按架构图写)
  2. 运行自测:python day05_practice_template.py,3 个测试应看到流式输出和工具调用链。
  3. 玩自己的 Agent:把文件末尾 asyncio.run(run_cli()) 的注释打开,和它对话: 输入"帮我计算 3 + 5 * 2"、"北京天气"、"你好"(不走工具)、"clear"(清历史)、"exit"。
  4. 验收:python day05_practice_validator.py —— 验收会构建你的 Agent 发起真实对话, 检查回答里是否包含工具算出的 13(工具没真的执行是混不过去的),并检查 messages 里有没有 role=tool 的回传消息。

⚠️ 避坑

  • ❌ 解析 [TOOL_CALL] 后忘记把工具结果追加成 role=tool 消息 → 下一轮 LLM 拿不到结果
  • ❌ 主循环没有轮数上限 / 没有终止条件 → 验收直接超时判 0 分
  • ❌ 在 async 循环里直接用 input() 阻塞事件循环(模板 run_cli 已示范 asyncio.to_thread 的正确写法)
  • ✅ stream=False 时不要打印 chunk,返回完整字符串——验收就是这么调你的

✅ 阶段一结业标准

完成今天后你应该能不查资料手写:Pydantic Schema、工具注册装饰器、异步生成器、Function Calling 主循环。 明天开始进入真正的 Agent 架构。