1
0

plan_tool.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from __future__ import annotations
  2. from pathlib import Path
  3. from typing import Dict, Any, List, Optional
  4. from core.llm import HelloAgentsLLM
  5. from tools.base import Tool, ToolParameter
  6. class PlanTool(Tool):
  7. """规划工具(可选)
  8. 用于在用户强制要求或任务明显需要多步执行时生成计划。
  9. 建议在 ReAct 中按需调用:plan[{"goal":"..."}] 或 plan[目标文本]
  10. """
  11. def __init__(self, llm: HelloAgentsLLM, prompt_path: Optional[str] = None):
  12. super().__init__(name="plan", description="生成可执行计划(仅在需要时调用)")
  13. self.llm = llm
  14. self.prompt_path = Path(prompt_path).resolve() if prompt_path else None
  15. def get_parameters(self) -> List[ToolParameter]:
  16. return [
  17. ToolParameter(
  18. name="goal",
  19. type="string",
  20. description="计划目标(例如:分析项目结构并说明模块职责)",
  21. required=True,
  22. ),
  23. ToolParameter(
  24. name="constraints",
  25. type="string",
  26. description="额外约束(可选)",
  27. required=False,
  28. ),
  29. ToolParameter(
  30. name="output",
  31. type="string",
  32. description="输出格式:markdown|json(默认 markdown)",
  33. required=False,
  34. default="markdown",
  35. ),
  36. ]
  37. def run(self, parameters: Dict[str, Any]) -> str:
  38. if not self.validate_parameters(parameters):
  39. return "❌ 参数验证失败:缺少 goal"
  40. goal = str(parameters.get("goal", "")).strip()
  41. constraints = parameters.get("constraints")
  42. output = str(parameters.get("output", "markdown")).strip() or "markdown"
  43. if not goal:
  44. return "❌ goal 不能为空"
  45. prompt = ""
  46. if self.prompt_path and self.prompt_path.exists():
  47. prompt = self.prompt_path.read_text(encoding="utf-8")
  48. else:
  49. prompt = (
  50. "你是一个规划助手。请输出一个可执行计划(5~12步),并包含 Risks 与 Validation。"
  51. )
  52. user_msg = f"目标:{goal}\n期望输出:{output}"
  53. if constraints:
  54. user_msg += f"\n约束:{constraints}"
  55. resp = self.llm.invoke(
  56. [
  57. {"role": "system", "content": prompt},
  58. {"role": "user", "content": user_msg},
  59. ],
  60. max_tokens=800,
  61. )
  62. return resp or ""