|
|
@@ -0,0 +1,254 @@
|
|
|
+{
|
|
|
+ "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
|
|
|
+}
|