📋 AI Agent 学习路线验收标准文档
本文档详细说明每个练习项目的验收标准、验证方法和预期结果。
📅 Day 1:异步编程核心
练习项目:异步批量调用多个 API(模拟 Agent 多工具并发调用)
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载,没有语法错误 | 验收脚本动态加载你的 .py 文件 | 5 分 |
| 2 | 异步请求:是 async 协程函数,返回 url/status/data 结构 | 脚本真的调用 异步请求() 并检查返回字典 | 20 分 |
| 3 | 并发请求:3 个请求结果正确且真并发(总耗时接近单次而非 3 倍) | 脚本用你自己的单次耗时做基准,真实计时对比 | 25 分 |
| 4 | 同步请求:返回结果正确(作为性能对比的慢基准) | 脚本调用 同步请求() | 8 分 |
| 5 | 性能对比:运行后打印同步/异步两种耗时 | 脚本捕获你的输出并检查 | 12 分 |
| 6 | 重试机制:第 1 次模拟失败后能重试并成功 | 脚本注入假 random(第 1 次失败、之后成功)观察行为 | 20 分 |
| 7 | 类型注解:至少 4 个函数有返回值注解 | AST 静态检查 | 10 分 |
总分:100 分
- 80-100 分:✅ 验收通过,继续 Day 2
- 60-79 分:⚠️ 基本通过,但有改进空间
- 60 分以下:❌ 未通过,需要重做
🔍 验收方式
# 方式 1:自动验收脚本(推荐)
python day01_practice_validator.py
# 方式 2:手动运行你的练习代码
python your_file.py
# 观察输出:异步总耗时应明显小于同步总耗时
📊 预期性能指标
| 调用方式 | 5 个 API 的延迟 | 预期总耗时 | 性能提升 |
|---|---|---|---|
| 同步(逐个) | 1s × 5 | ~5s | - |
| 异步(并发) | 最长的延迟 | ~1s | ~80% |
💡 完整标准答案
参考文件 tutorial_02_async.py(运行它跟着学)
📅 Day 2:类型系统与装饰器进阶
练习项目:用 Pydantic 定义 Tool Schema,并用装饰器实现工具注册机制
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载(需要 pydantic) | 动态加载;缺依赖会提示 pip install pydantic | 5 分 |
| 2 | 装饰器内使用 functools.wraps | AST 检查 @工具 装饰器内部 | 10 分 |
| 3 | 工具注册表:注册 ≥3 个工具且包含「计算器」,信息含 描述/函数 | 加载后检查 工具注册表 内容 | 15 分 |
| 4 | 调用工具:调用工具('计算器', 表达式='3 + 5 * 2') 算出 13 | 脚本真的调用你的函数并核对结果 | 20 分 |
| 5 | 输入验证:表达式传 int 等错误类型会被拦截 | 脚本故意传错误类型,要求抛异常或返回错误信息 | 15 分 |
| 6 | 列出所有工具:≥3 个,均为 OpenAI Function Calling 格式(含 parameters.properties) | 逐项检查结构(提示:用 model_json_schema()) | 20 分 |
| 7 | 注册的函数可直接调用,且保留原函数名(wraps 真的生效) | 调用注册表里的函数并检查 __name__ | 15 分 |
总分:100 分
- 80-100 分:✅ 验收通过
- 60-79 分:⚠️ 基本通过
- 60 分以下:❌ 未通过
🔍 验收方式
# 自动验收脚本
python day02_practice_validator.py
# 指定文件
python day02_practice_validator.py --file my_practice.py
💡 关键检查点
# ✅ 正确的装饰器写法
def 工具(名称, 描述):
def 装饰器(func):
@functools.wraps(func) # ← 必须有!
def 包装(**kwargs):
# 输入验证
输入 = 输入模型(**kwargs)
# 调用原函数
结果 = func(**输入.model_dump())
# 输出验证
return 输出模型(**结果)
# 注册
工具注册表[名称] = {"函数": 包装, "描述": 描述}
return 包装
return 装饰器
💡 完整标准答案
参考文件 tutorial_01_decorators.py(第 8 步:AI Agent 实战)
📅 Day 3:生成器、迭代器与上下文管理器
练习项目:实现一个流式 LLM 响应的异步生成器包装器
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载你的 .py 文件 | 5 分 |
| 2 | 同步生成器:逐块 yield ≥3 个 chunk,都是字符串 | 脚本真的 list() 迭代你的生成器 | 15 分 |
| 3 | 异步生成器:可用 async for 迭代出 ≥3 个 chunk(async def 里必须有 yield) | 脚本真的异步迭代 | 15 分 |
| 4 | 同步计时器类:__enter__ 返回 self,with 结束后打印耗时 | 脚本真的进入你的 with 块 | 10 分 |
| 5 | @contextmanager 版本可用(yield 前后逻辑正确) | 脚本真的进入并退出 | 10 分 |
| 6 | 异步计时器类:__aenter__ 返回 self | 脚本真的 async with | 10 分 |
| 7 | @asynccontextmanager 版本可用 | 脚本真的 async with | 10 分 |
| 8 | 流式 LLM 客户端:chat() 返回异步生成器并逐块产出 ≥3 个 chunk | 脚本真的 async for 迭代你的 chat() | 25 分 |
总分:100 分
🔍 验收方式
python day03_practice_validator.py
💡 关键代码示例
# 异步生成器(核心)
async def 流式输出(提示词: str) -> AsyncGenerator[str, None]:
for chunk in ["我", "喜欢", "写代码"]:
await asyncio.sleep(0.2) # 模拟延迟
yield chunk # ← 多次 yield
# 使用
async for chunk in 流式输出("Hello"):
print(chunk, end="")
📅 Day 4:LLM API 调用与 Prompt 工程
练习项目:实现支持 Function Calling 的 LLM 客户端
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载你的 .py 文件 | 5 分 |
| 2 | tools 参数:≥2 个工具,均为 OpenAI Function Calling 格式 | 调用你的 get_tools_for_api() 逐项检查 | 15 分 |
| 3 | 解析 tool_calls:id/name/arguments(arguments 要 json.loads 成字典) | 用构造好的 LLM 响应喂你的 parse_tool_calls() | 20 分 |
| 4 | 执行工具:calculator 真的算出 13 | 脚本调用你的 execute_tool_call() | 20 分 |
| 5 | 对话闭环:天气问题给出非空回答 | 脚本真的跑你的 chat_with_function_calling() | 15 分 |
| 6 | 对话闭环:计算问题给出回答 | 同上(换一个问题) | 15 分 |
| 7 | 错误处理:核心函数中有 try/except(JSON 解析必须容错) | AST 检查 | 10 分 |
🔍 验收方式
# 内置 mock LLM,无需 API Key 即可完成全部必做验收
python day04_practice_validator.py
# TODO 5.1(可选):有 DeepSeek 等 Key 时把 mock 换成真实 API 再玩一遍💡 关键流程
用户提问
↓
构造 messages + tools,调用 LLM API
↓
LLM 返回 tool_calls?(是/否)
├─ 是 → 解析 tool_calls → 执行对应函数 → 结果追加到 messages → 再次调用 LLM
└─ 否 → 返回最终回答
📅 Day 5:阶段一实战——命令行 AI 助手
练习项目:综合练习,集成异步 + Pydantic + Function Calling + 流式输出
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载(需要 pydantic) | 动态加载 | 5 分 |
| 2 | tools 参数:≥2 个工具格式正确 | 调用你的 get_tools_for_api() | 15 分 |
| 3 | 执行工具:calculator 算出 13 | 调用你的 execute_tool() | 15 分 |
| 4 | 流式 LLM:chat() 是异步生成器并逐块输出 | 脚本真的异步迭代你的 chat() | 20 分 |
| 5 | 端到端:计算问题——回答里必须包含工具算出的 13 | 脚本构建你的 Agent 发起真实对话 | 20 分 |
| 6 | 端到端:天气问答闭环 | 同上(换一个问题) | 10 分 |
| 7 | Function Calling:对话历史中有 role=tool 的消息(结果真的回传了) | 检查你的 messages 列表 | 10 分 |
| 8 | Pydantic 模型:≥3 个 BaseModel 子类 | AST 检查 | 5 分 |
🔍 验收方式
python day05_practice_validator.py
# 交互式体验(把模板末尾 run_cli 的注释打开):
# 输入"帮我计算 3 + 5 * 2" → 应调用工具并回答 13
# 输入"exit" 退出📅 Day 6:Agent 架构原理(核心!)
练习项目:不依赖框架,纯 Python 手写一个 ReAct Agent 循环
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载 | 5 分 |
| 2 | 工具描述:包含 Calculator 和 Weather(放进 System Prompt 的清单) | 调用你的 get_tools_description() | 10 分 |
| 3 | 执行工具:Calculator[3 + 5 * 2] 返回 success 且输出含 13 | 调用你的 execute_tool() | 15 分 |
| 4 | 解析 Action 响应:Thought/Action/Action Input 提取正确 | 用样例响应喂你的 parse_react_response() | 13 分 |
| 5 | 解析 Final Answer 响应:action 为空、答案在 action_input | 同上(换样例) | 12 分 |
| 6 | Agent 端到端:计算题——正常终止且回答含工具算出的 13(死循环直接判负) | 脚本真跑你的 react_agent() | 20 分 |
| 7 | Agent 端到端:天气题——回答包含查询结果 | 同上 | 15 分 |
| 8 | 循环结构:react_agent 内有 for 循环(步数上限)和 await | AST 检查 | 10 分 |
总分:100 分
🔍 验收方式
python day06_practice_validator.py
💡 ReAct 循环伪代码
async def react_agent(user_input: str, max_steps: int = 10):
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
messages.append({"role": "user", "content": user_input})
for step in range(max_steps):
# 1. 调用 LLM
response = await llm_chat(messages)
# 2. 解析响应
thought, action, action_input = parse_react_response(response)
# 3. 如果是 Final Answer,返回
if not action:
return action_input # 最终答案
# 4. 执行工具
observation = await execute_tool(action, action_input)
# 5. 把结果加入 messages
messages.append({"role": "assistant", "content": response})
messages.append({"role": "user", "content": f"Observation: {observation}"})
return "达到最大步数限制"
📅 Day 7:LangGraph 入门
练习项目:用 LangGraph 实现带条件分支的 ReAct Agent
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载 | 5 分 |
| 2 | AgentState:定义了 messages 和 step_count 字段 | 检查 TypedDict 注解 | 10 分 |
| 3 | tools 参数格式正确 | 调用你的 get_tools_for_api() | 10 分 |
| 4 | 执行工具:calculator 算出 13 | 调用你的 execute_tool() | 10 分 |
| 5 | call_model 节点:追加 assistant 消息、step_count +1(兼容部分更新返回) | 脚本构造 state 调用你的节点 | 15 分 |
| 6 | call_tool 节点:追加 role=tool 消息且内容含真实工具结果 | 构造带 tool_calls 的 state 调用 | 15 分 |
| 7 | 条件路由:有 tool_calls → 'call_tool',无 → 'end' | 两种 state 分别试探你的 router | 15 分 |
| 8 | 端到端:run_agent 完整跑通,回答含工具结果(未装 langgraph 可用模拟器降级) | 脚本真跑你的 run_agent | 20 分 |
🔍 验收方式
python day07_practice_validator.py
# 未安装 langgraph 也能验收:run_agent 允许降级调用内置模拟器
# 装了真实库(pip install langgraph)后取消 build_agent_graph 的注释即可无缝切换💡 关键代码框架
from langgraph.graph import StateGraph, END
class AgentState(TypedDict):
messages: list
# 其他状态字段
graph = StateGraph(AgentState)
graph.add_node("call_model", call_model)
graph.add_node("call_tool", call_tool)
graph.add_conditional_edges("call_model", should_continue)
graph.add_edge("call_tool", "call_model")
📅 Day 8:工具系统与 MCP 协议
练习项目:写一个简单的 MCP Server,在 Agent 中调用
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载你的 .py 文件 | 5 分 |
| 2 | tools/list:MockMCPServer.get_tool_list 列出 ≥2 个工具(含 name/description) | 调用并检查结构 | 15 分 |
| 3 | tools/call:calculator 经服务器真的算出 30(10 + 20) | 调用你的 call_tool 核对结果 | 15 分 |
| 4 | 超时控制:工具包装器内有 asyncio.wait_for | AST 检查 | 10 分 |
| 5 | MCPClient:connect 后 list_tools 能拿到工具列表 | 真的构建客户端并连接 | 15 分 |
| 6 | MCPClient.call_tool:calculator 算出 42 | 经客户端调用核对 | 10 分 |
| 7 | Agent 集成:问'帮我计算 10 + 20'得到包含 30 的回答 | 端到端跑你的 agent_with_mcp | 20 分 |
| 8 | read_note 工具:能读取文件内容 | 写临时文件 → 调用 → 核对内容 | 10 分 |
🔍 验收方式
# 终端 1:启动 MCP Server
mcp run your_mcp_server.py
# 终端 2:运行 Agent(连接到 MCP Server)
python your_day08_agent.py
📅 Day 9:记忆系统与 RAG
练习项目:实现能记住对话历史、并能从文档库检索知识的 Agent
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载 | 5 分 |
| 2 | 短期记忆:添加 + 裁剪(超限自动裁、system 永远保留、最新消息在) | 真加 6 条消息看裁剪结果 | 12 分 |
| 3 | 短期记忆:to_api_format 转成 role/content 字典列表 | 调用并检查结构 | 8 分 |
| 4 | 短期记忆:clear 清空历史但保留 system | 调用后检查 | 5 分 |
| 5 | 向量存储:添加文档后检索,最相关文档排第一且得分 > 0 | 加 3 条文档、查询、核对排序 | 20 分 |
| 6 | RAG 检索器:retrieve 返回包含关键词的资料文本 | 加知识 → 检索 → 核对 | 15 分 |
| 7 | MemoryAgent:两轮对话,第一轮用户消息被记住、第二轮历史仍保留 | 真的跑两轮 chat 并检查记忆列表 | 15 分 |
| 8 | compress_conversation:压缩后变短、system 保留、最新消息保留 | 构造 9 条消息、限制 token、核对 | 15 分 |
| 9 | 类型注解:至少 4 个函数有返回值注解 | AST 检查 | 5 分 |
🔍 验收方式
python your_day09_agent.py
# 测试多轮对话
> 我叫张三
✅ Agent:你好张三!
> 我叫什么名字?
✅ Agent:你叫张三。(从对话历史检索到)
📅 Day 10:阶段二实战——多工具 Agent
练习项目:用 LangGraph 构建多工具 Agent
✅ 验收标准(自动验收,共 100 分)
| 序号 | 验收标准 | 验证方法(行为级:验收脚本真的调用你的代码) | 分值 |
|---|---|---|---|
| 1 | 代码可以加载 | 动态加载 | 5 分 |
| 2 | 工具系统:注册至少 4 个工具 | 检查 TOOLS_REGISTRY | 20 分 |
| 3 | 工具包装器:calculator 经(超时+重试)包装器可异步调用 | 真的 await 调用 | 10 分 |
| 4 | 错误恢复成功路径:calculator → ToolResult(success=True, 含 13) | 调用 execute_tool_with_recovery | 15 分 |
| 5 | 错误恢复失败路径:不存在的工具不崩溃,返回 success=False | 传不存在的工具名试探 | 15 分 |
| 6 | Agent:返回真实回答(不是模板占位符'最终回答') | 构造记忆桩、端到端调用 | 10 分 |
| 7 | Agent 真的执行了工具:用间谍函数拦截 calculator,至少被调用 1 次 | 替换注册表函数为间谍后跑 Agent | 20 分 |
| 8 | 类型注解:至少 4 个函数有返回值注解 | AST 检查 | 5 分 |
📅 Day 11-15:完整项目实战
项目:智能开发助手 Agent
🛠 脚手架:project_day11_15/ 目录已提供分层 FastAPI 骨架和全部 TODO(用法见其中 README),Day 11-15 的开发都在该目录进行;Day 11 学习页 / Day 12 学习页 有逐步指引。
✅ 验收标准(项目交付清单)
Day 11-12:核心开发
- ☐ 项目有清晰的目录结构
- ☐ FastAPI 后端框架搭建完成
- ☐ Agent 核心循环实现(ReAct 或 LangGraph)
- ☐ 工具系统:至少 4 个可用工具
Day 13:Web UI
- ☐ FastAPI + SSE(Server-sent Events)实现流式 API
- ☐ 简单 Web 前端(Streamlit / Gradio / 纯 HTML+JS)
- ☐ Agent 思考过程可视化(显示 Thought、Action、Observation)
Day 14:测试与部署
- ☐ 单元测试(pytest + pytest-asyncio)
- ☐ Token 消耗统计与优化
- ☐ Docker 容器化(Dockerfile + docker-compose.yml)
- ☐ 部署到云服务器或本地运行
Day 15:文档
- ☐ README.md:项目介绍、安装步骤、使用方法
- ☐ 架构图(可以用 Markdown 画图或贴图)
- ☐ 示例代码
📊 综合评分标准
| 阶段 | 天数 | 通过分数 | 目标 |
|---|---|---|---|
| 阶段一 | Day 1-5 | 每 day ≥ 60 分 | 掌握 Python 高级特性 + LLM API |
| 阶段二 | Day 6-10 | 每天自动验收 ≥80 分 | 掌握 Agent 架构 |
| 阶段三 | Day 11-15 | 项目交付清单完成 ≥ 80% | 完整可部署的 Agent |
🔧 使用验收脚本
| 脚本名称 | 对应日期 | 功能 |
|---|---|---|
day01_practice_validator.py |
Day 1 | 自动检查异步代码质量、性能对比 |
day02_practice_validator.py |
Day 2 | 检查 Pydantic Schema + 装饰器注册 |
day03_practice_validator.py |
Day 3 | 检查生成器 + 上下文管理器 |
day04_practice_validator.py |
Day 4 | 检查 Function Calling 流程 |
day05_practice_validator.py |
Day 5 | 检查命令行 AI 助手综合实现 |
day06_practice_validator.py |
Day 6 | 检查 ReAct Agent 循环逻辑 ⭐ |
day07_practice_validator.py |
Day 7 | 检查 LangGraph 图结构 |
day08_practice_validator.py |
Day 8 | 检查 MCP Server / 客户端 / Agent 集成 |
day09_practice_validator.py |
Day 9 | 检查记忆裁剪 / 向量检索 / RAG / 多轮记忆 |
day10_practice_validator.py |
Day 10 | 检查多工具 / 错误恢复 / 间谍函数验证工具调用 |
使用方法:
# 先用模板创建你的练习代码
# (模板文件:day01_practice_template.py 等)
# 编辑模板,完成所有 TODO
# 运行验收脚本
python day01_practice_validator.py
python day01_practice_validator.py --file my_code.py # 指定文件
💡 常见问题
Q1:验收脚本报错了,怎么办?
A:仔细阅读脚本输出的"改进建议"部分,逐项修改你的代码,然后重新运行验收脚本。
Q2:我的代码能运行,但验收脚本不给满分?
A:验收脚本不仅检查"能运行",还检查"最佳实践"(类型注解、错误处理、代码规范等)。根据建议改进即可。
Q3:Day 8/9/10 的验收和其他天一样吗?
A:一样。python day08/09/10_practice_validator.py 都是行为级验收(真的调用你的 Server/记忆/Agent)。文档中的"手动检查清单"仍可作为深度自查的补充。
Q4:我可以参考标准答案吗?
A:项目暂不提供标准答案——建议先自己尝试。卡住时可以:① 对照验收脚本的逐项提示(它会告诉你差在哪);② 重读 TODO 的 docstring,需求都写在里面;③ 让 AI 助手帮你解读报错,但代码尽量自己写。
祝你学习顺利!遇到任何问题,随时问我! 🚀