|
|
@@ -0,0 +1,637 @@
|
|
|
+"""Code Plan Agent - 智能代码计划工具,具备Reflection反思功能"""
|
|
|
+
|
|
|
+import json
|
|
|
+from typing import Optional, List, Dict, Any, AsyncGenerator
|
|
|
+from datetime import datetime
|
|
|
+
|
|
|
+from hello_agents.core.agent import Agent
|
|
|
+from hello_agents.core.llm import HelloAgentsLLM
|
|
|
+from hello_agents.core.config import Config
|
|
|
+from hello_agents.core.message import Message
|
|
|
+from hello_agents.core.streaming import StreamEvent, StreamEventType
|
|
|
+from hello_agents.core.lifecycle import LifecycleHook
|
|
|
+from hello_agents.tools.registry import ToolRegistry
|
|
|
+
|
|
|
+
|
|
|
+class PlanMemory:
|
|
|
+ """
|
|
|
+ 计划记忆模块,用于存储代码计划的生成轨迹和反思记录
|
|
|
+ """
|
|
|
+ def __init__(self):
|
|
|
+ self.records: List[Dict[str, Any]] = []
|
|
|
+
|
|
|
+ def add_record(self, record_type: str, content: str, metadata: Optional[Dict] = None):
|
|
|
+ """向记忆中添加一条新记录"""
|
|
|
+ self.records.append({
|
|
|
+ "type": record_type,
|
|
|
+ "content": content,
|
|
|
+ "metadata": metadata or {},
|
|
|
+ "timestamp": datetime.now().isoformat()
|
|
|
+ })
|
|
|
+
|
|
|
+ def get_trajectory(self) -> str:
|
|
|
+ """将所有记忆记录格式化为一个连贯的字符串文本"""
|
|
|
+ trajectory = ""
|
|
|
+ for record in self.records:
|
|
|
+ if record['type'] == 'plan':
|
|
|
+ trajectory += f"--- 代码计划 ---\n{record['content']}\n\n"
|
|
|
+ elif record['type'] == 'reflection':
|
|
|
+ trajectory += f"--- 反思反馈 ---\n{record['content']}\n\n"
|
|
|
+ elif record['type'] == 'revision':
|
|
|
+ trajectory += f"--- 优化后计划 ---\n{record['content']}\n\n"
|
|
|
+ return trajectory.strip()
|
|
|
+
|
|
|
+ def get_last_plan(self) -> str:
|
|
|
+ """获取最近一次的代码计划"""
|
|
|
+ for record in reversed(self.records):
|
|
|
+ if record['type'] in ['plan', 'revision']:
|
|
|
+ return record['content']
|
|
|
+ return ""
|
|
|
+
|
|
|
+ def get_last_reflection(self) -> str:
|
|
|
+ """获取最近一次的反思反馈"""
|
|
|
+ for record in reversed(self.records):
|
|
|
+ if record['type'] == 'reflection':
|
|
|
+ return record['content']
|
|
|
+ return ""
|
|
|
+
|
|
|
+
|
|
|
+class CodePlanAgent(Agent):
|
|
|
+ """
|
|
|
+ Code Plan Agent - 智能代码计划工具,具备Reflection反思功能
|
|
|
+
|
|
|
+ 核心能力:
|
|
|
+ 1. 代码计划生成:根据需求描述生成结构化的代码实现计划
|
|
|
+ 2. 自我反思:对生成的代码计划进行质量评估和改进建议
|
|
|
+ 3. 迭代优化:根据反思结果优化代码计划
|
|
|
+ 4. 支持工具调用(可选)
|
|
|
+
|
|
|
+ 输出格式:
|
|
|
+ - 代码计划采用结构化格式,包含多个步骤
|
|
|
+ - 每个步骤包含:步骤编号、任务描述、实现要点、预期输出
|
|
|
+
|
|
|
+ 反思维度:
|
|
|
+ - 完整性:计划是否覆盖所有需求
|
|
|
+ - 可行性:技术方案是否可行
|
|
|
+ - 效率:是否存在性能优化空间
|
|
|
+ - 可维护性:代码结构是否清晰
|
|
|
+ - 安全性:是否存在安全风险
|
|
|
+ """
|
|
|
+
|
|
|
+ def __init__(
|
|
|
+ self,
|
|
|
+ name: str,
|
|
|
+ llm: HelloAgentsLLM,
|
|
|
+ system_prompt: Optional[str] = None,
|
|
|
+ config: Optional[Config] = None,
|
|
|
+ max_reflection_iterations: int = 2,
|
|
|
+ tool_registry: Optional['ToolRegistry'] = None,
|
|
|
+ enable_tool_calling: bool = True,
|
|
|
+ max_tool_iterations: int = 3
|
|
|
+ ):
|
|
|
+ """
|
|
|
+ 初始化CodePlanAgent
|
|
|
+
|
|
|
+ Args:
|
|
|
+ name: Agent名称
|
|
|
+ llm: LLM实例
|
|
|
+ system_prompt: 系统提示词(定义角色和行为)
|
|
|
+ config: 配置对象
|
|
|
+ max_reflection_iterations: 最大反思迭代次数
|
|
|
+ tool_registry: 工具注册表(可选)
|
|
|
+ enable_tool_calling: 是否启用工具调用
|
|
|
+ max_tool_iterations: 最大工具调用迭代次数
|
|
|
+ """
|
|
|
+ # 默认 system_prompt - 代码规划专家
|
|
|
+ default_system_prompt = """你是一位资深的软件架构师和代码规划专家。
|
|
|
+你擅长将业务需求转化为清晰、可行的代码实现计划。
|
|
|
+
|
|
|
+## 核心职责
|
|
|
+1. 分析需求并生成结构化的代码实现计划
|
|
|
+2. 确保计划覆盖所有核心功能和边界情况
|
|
|
+3. 设计合理的模块划分和接口定义
|
|
|
+4. 考虑代码的可维护性、扩展性和性能
|
|
|
+
|
|
|
+## 输出格式要求
|
|
|
+请按照以下结构化格式输出代码计划:
|
|
|
+
|
|
|
+```code_plan
|
|
|
+## 项目概述
|
|
|
+[简要描述项目目标和核心功能]
|
|
|
+
|
|
|
+## 技术栈
|
|
|
+- 语言:[编程语言]
|
|
|
+- 框架:[主要框架]
|
|
|
+- 数据库:[数据库类型]
|
|
|
+- 其他:[关键依赖]
|
|
|
+
|
|
|
+## 目录结构
|
|
|
+```
|
|
|
+[项目目录结构]
|
|
|
+```
|
|
|
+
|
|
|
+## 实现步骤
|
|
|
+1. [步骤1描述]
|
|
|
+ - 实现要点:[关键实现细节]
|
|
|
+ - 文件路径:[涉及文件]
|
|
|
+ - 预期输出:[预期结果]
|
|
|
+
|
|
|
+2. [步骤2描述]
|
|
|
+ - 实现要点:[关键实现细节]
|
|
|
+ - 文件路径:[涉及文件]
|
|
|
+ - 预期输出:[预期结果]
|
|
|
+
|
|
|
+...
|
|
|
+
|
|
|
+## 关键设计
|
|
|
+- [设计决策1]:[说明原因]
|
|
|
+- [设计决策2]:[说明原因]
|
|
|
+
|
|
|
+## 注意事项
|
|
|
+- [注意事项1]
|
|
|
+- [注意事项2]
|
|
|
+```
|
|
|
+
|
|
|
+请确保计划详细、清晰、可执行。"""
|
|
|
+
|
|
|
+ super().__init__(
|
|
|
+ name,
|
|
|
+ llm,
|
|
|
+ system_prompt or default_system_prompt,
|
|
|
+ config,
|
|
|
+ tool_registry=tool_registry
|
|
|
+ )
|
|
|
+
|
|
|
+ self.max_reflection_iterations = max_reflection_iterations
|
|
|
+ self.memory = PlanMemory()
|
|
|
+ self.enable_tool_calling = enable_tool_calling
|
|
|
+ self.max_tool_iterations = max_tool_iterations
|
|
|
+
|
|
|
+ def run(self, input_text: str, **kwargs) -> str:
|
|
|
+ """
|
|
|
+ 运行CodePlanAgent
|
|
|
+
|
|
|
+ Args:
|
|
|
+ input_text: 需求描述
|
|
|
+ **kwargs: 其他参数(temperature, max_tokens等)
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ 最终优化后的代码计划
|
|
|
+ """
|
|
|
+ print(f"\n🤖 {self.name} 开始处理代码规划任务: {input_text[:50]}...")
|
|
|
+
|
|
|
+ # 重置记忆
|
|
|
+ self.memory = PlanMemory()
|
|
|
+
|
|
|
+ # 1. 生成初始代码计划
|
|
|
+ print("\n--- 阶段1: 生成初始代码计划 ---")
|
|
|
+ initial_plan = self._generate_code_plan(input_text, **kwargs)
|
|
|
+ self.memory.add_record("plan", initial_plan, {"phase": "initial"})
|
|
|
+
|
|
|
+ print(f"\n✅ 初始计划已生成:\n{initial_plan}")
|
|
|
+
|
|
|
+ # 2. 迭代反思与优化
|
|
|
+ for i in range(self.max_reflection_iterations):
|
|
|
+ print(f"\n--- 阶段2: 第 {i+1}/{self.max_reflection_iterations} 轮反思优化 ---")
|
|
|
+
|
|
|
+ # a. 反思当前计划
|
|
|
+ print("\n-> 正在进行计划反思...")
|
|
|
+ last_plan = self.memory.get_last_plan()
|
|
|
+ reflection = self._reflect_on_plan(input_text, last_plan, **kwargs)
|
|
|
+ self.memory.add_record("reflection", reflection, {"iteration": i + 1})
|
|
|
+
|
|
|
+ print(f"\n💡 反思结果:\n{reflection}")
|
|
|
+
|
|
|
+ # b. 检查是否需要停止
|
|
|
+ if "无需改进" in reflection or "no need for improvement" in reflection.lower():
|
|
|
+ print("\n✅ 反思认为计划已无需改进,任务完成。")
|
|
|
+ break
|
|
|
+
|
|
|
+ # c. 优化计划
|
|
|
+ print("\n-> 正在优化代码计划...")
|
|
|
+ refined_plan = self._refine_plan(input_text, last_plan, reflection, **kwargs)
|
|
|
+ self.memory.add_record("revision", refined_plan, {"iteration": i + 1})
|
|
|
+
|
|
|
+ print(f"\n🔄 优化后的计划:\n{refined_plan}")
|
|
|
+
|
|
|
+ final_plan = self.memory.get_last_plan()
|
|
|
+ print(f"\n--- 🎉 任务完成 ---\n最终代码计划:\n{final_plan}")
|
|
|
+
|
|
|
+ # 保存到历史记录
|
|
|
+ self.add_message(Message(input_text, "user"))
|
|
|
+ self.add_message(Message(final_plan, "assistant"))
|
|
|
+
|
|
|
+ return final_plan
|
|
|
+
|
|
|
+ def _generate_code_plan(self, requirements: str, **kwargs) -> str:
|
|
|
+ """
|
|
|
+ 生成初始代码计划
|
|
|
+
|
|
|
+ Args:
|
|
|
+ requirements: 需求描述
|
|
|
+ **kwargs: LLM调用参数
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ 代码计划文本
|
|
|
+ """
|
|
|
+ messages = [
|
|
|
+ {"role": "system", "content": self.system_prompt},
|
|
|
+ {"role": "user", "content": f"""请根据以下需求描述,生成一份详细的代码实现计划:
|
|
|
+
|
|
|
+## 需求描述
|
|
|
+{requirements}
|
|
|
+
|
|
|
+请按照指定的格式输出代码计划。"""}
|
|
|
+ ]
|
|
|
+
|
|
|
+ return self._get_llm_response(messages, **kwargs)
|
|
|
+
|
|
|
+ def _reflect_on_plan(self, requirements: str, plan: str, **kwargs) -> str:
|
|
|
+ """
|
|
|
+ 对代码计划进行反思评估
|
|
|
+
|
|
|
+ Args:
|
|
|
+ requirements: 原始需求
|
|
|
+ plan: 当前代码计划
|
|
|
+ **kwargs: LLM调用参数
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ 反思反馈文本
|
|
|
+ """
|
|
|
+ reflection_prompt = f"""你是一位资深的技术评审专家。请对以下代码计划进行全面评估:
|
|
|
+
|
|
|
+## 原始需求
|
|
|
+{requirements}
|
|
|
+
|
|
|
+## 当前代码计划
|
|
|
+{plan}
|
|
|
+
|
|
|
+## 评审维度
|
|
|
+请从以下维度进行评估:
|
|
|
+
|
|
|
+1. **完整性**:计划是否覆盖了所有核心需求?是否有遗漏的功能?
|
|
|
+2. **可行性**:技术方案是否可行?是否存在技术风险?
|
|
|
+3. **架构合理性**:模块划分是否合理?接口设计是否清晰?
|
|
|
+4. **可维护性**:代码结构是否清晰?是否遵循最佳实践?
|
|
|
+5. **性能考虑**:是否考虑了性能优化?是否存在潜在的性能瓶颈?
|
|
|
+6. **安全性**:是否存在安全风险?是否需要添加安全措施?
|
|
|
+7. **测试覆盖**:是否考虑了测试策略?关键路径是否有测试覆盖?
|
|
|
+
|
|
|
+## 输出要求
|
|
|
+请给出具体的改进建议。如果计划已经很好,请回答"无需改进"。"""
|
|
|
+
|
|
|
+ messages = [
|
|
|
+ {"role": "system", "content": "你是一位严格的技术评审专家,擅长发现代码计划中的潜在问题并提出改进建议。"},
|
|
|
+ {"role": "user", "content": reflection_prompt}
|
|
|
+ ]
|
|
|
+
|
|
|
+ return self._get_llm_response(messages, **kwargs)
|
|
|
+
|
|
|
+ def _refine_plan(self, requirements: str, current_plan: str, feedback: str, **kwargs) -> str:
|
|
|
+ """
|
|
|
+ 根据反馈优化代码计划
|
|
|
+
|
|
|
+ Args:
|
|
|
+ requirements: 原始需求
|
|
|
+ current_plan: 当前代码计划
|
|
|
+ feedback: 反思反馈
|
|
|
+ **kwargs: LLM调用参数
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ 优化后的代码计划
|
|
|
+ """
|
|
|
+ refinement_prompt = f"""请根据评审反馈优化以下代码计划:
|
|
|
+
|
|
|
+## 原始需求
|
|
|
+{requirements}
|
|
|
+
|
|
|
+## 当前代码计划
|
|
|
+{current_plan}
|
|
|
+
|
|
|
+## 评审反馈
|
|
|
+{feedback}
|
|
|
+
|
|
|
+## 优化要求
|
|
|
+请根据反馈意见对代码计划进行修改和完善,确保:
|
|
|
+1. 解决反馈中指出的所有问题
|
|
|
+2. 保持计划的结构化格式
|
|
|
+3. 提供具体的改进方案
|
|
|
+
|
|
|
+请输出优化后的完整代码计划。"""
|
|
|
+
|
|
|
+ messages = [
|
|
|
+ {"role": "system", "content": self.system_prompt},
|
|
|
+ {"role": "user", "content": refinement_prompt}
|
|
|
+ ]
|
|
|
+
|
|
|
+ return self._get_llm_response(messages, **kwargs)
|
|
|
+
|
|
|
+ def _get_llm_response(self, messages: List[Dict[str, str]], **kwargs) -> str:
|
|
|
+ """
|
|
|
+ 调用LLM并获取完整响应(支持 Function Calling)
|
|
|
+
|
|
|
+ Args:
|
|
|
+ messages: 消息列表
|
|
|
+ **kwargs: 其他参数
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ LLM响应文本
|
|
|
+ """
|
|
|
+ # 如果没有启用工具调用,直接返回
|
|
|
+ if not self.enable_tool_calling or not self.tool_registry:
|
|
|
+ llm_response = self.llm.invoke(messages, **kwargs)
|
|
|
+ return llm_response.content if hasattr(llm_response, 'content') else str(llm_response)
|
|
|
+
|
|
|
+ # 启用工具调用模式
|
|
|
+ tool_schemas = self._build_tool_schemas()
|
|
|
+ current_iteration = 0
|
|
|
+
|
|
|
+ while current_iteration < self.max_tool_iterations:
|
|
|
+ current_iteration += 1
|
|
|
+
|
|
|
+ try:
|
|
|
+ response = self.llm.invoke_with_tools(
|
|
|
+ messages=messages,
|
|
|
+ tools=tool_schemas,
|
|
|
+ tool_choice="auto",
|
|
|
+ **kwargs
|
|
|
+ )
|
|
|
+ except Exception as e:
|
|
|
+ print(f"❌ LLM 调用失败: {e}")
|
|
|
+ break
|
|
|
+
|
|
|
+ response_message = response.choices[0].message
|
|
|
+
|
|
|
+ # 处理工具调用
|
|
|
+ tool_calls = response_message.tool_calls
|
|
|
+ if not tool_calls:
|
|
|
+ # 没有工具调用,返回文本响应
|
|
|
+ return response_message.content or ""
|
|
|
+
|
|
|
+ # 将助手消息添加到历史
|
|
|
+ messages.append({
|
|
|
+ "role": "assistant",
|
|
|
+ "content": response_message.content,
|
|
|
+ "tool_calls": [
|
|
|
+ {
|
|
|
+ "id": tc.id,
|
|
|
+ "type": "function",
|
|
|
+ "function": {
|
|
|
+ "name": tc.function.name,
|
|
|
+ "arguments": tc.function.arguments
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for tc in tool_calls
|
|
|
+ ]
|
|
|
+ })
|
|
|
+
|
|
|
+ # 执行所有工具调用
|
|
|
+ for tool_call in tool_calls:
|
|
|
+ tool_name = tool_call.function.name
|
|
|
+ tool_call_id = tool_call.id
|
|
|
+
|
|
|
+ try:
|
|
|
+ arguments = json.loads(tool_call.function.arguments)
|
|
|
+ except json.JSONDecodeError as e:
|
|
|
+ print(f"❌ 工具参数解析失败: {e}")
|
|
|
+ messages.append({
|
|
|
+ "role": "tool",
|
|
|
+ "tool_call_id": tool_call_id,
|
|
|
+ "content": f"错误:参数格式不正确 - {str(e)}"
|
|
|
+ })
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 执行工具(复用基类方法)
|
|
|
+ result = self._execute_tool_call(tool_name, arguments)
|
|
|
+
|
|
|
+ # 添加工具结果到消息
|
|
|
+ messages.append({
|
|
|
+ "role": "tool",
|
|
|
+ "tool_call_id": tool_call_id,
|
|
|
+ "content": result
|
|
|
+ })
|
|
|
+
|
|
|
+ # 如果超过最大迭代次数,获取最后一次回答
|
|
|
+ if current_iteration >= self.max_tool_iterations:
|
|
|
+ llm_response = self.llm.invoke(messages, **kwargs)
|
|
|
+ return llm_response.content if hasattr(llm_response, 'content') else str(llm_response)
|
|
|
+
|
|
|
+ return ""
|
|
|
+
|
|
|
+ async def arun_stream(
|
|
|
+ self,
|
|
|
+ input_text: str,
|
|
|
+ on_start: LifecycleHook = None,
|
|
|
+ on_finish: LifecycleHook = None,
|
|
|
+ on_error: LifecycleHook = None,
|
|
|
+ **kwargs
|
|
|
+ ) -> AsyncGenerator[StreamEvent, None]:
|
|
|
+ """
|
|
|
+ CodePlanAgent 流式执行
|
|
|
+
|
|
|
+ 实时返回:
|
|
|
+ - 计划生成阶段的输出
|
|
|
+ - 反思阶段的思考过程
|
|
|
+ - 优化阶段的输出
|
|
|
+
|
|
|
+ Args:
|
|
|
+ input_text: 用户输入
|
|
|
+ on_start: 开始钩子
|
|
|
+ on_finish: 完成钩子
|
|
|
+ on_error: 错误钩子
|
|
|
+ **kwargs: 其他参数
|
|
|
+
|
|
|
+ Yields:
|
|
|
+ StreamEvent: 流式事件
|
|
|
+ """
|
|
|
+ # 发送开始事件
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.AGENT_START,
|
|
|
+ self.name,
|
|
|
+ input_text=input_text
|
|
|
+ )
|
|
|
+
|
|
|
+ try:
|
|
|
+ # 阶段 1:生成代码计划
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_START,
|
|
|
+ self.name,
|
|
|
+ phase="plan_generation",
|
|
|
+ description="生成初始代码计划"
|
|
|
+ )
|
|
|
+
|
|
|
+ messages = []
|
|
|
+ if self.system_prompt:
|
|
|
+ messages.append({"role": "system", "content": self.system_prompt})
|
|
|
+
|
|
|
+ plan_prompt = f"""请根据以下需求描述,生成一份详细的代码实现计划:
|
|
|
+
|
|
|
+## 需求描述
|
|
|
+{input_text}
|
|
|
+
|
|
|
+请按照指定的格式输出代码计划。"""
|
|
|
+
|
|
|
+ messages.append({"role": "user", "content": plan_prompt})
|
|
|
+
|
|
|
+ initial_plan = ""
|
|
|
+ async for chunk in self.llm.astream_invoke(messages, **kwargs):
|
|
|
+ initial_plan += chunk
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.LLM_CHUNK,
|
|
|
+ self.name,
|
|
|
+ chunk=chunk,
|
|
|
+ phase="plan_generation"
|
|
|
+ )
|
|
|
+
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_FINISH,
|
|
|
+ self.name,
|
|
|
+ phase="plan_generation",
|
|
|
+ result=initial_plan
|
|
|
+ )
|
|
|
+
|
|
|
+ # 阶段 2:反思与优化循环
|
|
|
+ current_plan = initial_plan
|
|
|
+
|
|
|
+ for iteration in range(self.max_reflection_iterations):
|
|
|
+ # 反思阶段
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_START,
|
|
|
+ self.name,
|
|
|
+ phase="reflection",
|
|
|
+ iteration=iteration + 1,
|
|
|
+ description=f"第 {iteration + 1} 次反思"
|
|
|
+ )
|
|
|
+
|
|
|
+ reflection_prompt = f"""你是一位资深的技术评审专家。请对以下代码计划进行全面评估:
|
|
|
+
|
|
|
+## 原始需求
|
|
|
+{input_text}
|
|
|
+
|
|
|
+## 当前代码计划
|
|
|
+{current_plan}
|
|
|
+
|
|
|
+## 评审维度
|
|
|
+请从以下维度进行评估:
|
|
|
+1. 完整性:计划是否覆盖了所有核心需求?
|
|
|
+2. 可行性:技术方案是否可行?
|
|
|
+3. 架构合理性:模块划分是否合理?
|
|
|
+4. 可维护性:代码结构是否清晰?
|
|
|
+5. 性能考虑:是否考虑了性能优化?
|
|
|
+6. 安全性:是否存在安全风险?
|
|
|
+7. 测试覆盖:是否考虑了测试策略?
|
|
|
+
|
|
|
+请给出具体的改进建议。如果计划已经很好,请回答"无需改进"。"""
|
|
|
+
|
|
|
+ reflection_messages = [{"role": "user", "content": reflection_prompt}]
|
|
|
+
|
|
|
+ reflection = ""
|
|
|
+ async for chunk in self.llm.astream_invoke(reflection_messages, **kwargs):
|
|
|
+ reflection += chunk
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.THINKING,
|
|
|
+ self.name,
|
|
|
+ chunk=chunk,
|
|
|
+ phase="reflection",
|
|
|
+ iteration=iteration + 1
|
|
|
+ )
|
|
|
+
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_FINISH,
|
|
|
+ self.name,
|
|
|
+ phase="reflection",
|
|
|
+ iteration=iteration + 1,
|
|
|
+ reflection=reflection
|
|
|
+ )
|
|
|
+
|
|
|
+ # 检查是否需要停止
|
|
|
+ if "无需改进" in reflection or "no need for improvement" in reflection.lower():
|
|
|
+ break
|
|
|
+
|
|
|
+ # 优化阶段
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_START,
|
|
|
+ self.name,
|
|
|
+ phase="refinement",
|
|
|
+ iteration=iteration + 1,
|
|
|
+ description=f"第 {iteration + 1} 次优化"
|
|
|
+ )
|
|
|
+
|
|
|
+ refinement_prompt = f"""请根据评审反馈优化以下代码计划:
|
|
|
+
|
|
|
+## 原始需求
|
|
|
+{input_text}
|
|
|
+
|
|
|
+## 当前代码计划
|
|
|
+{current_plan}
|
|
|
+
|
|
|
+## 评审反馈
|
|
|
+{reflection}
|
|
|
+
|
|
|
+请输出优化后的完整代码计划。"""
|
|
|
+
|
|
|
+ refinement_messages = [{"role": "user", "content": refinement_prompt}]
|
|
|
+
|
|
|
+ refined_plan = ""
|
|
|
+ async for chunk in self.llm.astream_invoke(refinement_messages, **kwargs):
|
|
|
+ refined_plan += chunk
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.LLM_CHUNK,
|
|
|
+ self.name,
|
|
|
+ chunk=chunk,
|
|
|
+ phase="refinement",
|
|
|
+ iteration=iteration + 1
|
|
|
+ )
|
|
|
+
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.STEP_FINISH,
|
|
|
+ self.name,
|
|
|
+ phase="refinement",
|
|
|
+ iteration=iteration + 1,
|
|
|
+ result=refined_plan
|
|
|
+ )
|
|
|
+
|
|
|
+ current_plan = refined_plan
|
|
|
+
|
|
|
+ # 发送完成事件
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.AGENT_FINISH,
|
|
|
+ self.name,
|
|
|
+ result=current_plan,
|
|
|
+ total_iterations=self.max_reflection_iterations
|
|
|
+ )
|
|
|
+
|
|
|
+ # 保存到历史
|
|
|
+ self.add_message(Message(input_text, "user"))
|
|
|
+ self.add_message(Message(current_plan, "assistant"))
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ # 发送错误事件
|
|
|
+ yield StreamEvent.create(
|
|
|
+ StreamEventType.ERROR,
|
|
|
+ self.name,
|
|
|
+ error=str(e),
|
|
|
+ error_type=type(e).__name__
|
|
|
+ )
|
|
|
+ raise
|
|
|
+
|
|
|
+ def get_plan_trajectory(self) -> str:
|
|
|
+ """获取完整的计划生成轨迹"""
|
|
|
+ return self.memory.get_trajectory()
|
|
|
+
|
|
|
+
|
|
|
+def create_code_plan_agent(llm: HelloAgentsLLM) -> CodePlanAgent:
|
|
|
+ """
|
|
|
+ 创建CodePlanAgent实例的便捷工厂函数
|
|
|
+
|
|
|
+ Args:
|
|
|
+ llm: LLM实例
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ CodePlanAgent实例
|
|
|
+ """
|
|
|
+ return CodePlanAgent(
|
|
|
+ name="CodePlanAgent",
|
|
|
+ llm=llm,
|
|
|
+ max_reflection_iterations=2
|
|
|
+ )
|