{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# RequirementClarifierAgent - 多智能体需求澄清与技术方案助手\n", "\n", "## 项目简介\n", "使用 HelloAgents 的四个 SimpleAgent 协作,将模糊需求转化为结构化的需求与技术方案报告。\n", "\n", "## 作者信息\n", "- GitHub:[@zenith191](https://github.com/zenith191)\n", "- 日期:2026-07-30" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第1部分:环境配置" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 首次运行时取消下一行注释安装官方框架\n", "# %pip install -q \"hello-agents[all]==0.2.9\"\n", "\n", "import json\n", "import os\n", "import sys\n", "import time\n", "from pathlib import Path\n", "\n", "from dotenv import load_dotenv\n", "from hello_agents import HelloAgentsLLM, SimpleAgent, ToolRegistry\n", "from hello_agents.tools import Tool, ToolParameter\n", "from IPython.display import Markdown, display\n", "\n", "project_name = \"zenith191-RequirementClarifierAgent\"\n", "candidates = [\n", " Path.cwd(),\n", " Path.cwd() / \"Co-creation-projects\" / project_name,\n", " Path.cwd().parent / project_name,\n", "]\n", "PROJECT_ROOT = next(\n", " (path.resolve() for path in candidates if (path / \"main.py\").exists()),\n", " None,\n", ")\n", "if PROJECT_ROOT is None:\n", " raise FileNotFoundError(\"未找到项目目录,请从项目目录或仓库根目录启动 Notebook\")\n", "if str(PROJECT_ROOT) not in sys.path:\n", " sys.path.insert(0, str(PROJECT_ROOT))\n", "\n", "load_dotenv(PROJECT_ROOT / \".env\")\n", "\n", "from src.agents import build_agent_team\n", "from src.config import LLMSettings\n", "from src.tools import create_tool_registry\n", "from src.workflow import RequirementClarifierWorkflow\n", "\n", "print(f\"✅ 环境配置完成:{PROJECT_ROOT}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第2部分:工具定义\n", "\n", "项目通过官方 `Tool`、`ToolParameter` 和 `ToolRegistry` 提供两个确定性工具:需求完整度初检和报告结构质检。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tool_registry = create_tool_registry()\n", "assert isinstance(tool_registry, ToolRegistry)\n", "\n", "sample_requirement = (PROJECT_ROOT / \"data\" / \"sample_requirement.txt\").read_text(encoding=\"utf-8\")\n", "audit_tool = tool_registry.get_tool(\"requirement_audit\")\n", "audit_result = json.loads(audit_tool.run({\"requirement_text\": sample_requirement}))\n", "\n", "print(audit_result[\"summary\"])\n", "print(\"澄清问题:\")\n", "for question in audit_result[\"clarifying_questions\"]:\n", " print(f\"- {question}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第3部分:智能体构建\n", "\n", "四个角色分别负责需求分析、方案设计、风险审查和报告整合。只有 `.env` 中三项 LLM 配置齐全时才连接模型服务。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "required_env = (\"LLM_MODEL_ID\", \"LLM_API_KEY\", \"LLM_BASE_URL\")\n", "api_key = os.getenv(\"LLM_API_KEY\", \"\").strip()\n", "has_llm_config = (\n", " all(os.getenv(name, \"\").strip() for name in required_env)\n", " and not api_key.casefold().startswith(\"your_\")\n", ")\n", "\n", "team = None\n", "workflow = None\n", "if has_llm_config:\n", " settings = LLMSettings.from_env()\n", " team = build_agent_team(settings, tool_registry)\n", " workflow = RequirementClarifierWorkflow(team, tool_registry)\n", " for role, agent in (\n", " (\"需求分析师\", team.analyst),\n", " (\"方案架构师\", team.architect),\n", " (\"风险审查员\", team.reviewer),\n", " (\"报告整合员\", team.synthesizer),\n", " ):\n", " print(f\"✅ {role}: {type(agent).__name__}\")\n", "else:\n", " print(\"ℹ️ 未检测到完整 LLM 配置:跳过在线智能体创建,继续离线演示。\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第4部分:功能演示" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 示例1:基础功能——无需 API 密钥的完整度检查\n", "print(\"=== 示例1:需求完整度初检 ===\")\n", "print(f\"覆盖率:{audit_result['coverage_percent']}%\")\n", "print(f\"已覆盖:{'、'.join(audit_result['covered_dimensions'])}\")\n", "print(f\"待补充:{'、'.join(audit_result['missing_dimensions'])}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 示例2:复杂场景——有密钥时运行四智能体,否则展示仓库示例\n", "print(\"=== 示例2:多智能体需求澄清 ===\")\n", "if workflow is not None:\n", " result = workflow.run(sample_requirement)\n", " report_path = workflow.save_report(\n", " result, PROJECT_ROOT / \"outputs\" / \"requirement_report.md\"\n", " )\n", " print(f\"✅ 在线报告已保存:{report_path}\")\n", " display(Markdown(result.report))\n", "else:\n", " example_report = (\n", " PROJECT_ROOT / \"outputs\" / \"requirement_report.md\"\n", " ).read_text(encoding=\"utf-8\")\n", " print(\"ℹ️ 当前展示仓库内置示例;填写 .env 后重新运行即可调用真实智能体。\")\n", " display(Markdown(example_report))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第5部分:性能评估" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iterations = 200\n", "started_at = time.perf_counter()\n", "for _ in range(iterations):\n", " audit_tool.run({\"requirement_text\": sample_requirement})\n", "elapsed_ms = (time.perf_counter() - started_at) * 1000\n", "\n", "quality_tool = tool_registry.get_tool(\"report_quality_check\")\n", "example_report = (PROJECT_ROOT / \"outputs\" / \"requirement_report.md\").read_text(encoding=\"utf-8\")\n", "quality_result = json.loads(quality_tool.run({\"report_text\": example_report}))\n", "\n", "print(f\"确定性初检:{iterations} 次共 {elapsed_ms:.2f} ms,平均 {elapsed_ms / iterations:.3f} ms/次\")\n", "print(f\"示例需求覆盖率:{audit_result['coverage_percent']}%\")\n", "print(f\"示例报告结构评分:{quality_result['score']}/100\")\n", "print(\"自动化测试命令:python -m pytest -q\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 第6部分:总结与展望\n", "\n", "### 项目总结\n", "\n", "#### 实现的功能\n", "- 使用四个 HelloAgents `SimpleAgent` 完成职责隔离的顺序协作。\n", "- 使用两个官方 `Tool` 完成需求前置检查和报告后置质检。\n", "- 提供 CLI、Notebook、示例输入、示例输出和离线自动化测试。\n", "\n", "#### 遇到的挑战\n", "- 模糊需求容易诱发隐含假设:通过角色提示词强制区分事实、建议和待确认项。\n", "- LLM 输出不稳定:通过固定报告标题和确定性结构质检提供护栏。\n", "- 普通测试不应依赖密钥:编排层允许注入离线替身,Notebook 也支持无密钥执行。\n", "\n", "#### 未来改进方向\n", "- 支持用户回答澄清问题后的增量迭代。\n", "- 增加 JSON Schema 输出和失败自动修复。\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.10.0" } }, "nbformat": 4, "nbformat_minor": 4 }