{ "cells": [ { "cell_type": "markdown", "id": "252eb5a2", "metadata": {}, "source": [ "# 智能编程导师 (Intelligent Programming Tutor)\n", "\n", "一个基于多智能体协作的个性化编程学习系统,展示了如何使用 `hello-agents` 框架构建复杂的 Agent-to-Agent (A2A) 协作系统。\n", "\n", "## 系统架构\n", "\n", "本系统采用分层智能体架构:\n", "\n", "- **Tutor(导师)**:主协调智能体,负责与用户交互并调度子智能体\n", "- **Planner(规划师)**:分析用户需求,制定个性化学习计划\n", "- **Exercise(出题人)**:根据学习内容生成针对性的编程练习题\n", "- **Reviewer(评审员)**:评审用户代码,提供专业反馈和改进建议\n", "\n", "## 技术特点\n", "\n", "1. **多智能体协作**:使用 `AgentTool` 将子智能体封装为工具,实现 A2A 通信\n", "2. **工具调用**:Reviewer 配备 `CodeRunner` 工具,可执行 Python 代码验证\n", "3. **模块化设计**:每个智能体职责单一,易于维护和扩展\n", "\n", "## 演示说明\n", "\n", "本 notebook 包含三个完整的测试场景,展示了智能编程导师的核心功能。" ] }, { "cell_type": "markdown", "id": "setup_intro", "metadata": {}, "source": [ "## 步骤 1:环境设置\n", "\n", "初始化 LLM 和环境配置。\n", "\n", "**关键组件**:\n", "- `HelloAgentsLLM`:统一的 LLM 接口\n", "- `.env` 文件:存储 API 密钥等敏感信息\n", "- `src` 路径:包含自定义智能体和工具的实现" ] }, { "cell_type": "code", "execution_count": 1, "id": "3a142c96", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "✅ 环境配置完成\n", "✅ LLM 已初始化\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/chen/vs_code/hello_agent/hello-agents/.conda/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } ], "source": [ "# 1. 环境设置\n", "import os\n", "import sys\n", "from dotenv import load_dotenv\n", "from hello_agents import HelloAgentsLLM\n", "\n", "load_dotenv()\n", "\n", "if \"src\" not in sys.path:\n", " sys.path.append(os.path.abspath(\"src\"))\n", "\n", "# 初始化 LLM\n", "llm = HelloAgentsLLM()\n", "\n", "print(\"✅ 环境配置完成\")\n", "print(\"✅ LLM 已初始化\")" ] }, { "cell_type": "markdown", "id": "tutor_init_intro", "metadata": {}, "source": [ "## 步骤 2:初始化智能编程导师\n", "\n", "创建 `TutorAgent` 实例时,会自动:\n", "1. 创建 Planner、Exercise、Reviewer 三个子智能体\n", "2. 将子智能体封装为工具(`call_planner`、`call_exercise`、`call_reviewer`)\n", "3. 注册 `CodeRunner` 工具给 Reviewer 使用\n", "\n", "**架构亮点**:\n", "- 使用 `AgentTool` 实现 Agent-to-Agent 调用\n", "- 每个子智能体有独立的 `system_prompt` 定义其专业领域\n", "- Tutor 通过工具调用协调所有子智能体" ] }, { "cell_type": "code", "execution_count": 2, "id": "7728b695", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "创建智能编程导师...\n", "✅ 工具 'code_runner' 已注册。\n", "✅ 工具 'call_planner' 已注册。\n", "✅ 工具 'call_exercise' 已注册。\n", "✅ 工具 'call_reviewer' 已注册。\n", "\n", "✅ Tutor 初始化完成!\n", " - Planner(规划师)已就绪\n", " - Exercise(出题人)已就绪\n", " - Reviewer(评审员)已就绪\n" ] } ], "source": [ "# 2. 初始化 Tutor(自动创建所有子智能体)\n", "from agents.tutor import TutorAgent\n", "\n", "print(\"创建智能编程导师...\")\n", "tutor = TutorAgent(llm)\n", "\n", "print(\"\\n✅ Tutor 初始化完成!\")\n", "print(\" - Planner(规划师)已就绪\")\n", "print(\" - Exercise(出题人)已就绪\") \n", "print(\" - Reviewer(评审员)已就绪\")" ] }, { "cell_type": "markdown", "id": "072727a2", "metadata": {}, "source": [ "---\n", "\n", "## 测试 1:请求学习计划\n", "\n", "演示 **Tutor → Planner** 的协作流程。\n", "\n", "**执行流程**:\n", "1. 用户向 Tutor 表达学习目标\n", "2. Tutor 识别意图并调用 `call_planner` 工具\n", "3. Planner 分析需求,生成分模块的学习计划\n", "4. Tutor 将学习计划友好地呈现给用户\n", "\n", "**期望输出**:包含多个学习模块、时间安排、学习建议的完整学习路径。" ] }, { "cell_type": "code", "execution_count": 3, "id": "033dc763", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "用户目标: 我想学习 Python 中的列表推导式\n", "\n", "=== Tutor 回应 ===\n", "# Python列表推导式学习计划\n", "\n", "您好!很高兴为您制定Python列表推导式的学习计划。列表推导式是Python中一个强大而优雅的特性,能让您的代码更加简洁高效。\n", "\n", "## 学习目标\n", "掌握Python列表推导式的语法、应用场景和最佳实践,提升代码简洁性和可读性。\n", "\n", "## 详细学习路径\n", "\n", "### 模块1: 基础概念与语法 (2-3天)\n", "您将学习:\n", "- 列表推导式的基本语法结构 `[expression for item in iterable]`\n", "- 与传统for循环的对比\n", "- 理解表达式、迭代变量和可迭代对象的关系\n", "- 创建简单的数值列表\n", "- 字符串处理应用\n", "\n", "### 模块2: 条件过滤 (3-4天)\n", "您将学习:\n", "- 带条件的列表推导式 `[expression for item in iterable if condition]`\n", "- 单一条件过滤\n", "- 多条件组合 (and, or, not)\n", "- 实际应用场景:数据筛选、文本处理\n", "- 性能优势理解\n", "\n", "### 模块3: 复杂表达式与嵌套 (4-5天)\n", "您将学习:\n", "- 复杂表达式的构建\n", "- 嵌套列表推导式 `[[expression for item2 in iterable2] for item1 in iterable1]`\n", "- 处理二维列表和矩阵\n", "- 嵌套循环的简化\n", "- 可读性考虑\n", "\n", "### 模块4: 高级应用与其他推导式 (3-4天)\n", "您将学习:\n", "- 字典推导式 `{key_expr: value_expr for item in iterable}`\n", "- 集合推导式 `{expression for item in iterable}`\n", "- 生成器表达式 `(expression for item in iterable)`\n", "- 何时使用列表推导式 vs 其他方法\n", "- PEP 8规范和代码风格\n", "\n", "### 模块5: 实战项目与优化 (3-4天)\n", "您将学习:\n", "- 实际项目中的应用案例\n", "- 性能测试和比较\n", "- 代码重构练习\n", "- 常见陷阱和错误避免\n", "- 最佳实践总结\n", "\n", "## 学习建议\n", "- 每天编写至少3-5个练习代码\n", "- 结合实际数据处理场景练习\n", "- 注意代码可读性,避免过度复杂的推导式\n", "- 定期回顾和重构自己的代码\n", "\n", "**预计总时长:** 约2-3周 (根据个人基础调整)\n", "\n", "现在您想开始学习哪个模块呢?如果您需要相关的练习题来巩固所学知识,请随时告诉我!\n" ] } ], "source": [ "user_goal = \"我想学习 Python 中的列表推导式\"\n", "print(f\"用户目标: {user_goal}\\n\")\n", "\n", "# Tutor 会调用 call_planner 工具\n", "response = tutor.run(f\"用户说:'{user_goal}'。请为用户制定学习计划。\")\n", "\n", "print(\"=== Tutor 回应 ===\")\n", "print(response)" ] }, { "cell_type": "markdown", "id": "test2_desc", "metadata": {}, "source": [ "---\n", "\n", "## 测试 2:请求练习题\n", "\n", "演示 **Tutor → Exercise** 的协作流程。\n", "\n", "**执行流程**:\n", "1. 用户向 Tutor 请求练习题\n", "2. Tutor 调用 `call_exercise` 工具\n", "3. Exercise 生成结构化的编程练习题\n", "4. Tutor 返回包含题目描述、示例、约束条件的完整题目\n", "\n", "**期望输出**:一道高质量的编程练习题,包含:\n", "- 题目描述\n", "- 输入/输出示例\n", "- 约束条件\n", "- 函数签名" ] }, { "cell_type": "code", "execution_count": 4, "id": "6703c3c7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=== Tutor 回应 ===\n", "# Python 列表推导式练习题\n", "\n", "## 题目描述\n", "编写一个函数 `filter_and_square_numbers()`,该函数接收一个整数列表和一个阈值,返回一个新的列表,其中包含原列表中所有大于阈值的数字的平方。\n", "\n", "要求使用列表推导式来实现这个功能,而不是传统的for循环。\n", "\n", "## 示例\n", "\n", "**示例 1:**\n", "```python\n", "输入: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], threshold = 5\n", "输出: [36, 49, 64, 81, 100]\n", "解释: 大于5的数字是6,7,8,9,10,它们的平方分别是36,49,64,81,100\n", "```\n", "\n", "**示例 2:**\n", "```python\n", "输入: numbers = [-3, -1, 0, 2, 5, 8], threshold = 0\n", "输出: [4, 25, 64]\n", "解释: 大于0的数字是2,5,8,它们的平方分别是4,25,64\n", "```\n", "\n", "**示例 3:**\n", "```python\n", "输入: numbers = [1, 3, 5], threshold = 10\n", "输出: []\n", "解释: 没有数字大于10,所以返回空列表\n", "```\n", "\n", "## 约束条件\n", "- 输入列表可以包含正数、负数和零\n", "- 阈值可以是任意整数(正数、负数或零)\n", "- 必须使用列表推导式实现\n", "- 不允许使用传统的for循环或while循环\n", "- 函数应该能够处理空列表的情况\n", "\n", "## 函数签名\n", "```python\n", "def filter_and_square_numbers(numbers: list, threshold: int) -> list:\n", " pass\n", "```\n", "\n", "---\n", "\n", "💡 **提示**: 列表推导式的基本语法是 `[expression for item in iterable if condition]`\n", "\n", "试着完成这个练习,如果您需要任何帮助或者想要我评审您的代码,请随时告诉我!\n" ] } ], "source": [ "# Tutor 会调用 call_exercise 工具\n", "response = tutor.run(\"请给我出一道关于列表推导式的练习题。\")\n", "\n", "print(\"=== Tutor 回应 ===\")\n", "print(response)" ] }, { "cell_type": "markdown", "id": "test3_desc", "metadata": {}, "source": [ "---\n", "\n", "## 测试 3:提交代码评审\n", "\n", "演示 **Tutor → Reviewer → CodeRunner** 的多层协作流程。\n", "\n", "**执行流程**:\n", "1. 用户提交代码给 Tutor 评审\n", "2. Tutor 调用 `call_reviewer` 工具\n", "3. Reviewer 使用 `code_runner` 工具执行代码验证\n", "4. Reviewer 分析代码逻辑、风格和性能\n", "5. Tutor 返回详细的评审报告\n", "\n", "**技术亮点**:\n", "- Reviewer 能够实际运行代码获取输出\n", "- 提供结构化的评审反馈(优点、问题、改进建议)\n", "- 支持代码片段和函数定义两种形式\n", "\n", "**测试代码说明**:\n", "用户尝试解答测试 2 中的练习题(筛选正偶数并求平方),Reviewer 会验证代码的正确性。" ] }, { "cell_type": "code", "execution_count": 5, "id": "f9019406", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=== 用户代码 ===\n", "\n", "def filter_and_square_numbers(numbers):\n", " return [n * n for n in numbers if n > 0 and n % 2 == 0]\n", "\n", "# 测试\n", "test_list = [1, 2, 3, 4, 5, 6, -2, -4, 0]\n", "result = filter_and_square_numbers(test_list)\n", "print(result)\n", "\n", "\n", "=== Tutor 回应 ===\n", "# 代码评审\n", "\n", "## 总体评价\n", "您的代码基本实现了筛选正偶数并求平方的功能,但存在一些与题目要求不符的地方。让我详细分析一下:\n", "\n", "## 发现的问题\n", "\n", "1. **函数签名不完整**: \n", " - 题目要求函数接受两个参数(`numbers`和`threshold`),但您的实现只接受一个参数\n", " - 缺少阈值参数,无法满足题目的完整需求\n", "\n", "2. **逻辑不符合题目要求**:\n", " - 题目示例显示应该筛选\"大于阈值\"的数字,但您的代码固定筛选\"大于0\"的数字\n", " - 这使得函数不够通用,无法处理不同的阈值需求\n", "\n", "3. **硬编码条件**:\n", " - 使用了固定的条件`n > 0`而不是基于传入的阈值参数\n", "\n", "## 改进建议\n", "\n", "```python\n", "def filter_and_square_numbers(numbers, threshold):\n", " # 应该筛选大于threshold的数字,并返回它们的平方\n", " return [n * n for n in numbers if n > threshold]\n", "\n", "# 或者如果确实只需要正偶数:\n", "def filter_positive_even_squares(numbers, threshold):\n", " return [n * n for n in numbers if n > threshold and n > 0 and n % 2 == 0]\n", "```\n", "\n", "## 测试结果分析\n", "\n", "对于您的测试用例`[1, 2, 3, 4, 5, 6, -2, -4, 0]`:\n", "- 输出`[4, 16, 36]`是正确的(对应数字2, 4, 6)\n", "- 但如果threshold设置为3,则应返回`[16, 36]`(对应数字4, 6)\n", "\n", "## 评分\n", "- 功能正确性: ⭐⭐⭐☆☆ (部分正确)\n", "- 代码质量: ⭐⭐⭐⭐☆ (列表推导式使用恰当)\n", "- 符合要求: ⭐⭐☆☆☆ (未满足完整的题目要求)\n", "\n", "请根据上述建议修改代码以完全符合题目要求!\n" ] } ], "source": [ "# 用户尝试解答上面的练习题\n", "user_code = \"\"\"\n", "def filter_and_square_numbers(numbers):\n", " return [n * n for n in numbers if n > 0 and n % 2 == 0]\n", "\n", "# 测试\n", "test_list = [1, 2, 3, 4, 5, 6, -2, -4, 0]\n", "result = filter_and_square_numbers(test_list)\n", "print(result)\n", "\"\"\"\n", "\n", "print(f\"=== 用户代码 ===\\n{user_code}\\n\")\n", "\n", "# Tutor 会调用 call_reviewer 工具\n", "response = tutor.run(f\"\"\"用户尝试解答前面的列表推导式练习题,请评审以下代码:\n", "\n", "{user_code}\n", "\n", "题目要求:筛选出正偶数并返回它们的平方。\"\"\")\n", "\n", "print(\"=== Tutor 回应 ===\")\n", "print(response)" ] }, { "cell_type": "markdown", "id": "conclusion", "metadata": {}, "source": [ "---\n", "\n", "## 总结\n", "\n", "本演示展示了如何使用 `hello-agents` 框架构建多智能体协作系统。\n", "\n", "### 关键技术\n", "\n", "1. **AgentTool**:将智能体封装为工具,实现 A2A 调用\n", " ```python\n", " self.add_tool(AgentTool(\n", " self.planner,\n", " name=\"call_planner\",\n", " description=\"调用课程规划师\"\n", " ))\n", " ```\n", "\n", "2. **工具链**:Reviewer 使用 CodeRunner 执行代码\n", " ```python\n", " ReviewerAgent(llm, tools=[CodeRunner()])\n", " ```\n", "\n", "3. **System Prompt**:通过精心设计的提示词定义智能体行为\n", "\n", "### 扩展建议\n", "\n", "- 添加学习进度追踪功能\n", "- 支持更多编程语言\n", "- 集成代码风格检查工具(如 Pylint)\n", "- 添加知识库检索增强(RAG)\n", "\n", "### 项目结构\n", "\n", "```\n", "src/\n", "├── agents/\n", "│ ├── tutor.py # 主协调智能体\n", "│ ├── planner.py # 学习计划制定\n", "│ ├── exercise.py # 练习题生成\n", "│ └── reviewer.py # 代码评审\n", "└── tools/\n", " ├── agent_tool.py # A2A 工具封装\n", " └── code_runner.py # 代码执行工具\n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }