{
    "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
}