Bladeren bron

feat: 真实实现模型工具

xyliu3 7 maanden geleden
bovenliggende
commit
da93eeb252

File diff suppressed because it is too large
+ 927 - 95
Co-creation-projects/melxy1997-ColumnWriter/agents.py


+ 0 - 752
Co-creation-projects/melxy1997-ColumnWriter/agents_advanced.py

@@ -1,752 +0,0 @@
-"""核心 Agent"""
-
-import json
-import os
-from typing import Dict, Any, Optional, List
-from hello_agents import (
-    HelloAgentsLLM,
-    ReActAgent,
-    ReflectionAgent,
-    PlanAndSolveAgent
-)
-from hello_agents.tools import MCPTool, ToolRegistry
-from models import ColumnPlan, ReviewResult, ContentNode, ContentLevel
-from prompts import get_structure_requirements, get_react_writer_prompt, get_reflection_writer_prompts, get_planner_prompts
-from config import get_settings, get_word_count
-import re # Added for JSON parsing
-
-settings = get_settings()
-
-class LLMService:
-    """LLM 服务单例"""
-    _instance: Optional[HelloAgentsLLM] = None
-    
-    @classmethod
-    def get_llm(cls) -> HelloAgentsLLM:
-        """获取 LLM 实例(单例模式)"""
-        if cls._instance is None:
-            cls._instance = HelloAgentsLLM()
-            print(f"✅ LLM服务初始化成功")
-            print(f"   提供商: {cls._instance.provider}")
-            print(f"   模型: {cls._instance.model}")
-        return cls._instance
-
-
-class AdvancedPlannerAgent:
-    """
-    使用 PlanAndSolveAgent 模式
-    
-    PlanAndSolveAgent 将任务分解为子任务并逐步执行,非常适合专栏规划场景:
-    1. 分析主题(理解用户需求)
-    2. 规划子话题(分解任务)
-    3. 组织结构(逐步执行)
-    """
-    
-    def __init__(self):
-        self.llm = LLMService.get_llm()
-        
-        # 自定义 PlanAndSolve 提示词
-        planner_prompts = {
-            "planner": """
-你是一位经验丰富的专栏策划专家。请将以下专栏主题分解为清晰的子话题规划步骤。
-
-主题: {question}
-
-请按以下格式输出规划步骤:
-```python
-[
-    "步骤1: 分析主题的核心概念和目标读者",
-    "步骤2: 确定知识体系的整体框架",
-    "步骤3: 规划2-4个子话题,确保逻辑递进",
-    "步骤4: 为每个子话题设定学习目标和要点",
-    "步骤5: 组装完整的专栏大纲"
-]
-```
-""",
-            "executor": """
-你是专栏规划执行专家。请按照规划步骤执行专栏大纲的生成。
-
-# 原始主题: {question}
-# 规划步骤: {plan}
-# 已完成步骤: {history}
-# 当前步骤: {current_step}
-
-请执行当前步骤。如果这是最后一步,请输出完整的 JSON 格式专栏大纲:
-
-```json
-{{
-  "column_title": "专栏总标题",
-  "column_description": "专栏简介(100-200字)",
-  "target_audience": "目标读者群体",
-  "topics": [
-    {{
-      "id": "topic_001",
-      "title": "子话题标题",
-      "description": "子话题简介(50-100字)",
-      "estimated_words": 2500,
-      "key_points": ["要点1", "要点2", "要点3"],
-      "prerequisites": ["前置知识1", "前置知识2"]
-    }}
-  ]
-}}
-```
-
-如果不是最后一步,请输出当前步骤的分析结果。
-"""
-        }
-        
-        self.agent = PlanAndSolveAgent(
-            name="专栏规划专家",
-            llm=self.llm,
-            custom_prompts=planner_prompts
-        )
-    
-    def plan_column(self, main_topic: str) -> ColumnPlan:
-        """
-        规划专栏大纲
-        
-        Args:
-            main_topic: 专栏主题
-            
-        Returns:
-            ColumnPlan 实例
-        """
-        print(f"\n📋 PlanAndSolve Agent 开始规划专栏...")
-        print(f"   使用模式: 任务分解 → 逐步执行")
-        print(f"   主题: {main_topic}")
-        
-        response = self.agent.run(main_topic)
-        
-        # 解析 JSON 响应
-        plan_data = self._extract_json(response)
-        plan = ColumnPlan.from_dict(plan_data)
-        
-        print(f"✅ 规划完成")
-        print(f"   专栏标题: {plan.column_title}")
-        print(f"   话题数量: {plan.get_topic_count()}")
-        
-        return plan
-    
-    def _extract_json(self, response: str) -> Dict[str, Any]:
-        """从响应中提取 JSON"""
-        try:
-            if response.strip().startswith('{'):
-                return json.loads(response)
-            
-            if "```json" in response:
-                json_start = response.find("```json") + 7
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-            elif "```" in response:
-                json_start = response.find("```") + 3
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-            elif "{" in response and "}" in response:
-                json_start = response.find("{")
-                json_end = response.rfind("}") + 1
-                json_str = response[json_start:json_end]
-            else:
-                raise ValueError("响应中未找到 JSON 数据")
-            
-            return json.loads(json_str)
-        except Exception as e:
-            print(f"⚠️  JSON 解析失败: {e}")
-            print(f"   响应内容: {response[:500]}...")
-            raise
-
-
-class ReActAgentWrapper:
-    """
-    ReActAgent 包装器,用于捕获历史信息和处理错误
-    """
-    def __init__(self, agent: ReActAgent):
-        self.agent = agent
-        self.last_history = []  # 保存最后一次运行的历史
-        self.last_response = None
-    
-    def run(self, question: str):
-        """运行 Agent 并捕获历史信息"""
-        try:
-            # 尝试访问 agent 的 history 属性(如果存在)
-            if hasattr(self.agent, 'history'):
-                original_history = self.agent.history.copy() if self.agent.history else []
-            else:
-                original_history = []
-            
-            response = self.agent.run(question)
-            self.last_response = response
-            
-            # 尝试获取最终的历史信息
-            if hasattr(self.agent, 'history'):
-                self.last_history = self.agent.history.copy() if self.agent.history else []
-            else:
-                self.last_history = original_history
-            
-            return response
-        except Exception as e:
-            # 即使出错也尝试保存历史
-            if hasattr(self.agent, 'history'):
-                self.last_history = self.agent.history.copy() if self.agent.history else []
-            raise
-
-
-class AdvancedWriterAgent:
-    """
-    写作 Agent - 使用 ReActAgent 模式
-    
-    ReActAgent 结合推理(Reasoning)和行动(Acting),非常适合需要工具调用的写作场景:
-    1. 分析写作需求(推理)
-    2. 决定是否需要搜索(推理)
-    3. 调用搜索工具(行动)
-    4. 整合信息写作(行动)
-    """
-    
-    def __init__(self, enable_search: bool = True):
-        """
-        初始化写作 Agent
-        
-        Args:
-            enable_search: 是否启用搜索功能
-        """
-        self.llm = LLMService.get_llm()
-        self.enable_search = enable_search
-        
-        # 创建工具注册表
-        self.tool_registry = ToolRegistry()
-        
-        # 添加搜索工具(如果启用)
-        if enable_search:
-            self._setup_search_tool()
-        
-        # 自定义 ReAct 提示词(参考示例代码的简洁格式)
-        react_prompt = get_react_writer_prompt() # 从 prompts.py 获取
-
-        # 创建 ReActAgent 并用包装器包装
-        react_agent = ReActAgent(
-            name="内容创作专家",
-            llm=self.llm,
-            tool_registry=self.tool_registry,
-            custom_prompt=react_prompt,
-            max_steps=10  # 增加到 10 步,给 Agent 更多机会完成任务
-        )
-        
-        self.agent = ReActAgentWrapper(react_agent)
-    
-    def _setup_search_tool(self):
-        """设置搜索工具(使用 MCPTool)"""
-        settings = get_settings()
-        
-        # 检查是否配置了搜索 API
-        has_search_api = bool(settings.tavily_api_key or settings.serpapi_api_key)
-        
-        if not has_search_api:
-            print("⚠️  未配置搜索 API Key,WriterAgent 将使用 ReAct 模式但无搜索能力")
-            return
-        
-        try:
-            # 准备环境变量
-            env = {}
-            if settings.tavily_api_key:
-                env["TAVILY_API_KEY"] = settings.tavily_api_key
-            if settings.serpapi_api_key:
-                env["SERPAPI_API_KEY"] = settings.serpapi_api_key
-            
-            # 创建搜索 MCP 工具
-            search_tool = MCPTool(
-                name="search",
-                description="联网搜索工具,提供 web_search, search_recent_info, search_code_examples, verify_facts 等功能",
-                server_command=["python", "search_mcp_server.py"],
-                env=env,
-                auto_expand=True
-            )
-            
-            # 将 MCP 工具的所有子工具注册到 ToolRegistry
-            # 注意:这里我们需要手动注册,因为 ReActAgent 使用 ToolRegistry
-            self._register_search_functions()
-            
-            print("✅ 搜索工具已添加到 ReActAgent")
-            
-        except Exception as e:
-            print(f"⚠️  添加搜索工具失败: {e}")
-    
-    def _register_search_functions(self):
-        """注册搜索函数到 ToolRegistry"""
-        # 这里注册模拟的搜索函数(实际项目中应该调用 MCP 服务器)
-        def web_search(query: str) -> str:
-            """网页搜索"""
-            return f"[模拟搜索结果] 关于 '{query}' 的搜索结果..."
-        
-        def search_recent_info(topic: str) -> str:
-            """搜索最新信息"""
-            return f"[模拟最新信息] 关于 '{topic}' 的最新动态..."
-        
-        def search_code_examples(technology: str, task: str) -> str:
-            """搜索代码示例"""
-            return f"[模拟代码示例] {technology} 实现 {task} 的示例代码..."
-        
-        def verify_facts(statement: str) -> str:
-            """验证事实"""
-            return f"[模拟验证结果] 关于 '{statement}' 的验证信息..."
-        
-        self.tool_registry.register_function(
-            "web_search",
-            "通用网页搜索,获取最新资讯和资料",
-            web_search
-        )
-        self.tool_registry.register_function(
-            "search_recent_info",
-            "搜索最新信息和动态",
-            search_recent_info
-        )
-        self.tool_registry.register_function(
-            "search_code_examples",
-            "搜索代码示例和教程",
-            search_code_examples
-        )
-        self.tool_registry.register_function(
-            "verify_facts",
-            "验证事实准确性",
-            verify_facts
-        )
-    
-    def generate_content(
-        self,
-        node: ContentNode,
-        context: Dict[str, Any],
-        level: int,
-        additional_requirements: str = ""
-    ) -> Dict[str, Any]:
-        """
-        生成内容(使用 ReAct 模式)
-        
-        Args:
-            node: 当前节点
-            context: 写作上下文
-            level: 当前层级
-            additional_requirements: 额外要求
-            
-        Returns:
-            生成的内容数据
-        """
-        structure_requirements = get_structure_requirements(level)
-        word_count = get_word_count(level)
-        
-        # 构建写作任务描述(简化格式,参考示例代码)
-        task_description = f"""
-请撰写一篇技术专栏文章。
-
-层级: Level {level}/3
-话题: {node.title}
-描述: {node.description}
-要求字数: {word_count} 字(允许误差±10%)
-
-上下文信息:
-{json.dumps(context, ensure_ascii=False, indent=2)}
-
-结构要求:
-{structure_requirements}
-
-额外要求:
-{additional_requirements if additional_requirements else "无"}
-
-重要提示:
-- 完成写作后,必须使用 `Finish[JSON内容]` 格式输出结果
-- JSON 中的 `level` 字段必须是 {level}
-- `content` 字段必须包含完整的文章正文(Markdown格式)
-- 文章必须包含:引言、主体内容(3-5个小节)、实践案例、总结
-"""
-        
-        try:
-            response = self.agent.run(task_description)
-            
-            # 调试:打印原始响应
-            print(f"\n{'='*70}")
-            print("📋 ReActAgent 原始响应:")
-            print(f"{'='*70}")
-            print(response[:1000] if len(response) > 1000 else response)
-            print(f"{'='*70}\n")
-            
-            # 检查是否是错误消息
-            if response and ("无法在限定步数内完成" in response or "抱歉" in response):
-                print("⚠️  ReActAgent 达到最大步数限制或无法完成任务")
-                print(f"   已收集的历史信息: {len(self.agent.last_history)} 条")
-                # 如果达到步数限制,基于历史信息生成内容
-                return self._generate_content_with_history(
-                    node, context, level, structure_requirements, word_count,
-                    self.agent.last_history, task_description
-                )
-            
-            content_data = self._extract_json(response)
-            
-            return content_data
-        except Exception as e:
-            print(f"⚠️  ReActAgent 执行失败: {e}")
-            print(f"   已收集的历史信息: {len(self.agent.last_history)} 条")
-            print("   尝试基于历史信息生成内容...")
-            return self._generate_content_with_history(
-                node, context, level, structure_requirements, word_count,
-                self.agent.last_history, task_description
-            )
-    
-    def _generate_content_with_history(
-        self,
-        node: ContentNode,
-        context: Dict[str, Any],
-        level: int,
-        structure_requirements: str,
-        word_count: int,
-        history: List[str],
-        original_task: str
-    ) -> Dict[str, Any]:
-        """
-        当 ReActAgent 失败时,基于历史信息使用 SimpleAgent 生成内容
-        
-        Args:
-            history: ReActAgent 收集的历史信息(Thought、Action、Observation)
-        """
-        from hello_agents import SimpleAgent
-        
-        fallback_agent = SimpleAgent(
-            name="内容创作专家(备用)",
-            llm=self.llm,
-            system_prompt="你是一位专业的内容创作者,擅长撰写技术专栏文章。"
-        )
-        
-        # 构建包含历史信息的任务描述
-        history_summary = ""
-        if history:
-            history_summary = "\n\n## 已撰写的部分历史:\n"
-            for i, item in enumerate(history[-10:], 1):  # 只取最后10条历史
-                history_summary += f"{i}. {item}\n"
-            history_summary += "\n请基于以上信息继续完成写作任务。\n"
-        
-        task = f"""
-请撰写一篇技术专栏文章。
-
-话题: {node.title}
-描述: {node.description}
-要求字数: {word_count} 字
-
-结构要求:
-{structure_requirements}
-{history_summary}
-
-请直接输出 JSON 格式的内容:
-{{
-  "title": "{node.title}",
-  "level": {level},
-  "content": "完整的文章正文(markdown格式,包含引言、主体、案例、总结)",
-  "word_count": 实际字数,
-  "needs_expansion": false,
-  "subsections": [],
-  "metadata": {{}}
-}}
-"""
-        
-        print(f"📝 使用 SimpleAgent 基于历史信息生成内容...")
-        response = fallback_agent.run(task)
-        return self._extract_json(response)
-    
-    def revise_content(
-        self,
-        original_content: str,
-        review_result: ReviewResult,
-        level: int
-    ) -> Dict[str, Any]:
-        """
-        根据评审意见修改内容
-        
-        Args:
-            original_content: 原始内容
-            review_result: 评审结果
-            level: 层级
-            
-        Returns:
-            修改后的内容数据
-        """
-        # 构建修改任务
-        task_description = f"""
-## 修改任务
-
-**原始内容**:
-{original_content[:500]}...
-
-**评审分数**: {review_result.score}/100
-**评审等级**: {review_result.grade}
-
-**主要问题**:
-{json.dumps(review_result.detailed_feedback.get('issues', [])[:3], ensure_ascii=False, indent=2)}
-
-**修改建议**:
-{json.dumps(review_result.revision_plan.get('priority_changes', []), ensure_ascii=False, indent=2)}
-
-请使用 ReAct 模式完成修改:
-1. 思考评审意见的核心要求
-2. 决定是否需要搜索新信息
-3. 修改内容
-4. 使用 Finish[修改后的JSON内容] 输出结果
-"""
-        
-        response = self.agent.run(task_description)
-        revised_data = self._extract_json(response)
-        
-        return revised_data
-    
-    def _extract_json(self, response: str) -> Dict[str, Any]:
-        """
-        从响应中提取 JSON(支持多种格式,包括 Finish[...] 格式)
-        增强的 JSON 解析,能够处理包含复杂字符串的 JSON
-        """
-        import re
-        import json.encoder
-        
-        def extract_json_with_retry(json_str: str) -> Dict[str, Any]:
-            """尝试多种方式解析 JSON"""
-            # 方法1: 直接解析
-            try:
-                return json.loads(json_str)
-            except json.JSONDecodeError:
-                pass
-            
-            # 方法2: 尝试修复常见的 JSON 问题
-            # 修复未转义的换行符
-            fixed = json_str.replace('\n', '\\n').replace('\r', '\\r').replace('\t', '\\t')
-            try:
-                return json.loads(fixed)
-            except json.JSONDecodeError:
-                pass
-            
-            # 方法3: 尝试提取并重新构建 JSON
-            # 提取各个字段
-            title_match = re.search(r'"title"\s*:\s*"([^"]*)"', json_str)
-            level_match = re.search(r'"level"\s*:\s*(\d+)', json_str)
-            word_count_match = re.search(r'"word_count"\s*:\s*(\d+)', json_str)
-            needs_expansion_match = re.search(r'"needs_expansion"\s*:\s*(true|false)', json_str)
-            
-            # 提取 content(可能跨多行)
-            content_match = re.search(r'"content"\s*:\s*"(.*?)"(?=\s*[,}])', json_str, re.DOTALL)
-            if not content_match:
-                # 尝试另一种格式
-                content_match = re.search(r'"content"\s*:\s*"([^"]*(?:\\.[^"]*)*)"', json_str, re.DOTALL)
-            
-            result = {}
-            if title_match:
-                result['title'] = title_match.group(1)
-            if level_match:
-                result['level'] = int(level_match.group(1))
-            if content_match:
-                # 处理转义字符
-                content = content_match.group(1)
-                content = content.replace('\\n', '\n').replace('\\r', '\r').replace('\\t', '\t')
-                result['content'] = content
-            if word_count_match:
-                result['word_count'] = int(word_count_match.group(1))
-            else:
-                result['word_count'] = len(result.get('content', ''))
-            if needs_expansion_match:
-                result['needs_expansion'] = needs_expansion_match.group(1) == 'true'
-            else:
-                result['needs_expansion'] = False
-            result['subsections'] = []
-            result['metadata'] = {}
-            
-            return result
-        
-        try:
-            # 方法1: 尝试从 Finish[...] 格式中提取(ReAct 标准格式)
-            finish_match = re.search(r"Finish\[(.*?)\]", response, re.DOTALL)
-            if finish_match:
-                finish_content = finish_match.group(1).strip()
-                print(f"🔍 找到 Finish 格式,内容长度: {len(finish_content)}")
-                return extract_json_with_retry(finish_content)
-            
-            # 方法2: 直接是 JSON 对象
-            if response.strip().startswith('{'):
-                return extract_json_with_retry(response.strip())
-            
-            # 方法3: Markdown 代码块中的 JSON
-            if "```json" in response:
-                json_start = response.find("```json") + 7
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-                return extract_json_with_retry(json_str)
-            
-            # 方法4: 普通代码块中的 JSON
-            if "```" in response:
-                json_start = response.find("```") + 3
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-                if json_str.startswith("json"):
-                    json_str = json_str[4:].strip()
-                return extract_json_with_retry(json_str)
-            
-            # 方法5: 尝试提取第一个完整的 JSON 对象(使用更宽松的正则)
-            # 匹配从第一个 { 到最后一个 } 之间的内容
-            brace_start = response.find('{')
-            if brace_start != -1:
-                brace_count = 0
-                brace_end = brace_start
-                for i in range(brace_start, len(response)):
-                    if response[i] == '{':
-                        brace_count += 1
-                    elif response[i] == '}':
-                        brace_count -= 1
-                        if brace_count == 0:
-                            brace_end = i + 1
-                            break
-                
-                if brace_end > brace_start:
-                    json_str = response[brace_start:brace_end]
-                    return extract_json_with_retry(json_str)
-            
-            # 如果都失败了,抛出错误并显示响应内容
-            print(f"⚠️  无法从响应中提取 JSON")
-            print(f"   响应完整内容(前2000字符):\n{response[:2000]}")
-            raise ValueError("响应中未找到有效的 JSON 数据")
-            
-        except Exception as e:
-            print(f"⚠️  提取 JSON 时发生错误: {e}")
-            print(f"   响应内容(前1000字符): {response[:1000]}")
-            raise
-
-
-class AdvancedReflectionWriterAgent:
-    """
-    反思写作 Agent - 使用 ReflectionAgent 模式
-    
-    ReflectionAgent 通过自我反思和迭代优化来改进输出,将评审和修改整合为一个 Agent:
-    1. 生成初稿
-    2. 自我评审(反思)
-    3. 根据反思修改(优化)
-    4. 达到质量标准
-    """
-    
-    def __init__(self):
-        self.llm = LLMService.get_llm()
-        
-        # 自定义 Reflection 提示词
-        reflection_prompts = {
-            "initial": """
-你是一位专业的内容创作者。请撰写以下内容的初稿:
-
-{task}
-
-请输出完整的 JSON 格式内容。
-""",
-            "reflect": """
-你是一位严格的内容评审专家。请评审以下内容:
-
-# 写作任务: {task}
-# 内容初稿: {content}
-
-请从以下维度评审:
-1. **内容质量** (40分): 准确性、完整性、深度、原创性
-2. **结构逻辑** (30分): 层次清晰、逻辑连贯、过渡自然
-3. **语言表达** (20分): 易读性、专业性、准确性
-4. **格式规范** (10分): 字数达标、格式正确、排版美观
-
-如果内容质量很好(85分以上),请回答"无需改进"。
-否则,请详细指出问题并提供具体的修改建议。
-""",
-            "refine": """
-请根据评审意见优化你的内容:
-
-# 原始任务: {task}
-# 当前内容: {last_attempt}
-# 评审意见: {feedback}
-
-请输出优化后的完整 JSON 格式内容。
-"""
-        }
-        
-        self.agent = ReflectionAgent(
-            name="反思写作专家",
-            llm=self.llm,
-            custom_prompts=reflection_prompts,
-            max_iterations=2  # 最多反思 2 次
-        )
-    
-    def generate_and_refine_content(
-        self,
-        node: ContentNode,
-        context: Dict[str, Any],
-        level: int
-    ) -> Dict[str, Any]:
-        """
-        生成并反思优化内容
-        
-        Args:
-            node: 当前节点
-            context: 写作上下文
-            level: 当前层级
-            
-        Returns:
-            优化后的内容数据
-        """
-        print(f"\n🔄 ReflectionAgent 开始写作并自我反思...")
-        print(f"   使用模式: 初稿 → 自我评审 → 优化")
-        
-        structure_requirements = get_structure_requirements(level)
-        word_count = get_word_count(level)
-        
-        task_description = f"""
-## 写作任务
-
-**层级**: Level {level}/3
-**话题**: {node.title}
-**描述**: {node.description}
-**要求字数**: {word_count} 字(允许误差±10%)
-
-**结构要求**:
-{structure_requirements}
-
-**上下文**:
-{json.dumps(context, ensure_ascii=False, indent=2)}
-
-请输出完整的 JSON 格式内容:
-```json
-{{
-  "title": "章节标题",
-  "level": {level},
-  "content": "正文内容(markdown格式)",
-  "word_count": 实际字数,
-  "needs_expansion": true/false,
-  "subsections": [...],
-  "metadata": {{...}}
-}}
-```
-"""
-        
-        response = self.agent.run(task_description)
-        content_data = self._extract_json(response)
-        
-        print(f"✅ ReflectionAgent 完成反思优化")
-        
-        return content_data
-    
-    def _extract_json(self, response: str) -> Dict[str, Any]:
-        """从响应中提取 JSON"""
-        try:
-            if response.strip().startswith('{'):
-                return json.loads(response)
-            
-            if "```json" in response:
-                json_start = response.find("```json") + 7
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-            elif "```" in response:
-                json_start = response.find("```") + 3
-                json_end = response.find("```", json_start)
-                json_str = response[json_start:json_end].strip()
-            elif "{" in response and "}" in response:
-                json_start = response.find("{")
-                json_end = response.rfind("}") + 1
-                json_str = response[json_start:json_end]
-            else:
-                raise ValueError("响应中未找到 JSON 数据")
-            
-            return json.loads(json_str)
-        except Exception as e:
-            print(f"⚠️  JSON 解析失败: {e}")
-            raise
-

+ 3 - 3
Co-creation-projects/melxy1997-ColumnWriter/config.py

@@ -48,9 +48,9 @@ class Settings(BaseSettings):
     vite_amap_web_key: str = ""
     
     # 字数配置
-    word_count_level_1: int = 2500
-    word_count_level_2: int = 600
-    word_count_level_3: int = 400
+    word_count_level_1: int = 600
+    word_count_level_2: int = 400
+    word_count_level_3: int = 200
     word_count_tolerance: float = 0.1
     
     class Config:

+ 0 - 989
Co-creation-projects/melxy1997-ColumnWriter/lib_tutorial.md

@@ -1,989 +0,0 @@
-# HelloAgents 库使用教程
-
-本文档基于 `helloagents-examples` 官方案例集和 `helloagents-trip-planner` 真实项目,总结使用 `hello_agents` 库构建智能体系统的编码方式和最佳实践。
-
-## 目录
-
-1. [基础概念](#基础概念)
-2. [核心组件](#核心组件)
-3. [Agent 类型详解](#agent-类型详解)
-4. [工具系统](#工具系统)
-5. [多智能体系统](#多智能体系统)
-6. [项目架构模式](#项目架构模式)
-7. [最佳实践](#最佳实践)
-
----
-
-## 基础概念
-
-### HelloAgents 设计理念
-
-- **默认优秀**:开箱即用的高质量 Agent
-- **完全可定制**:用户可以完全替换提示词模板
-- **简洁 API**:最少的参数,最大的灵活性
-- **渐进式**:从简单到复杂的学习路径
-
-### 核心导入
-
-```python
-from hello_agents import (
-    HelloAgentsLLM,
-    SimpleAgent, 
-    ReActAgent, 
-    ReflectionAgent, 
-    PlanAndSolveAgent,
-    FunctionCallAgent,
-    ToolRegistry,
-    MCPTool
-)
-```
-
----
-
-## 核心组件
-
-### 1. HelloAgentsLLM - LLM 统一接口
-
-`HelloAgentsLLM` 是统一的 LLM 接口,自动从环境变量读取配置。
-
-#### 基本使用
-
-```python
-from hello_agents import HelloAgentsLLM
-
-# 方式1: 使用默认配置(从环境变量读取)
-llm = HelloAgentsLLM()
-
-# 方式2: 指定模型
-llm = HelloAgentsLLM(model="gpt-4o-mini")
-
-# 方式3: 自定义配置
-llm = HelloAgentsLLM(
-    api_key="your-api-key",
-    base_url="https://api.openai.com/v1",
-    model="gpt-4"
-)
-```
-
-#### 环境变量配置
-
-```bash
-# .env 文件
-OPENAI_API_KEY=your-api-key
-OPENAI_BASE_URL=https://api.openai.com/v1
-OPENAI_MODEL=gpt-4
-
-# 或者使用 HelloAgents 的命名
-LLM_API_KEY=your-api-key
-LLM_BASE_URL=https://api.openai.com/v1
-LLM_MODEL_ID=gpt-4
-```
-
-#### 单例模式(推荐)
-
-在实际项目中,建议使用单例模式管理 LLM 实例:
-
-```python
-# services/llm_service.py
-from hello_agents import HelloAgentsLLM
-
-_llm_instance = None
-
-def get_llm() -> HelloAgentsLLM:
-    """获取LLM实例(单例模式)"""
-    global _llm_instance
-    
-    if _llm_instance is None:
-        _llm_instance = HelloAgentsLLM()
-        print(f"✅ LLM服务初始化成功")
-        print(f"   提供商: {_llm_instance.provider}")
-        print(f"   模型: {_llm_instance.model}")
-    
-    return _llm_instance
-```
-
----
-
-## Agent 类型详解
-
-### 1. SimpleAgent - 基础对话 Agent
-
-最简单的 Agent 类型,适用于基础对话场景。
-
-#### 基本使用
-
-```python
-from hello_agents import SimpleAgent, HelloAgentsLLM
-
-llm = HelloAgentsLLM()
-
-# 创建简单 Agent
-agent = SimpleAgent(
-    name="助手",
-    llm=llm,
-    system_prompt="你是一个有用的AI助手,请用中文回答问题。"
-)
-
-# 运行对话
-response = agent.run("你好,请介绍一下自己")
-print(response)
-```
-
-#### 特点
-
-- ✅ 最简单易用
-- ✅ 适合基础对话
-- ✅ 不支持工具调用
-- ✅ 可自定义系统提示词
-
----
-
-### 2. ReActAgent - 推理与行动结合
-
-结合推理(Reasoning)和行动(Acting)的 Agent,支持工具调用。
-
-#### 基本使用
-
-```python
-from hello_agents import ReActAgent, HelloAgentsLLM, ToolRegistry, search, calculate
-
-llm = HelloAgentsLLM()
-
-# 创建工具注册表
-tool_registry = ToolRegistry()
-
-# 注册工具
-tool_registry.register_function(
-    name="search",
-    description="一个网页搜索引擎。当你需要回答关于时事、事实以及在你的知识库中找不到的信息时,应使用此工具。",
-    func=search
-)
-
-tool_registry.register_function(
-    name="calculate",
-    description="执行数学计算。支持基本运算、数学函数等。例如:2+3*4, sqrt(16), sin(pi/2)等。",
-    func=calculate
-)
-
-# 创建 ReAct Agent
-agent = ReActAgent(
-    name="通用助手",
-    llm=llm,
-    tool_registry=tool_registry,
-    max_steps=3  # 最大推理步骤
-)
-
-# 运行任务
-response = agent.run("计算 15 * 23 + 45 的结果")
-print(response)
-```
-
-#### 自定义提示词
-
-```python
-custom_prompt = """
-你是一个专业的研究助手,擅长信息收集和分析。
-
-可用工具如下:
-{tools}
-
-请按照以下格式进行研究:
-
-Thought: 分析问题,确定需要什么信息,制定研究策略。
-Action: 选择合适的工具获取信息,格式为:
-- `{tool_name}[{tool_input}]`:调用工具获取信息。
-- `Finish[研究结论]`:当你有足够信息得出结论时。
-
-研究问题:{question}
-已完成的研究:{history}
-"""
-
-research_agent = ReActAgent(
-    name="研究助手",
-    llm=llm,
-    tool_registry=tool_registry,
-    custom_prompt=custom_prompt,
-    max_steps=3
-)
-```
-
-#### 特点
-
-- ✅ 支持工具调用
-- ✅ 推理-行动循环
-- ✅ 可自定义提示词模板
-- ✅ 适合需要外部工具的场景
-
----
-
-### 3. ReflectionAgent - 自我反思与迭代优化
-
-通过自我反思和迭代优化来改进输出的 Agent。
-
-#### 基本使用
-
-```python
-from hello_agents import ReflectionAgent, HelloAgentsLLM
-
-llm = HelloAgentsLLM()
-
-# 默认配置
-agent = ReflectionAgent(
-    name="通用助手",
-    llm=llm,
-    max_iterations=2  # 最大迭代次数
-)
-
-response = agent.run("解释什么是递归算法,并给出一个简单的例子")
-print(response)
-```
-
-#### 自定义提示词
-
-```python
-code_prompts = {
-    "initial": """
-你是一位资深的程序员。请根据以下要求编写代码:
-
-要求: {task}
-
-请提供完整的代码实现,包含必要的注释和文档。
-""",
-    "reflect": """
-你是一位严格的代码评审专家。请审查以下代码:
-
-# 原始任务: {task}
-# 待审查的代码: {content}
-
-请分析代码的质量,包括算法效率、可读性、错误处理等。
-如果代码质量良好,请回答"无需改进"。否则请提出具体的改进建议。
-""",
-    "refine": """
-请根据代码评审意见优化你的代码:
-
-# 原始任务: {task}
-# 上一轮代码: {last_attempt}
-# 评审意见: {feedback}
-
-请提供优化后的代码。
-"""
-}
-
-code_agent = ReflectionAgent(
-    name="代码专家",
-    llm=llm,
-    custom_prompts=code_prompts,
-    max_iterations=2
-)
-```
-
-#### 特点
-
-- ✅ 自我反思机制
-- ✅ 迭代优化输出
-- ✅ 适合需要高质量输出的场景
-- ✅ 可自定义反思和优化提示词
-
----
-
-### 4. PlanAndSolveAgent - 分解规划与逐步执行
-
-将复杂任务分解为子任务,然后逐步执行的 Agent。
-
-#### 基本使用
-
-```python
-from hello_agents import PlanAndSolveAgent, HelloAgentsLLM
-
-llm = HelloAgentsLLM()
-
-# 默认配置
-agent = PlanAndSolveAgent(
-    name="通用助手",
-    llm=llm
-)
-
-response = agent.run("如何学习Python编程?请制定一个详细的学习计划。")
-print(response)
-```
-
-#### 自定义提示词
-
-```python
-math_prompts = {
-    "planner": """
-你是一个数学问题分解专家。请将以下数学问题分解为清晰的计算步骤。
-每个步骤应该是一个具体的数学运算或逻辑推理。
-
-数学问题: {question}
-
-请按以下格式输出计算计划:
-```python
-["步骤1: 具体计算", "步骤2: 具体计算", ...]
-```
-""",
-    "executor": """
-你是一个数学计算专家。请严格按照计划执行数学计算。
-
-# 原始问题: {question}
-# 计算计划: {plan}
-# 已完成的计算: {history}
-# 当前计算步骤: {current_step}
-
-请执行当前步骤的计算,只输出计算结果:
-"""
-}
-
-math_agent = PlanAndSolveAgent(
-    name="数学专家",
-    llm=llm,
-    custom_prompts=math_prompts
-)
-```
-
-#### 特点
-
-- ✅ 任务分解能力
-- ✅ 逐步执行计划
-- ✅ 适合复杂任务
-- ✅ 可自定义规划器和执行器提示词
-
----
-
-### 5. FunctionCallAgent - 函数调用 Agent
-
-专门用于函数调用的 Agent,支持 OpenAI 的函数调用功能。
-
-#### 基本使用
-
-```python
-from hello_agents.agents import FunctionCallAgent
-from hello_agents.core.llm import HelloAgentsLLM
-from hello_agents.tools.registry import ToolRegistry
-
-def get_horoscope(sign: str) -> str:
-    """获取星座运势"""
-    sample_data = {
-        "白羊座": "保持耐心,合作能带来额外好运。",
-        "金牛座": "适合整理计划,财务上保持谨慎。",
-        "双子座": "沟通顺畅,适合推进新想法。",
-    }
-    return sample_data.get(sign.strip(), "今天以平静面对生活,一切都会慢慢变好。")
-
-# 创建 LLM
-llm = HelloAgentsLLM(model="gpt-4o-mini")
-
-# 创建工具注册表
-registry = ToolRegistry()
-registry.register_function(
-    name="get_horoscope",
-    description="Get today's horoscope for an astrological sign.",
-    func=get_horoscope,
-)
-
-# 创建 FunctionCallAgent
-agent = FunctionCallAgent(
-    name="demo-agent",
-    llm=llm,
-    tool_registry=registry,
-)
-
-# 运行
-question = "请告诉我金牛座今天的运势,并说明是如何得到信息的。"
-answer = agent.run(question)
-print("Agent:", answer)
-```
-
-#### 特点
-
-- ✅ 使用 OpenAI 函数调用
-- ✅ 自动参数解析
-- ✅ 适合需要精确函数调用的场景
-
----
-
-## 工具系统
-
-### ToolRegistry - 工具注册表
-
-用于注册和管理 Agent 可用的工具。
-
-#### 基本使用
-
-```python
-from hello_agents import ToolRegistry, search, calculate
-
-# 创建工具注册表
-tool_registry = ToolRegistry()
-
-# 注册内置工具
-tool_registry.register_function(
-    name="search",
-    description="网页搜索引擎",
-    func=search
-)
-
-tool_registry.register_function(
-    name="calculate",
-    description="数学计算工具",
-    func=calculate
-)
-
-# 注册自定义函数
-def custom_function(param: str) -> str:
-    """自定义函数"""
-    return f"处理结果: {param}"
-
-tool_registry.register_function(
-    name="custom_function",
-    description="自定义处理函数",
-    func=custom_function
-)
-```
-
----
-
-### MCPTool - MCP 协议工具
-
-用于集成 MCP (Model Context Protocol) 服务器的工具。
-
-#### 基本使用
-
-```python
-from hello_agents.tools import MCPTool
-
-# 创建 MCP 工具
-amap_tool = MCPTool(
-    name="amap",
-    description="高德地图服务",
-    server_command=["uvx", "amap-mcp-server"],
-    env={"AMAP_MAPS_API_KEY": "your-api-key"},
-    auto_expand=True  # 自动展开工具
-)
-
-# 添加到 Agent
-agent = SimpleAgent(name="地图助手", llm=llm)
-agent.add_tool(amap_tool)
-```
-
-#### 共享 MCP 工具
-
-在多智能体系统中,可以共享同一个 MCP 工具实例:
-
-```python
-class MultiAgentSystem:
-    def __init__(self):
-        # 创建共享的 MCP 工具(只创建一次)
-        self.amap_tool = MCPTool(
-            name="amap",
-            description="高德地图服务",
-            server_command=["uvx", "amap-mcp-server"],
-            env={"AMAP_MAPS_API_KEY": settings.amap_api_key},
-            auto_expand=True
-        )
-        
-        # 多个 Agent 共享同一个工具
-        self.agent1 = SimpleAgent(name="Agent1", llm=llm)
-        self.agent1.add_tool(self.amap_tool)
-        
-        self.agent2 = SimpleAgent(name="Agent2", llm=llm)
-        self.agent2.add_tool(self.amap_tool)
-```
-
----
-
-### 工具调用格式
-
-在 Agent 的提示词中,可以使用特定的工具调用格式:
-
-```python
-# 在提示词中指导 Agent 使用工具
-ATTRACTION_AGENT_PROMPT = """你是景点搜索专家。你的任务是根据城市和用户偏好搜索合适的景点。
-
-**重要提示:**
-你必须使用工具来搜索景点!不要自己编造景点信息!
-
-**工具调用格式:**
-使用maps_text_search工具时,必须严格按照以下格式:
-`[TOOL_CALL:amap_maps_text_search:keywords=景点关键词,city=城市名]`
-
-**示例:**
-用户: "搜索北京的历史文化景点"
-你的回复: [TOOL_CALL:amap_maps_text_search:keywords=历史文化,city=北京]
-"""
-```
-
----
-
-## 多智能体系统
-
-### 架构模式
-
-在实际项目中,多智能体系统通常采用以下架构:
-
-```
-用户请求
-    ↓
-协调层(可选)
-    ↓
-┌─────────────┬─────────────┬─────────────┐
-│  Agent 1    │  Agent 2    │  Agent 3    │
-│  (专业1)    │  (专业2)    │  (专业3)    │
-└─────────────┴─────────────┴─────────────┘
-    ↓              ↓              ↓
-共享工具层(MCP工具、API等)
-    ↓
-最终结果
-```
-
-### 实现示例
-
-基于 `helloagents-trip-planner` 项目的多智能体系统:
-
-```python
-class MultiAgentTripPlanner:
-    """多智能体旅行规划系统"""
-    
-    def __init__(self):
-        """初始化多智能体系统"""
-        self.llm = get_llm()
-        
-        # 创建共享的 MCP 工具
-        self.amap_tool = MCPTool(
-            name="amap",
-            description="高德地图服务",
-            server_command=["uvx", "amap-mcp-server"],
-            env={"AMAP_MAPS_API_KEY": settings.amap_api_key},
-            auto_expand=True
-        )
-        
-        # 创建专业 Agent
-        self.attraction_agent = SimpleAgent(
-            name="景点搜索专家",
-            llm=self.llm,
-            system_prompt=ATTRACTION_AGENT_PROMPT
-        )
-        self.attraction_agent.add_tool(self.amap_tool)
-        
-        self.weather_agent = SimpleAgent(
-            name="天气查询专家",
-            llm=self.llm,
-            system_prompt=WEATHER_AGENT_PROMPT
-        )
-        self.weather_agent.add_tool(self.amap_tool)
-        
-        self.hotel_agent = SimpleAgent(
-            name="酒店推荐专家",
-            llm=self.llm,
-            system_prompt=HOTEL_AGENT_PROMPT
-        )
-        self.hotel_agent.add_tool(self.amap_tool)
-        
-        # 规划 Agent(不需要工具)
-        self.planner_agent = SimpleAgent(
-            name="行程规划专家",
-            llm=self.llm,
-            system_prompt=PLANNER_AGENT_PROMPT
-        )
-    
-    def plan_trip(self, request: TripRequest) -> TripPlan:
-        """使用多智能体协作生成旅行计划"""
-        # 步骤1: 景点搜索
-        attraction_query = self._build_attraction_query(request)
-        attraction_response = self.attraction_agent.run(attraction_query)
-        
-        # 步骤2: 天气查询
-        weather_query = f"请查询{request.city}的天气信息"
-        weather_response = self.weather_agent.run(weather_query)
-        
-        # 步骤3: 酒店推荐
-        hotel_query = f"请搜索{request.city}的{request.accommodation}酒店"
-        hotel_response = self.hotel_agent.run(hotel_query)
-        
-        # 步骤4: 整合信息生成计划
-        planner_query = self._build_planner_query(
-            request, 
-            attraction_response, 
-            weather_response, 
-            hotel_response
-        )
-        planner_response = self.planner_agent.run(planner_query)
-        
-        # 解析最终计划
-        trip_plan = self._parse_response(planner_response, request)
-        return trip_plan
-```
-
-### 单例模式
-
-在多智能体系统中,使用单例模式管理 Agent 实例:
-
-```python
-# 全局多智能体系统实例
-_multi_agent_planner = None
-
-def get_trip_planner_agent() -> MultiAgentTripPlanner:
-    """获取多智能体旅行规划系统实例(单例模式)"""
-    global _multi_agent_planner
-    
-    if _multi_agent_planner is None:
-        _multi_agent_planner = MultiAgentTripPlanner()
-    
-    return _multi_agent_planner
-```
-
----
-
-## 项目架构模式
-
-### 1. 前后端分离架构
-
-```
-helloagents-trip-planner/
-├── backend/              # FastAPI 后端
-│   ├── app/
-│   │   ├── agents/       # Agent 层
-│   │   │   └── trip_planner_agent.py
-│   │   ├── api/          # API 层
-│   │   │   ├── main.py
-│   │   │   └── routes/
-│   │   │       └── trip.py
-│   │   ├── services/     # 服务层
-│   │   │   ├── llm_service.py
-│   │   │   └── amap_service.py
-│   │   ├── models/       # 数据模型
-│   │   │   └── schemas.py
-│   │   └── config.py     # 配置管理
-│   └── requirements.txt
-└── frontend/             # Vue.js 前端
-    └── src/
-```
-
-### 2. 配置管理
-
-使用 Pydantic Settings 管理配置:
-
-```python
-# config.py
-from pydantic_settings import BaseSettings
-from dotenv import load_dotenv
-
-load_dotenv()
-
-class Settings(BaseSettings):
-    """应用配置"""
-    app_name: str = "HelloAgents智能旅行助手"
-    app_version: str = "1.0.0"
-    
-    # API 配置
-    amap_api_key: str = ""
-    
-    # LLM 配置(从环境变量读取)
-    openai_api_key: str = ""
-    openai_base_url: str = "https://api.openai.com/v1"
-    openai_model: str = "gpt-4"
-    
-    class Config:
-        env_file = ".env"
-        case_sensitive = False
-
-settings = Settings()
-
-def get_settings() -> Settings:
-    """获取配置实例"""
-    return settings
-```
-
-### 3. API 路由
-
-使用 FastAPI 创建 RESTful API:
-
-```python
-# api/routes/trip.py
-from fastapi import APIRouter, HTTPException
-from ...agents.trip_planner_agent import get_trip_planner_agent
-from ...models.schemas import TripRequest, TripPlanResponse
-
-router = APIRouter(prefix="/trip", tags=["旅行规划"])
-
-@router.post("/plan", response_model=TripPlanResponse)
-async def plan_trip(request: TripRequest):
-    """生成旅行计划"""
-    try:
-        # 获取 Agent 实例
-        agent = get_trip_planner_agent()
-        
-        # 生成旅行计划
-        trip_plan = agent.plan_trip(request)
-        
-        return TripPlanResponse(
-            success=True,
-            message="旅行计划生成成功",
-            data=trip_plan
-        )
-    except Exception as e:
-        raise HTTPException(
-            status_code=500,
-            detail=f"生成旅行计划失败: {str(e)}"
-        )
-```
-
-### 4. 错误处理和降级
-
-实现错误处理和降级方案:
-
-```python
-def plan_trip(self, request: TripRequest) -> TripPlan:
-    """使用多智能体协作生成旅行计划"""
-    try:
-        # 多智能体协作流程
-        attraction_response = self.attraction_agent.run(query)
-        weather_response = self.weather_agent.run(query)
-        planner_response = self.planner_agent.run(query)
-        
-        # 解析响应
-        trip_plan = self._parse_response(planner_response, request)
-        return trip_plan
-        
-    except Exception as e:
-        print(f"❌ 生成旅行计划失败: {str(e)}")
-        # 降级方案:返回基础计划
-        return self._create_fallback_plan(request)
-
-def _create_fallback_plan(self, request: TripRequest) -> TripPlan:
-    """创建备用计划(当Agent失败时)"""
-    # 返回基础的计划结构
-    # ...
-```
-
----
-
-## 最佳实践
-
-### 1. LLM 实例管理
-
-✅ **推荐**:使用单例模式管理 LLM 实例
-
-```python
-_llm_instance = None
-
-def get_llm() -> HelloAgentsLLM:
-    global _llm_instance
-    if _llm_instance is None:
-        _llm_instance = HelloAgentsLLM()
-    return _llm_instance
-```
-
-❌ **不推荐**:每次创建新实例
-
-```python
-def process_request():
-    llm = HelloAgentsLLM()  # 每次都创建新实例
-    agent = SimpleAgent(llm=llm)
-```
-
-### 2. Agent 提示词设计
-
-✅ **推荐**:清晰的工具调用指导
-
-```python
-PROMPT = """你是专家。你必须使用工具来完成任务。
-
-**工具调用格式:**
-`[TOOL_CALL:tool_name:param1=value1,param2=value2]`
-
-**示例:**
-用户: "搜索北京景点"
-你的回复: [TOOL_CALL:search:keywords=北京景点]
-"""
-```
-
-❌ **不推荐**:模糊的提示词
-
-```python
-PROMPT = "你是专家,可以帮助用户。"  # 太模糊
-```
-
-### 3. 工具共享
-
-✅ **推荐**:在多智能体系统中共享工具实例
-
-```python
-class MultiAgentSystem:
-    def __init__(self):
-        # 创建一次,共享使用
-        self.shared_tool = MCPTool(...)
-        self.agent1.add_tool(self.shared_tool)
-        self.agent2.add_tool(self.shared_tool)
-```
-
-❌ **不推荐**:每个 Agent 创建独立工具
-
-```python
-agent1.add_tool(MCPTool(...))  # 创建多个实例
-agent2.add_tool(MCPTool(...))
-```
-
-### 4. 错误处理
-
-✅ **推荐**:完善的错误处理和降级方案
-
-```python
-try:
-    result = agent.run(query)
-    return result
-except Exception as e:
-    logger.error(f"Agent执行失败: {e}")
-    return fallback_result()
-```
-
-❌ **不推荐**:忽略错误
-
-```python
-result = agent.run(query)  # 没有错误处理
-return result
-```
-
-### 5. 配置管理
-
-✅ **推荐**:使用环境变量和配置类
-
-```python
-from pydantic_settings import BaseSettings
-from dotenv import load_dotenv
-
-load_dotenv()
-
-class Settings(BaseSettings):
-    api_key: str = ""
-    model: str = "gpt-4"
-    class Config:
-        env_file = ".env"
-```
-
-❌ **不推荐**:硬编码配置
-
-```python
-api_key = "sk-xxx"  # 硬编码
-```
-
-### 6. 响应解析
-
-✅ **推荐**:健壮的 JSON 解析
-
-```python
-def _parse_response(self, response: str) -> TripPlan:
-    """解析Agent响应"""
-    try:
-        # 尝试多种方式提取 JSON
-        if "```json" in response:
-            json_start = response.find("```json") + 7
-            json_end = response.find("```", json_start)
-            json_str = response[json_start:json_end].strip()
-        elif "{" in response and "}" in response:
-            json_start = response.find("{")
-            json_end = response.rfind("}") + 1
-            json_str = response[json_start:json_end]
-        else:
-            raise ValueError("响应中未找到JSON数据")
-        
-        data = json.loads(json_str)
-        return TripPlan(**data)
-    except Exception as e:
-        # 降级处理
-        return self._create_fallback_plan()
-```
-
-### 7. 日志和调试
-
-✅ **推荐**:详细的日志输出
-
-```python
-print(f"\n{'='*60}")
-print(f"🚀 开始多智能体协作规划旅行...")
-print(f"目的地: {request.city}")
-print(f"日期: {request.start_date} 至 {request.end_date}")
-print(f"{'='*60}\n")
-
-print("📍 步骤1: 搜索景点...")
-attraction_response = self.attraction_agent.run(query)
-print(f"景点搜索结果: {attraction_response[:200]}...\n")
-```
-
-### 8. Agent 职责划分
-
-✅ **推荐**:每个 Agent 专注于单一职责
-
-```python
-# 景点搜索专家 - 只负责搜索景点
-self.attraction_agent = SimpleAgent(
-    name="景点搜索专家",
-    system_prompt="你是景点搜索专家。你的任务是根据城市和用户偏好搜索合适的景点。"
-)
-
-# 天气查询专家 - 只负责查询天气
-self.weather_agent = SimpleAgent(
-    name="天气查询专家",
-    system_prompt="你是天气查询专家。你的任务是查询指定城市的天气信息。"
-)
-
-# 行程规划专家 - 整合信息生成计划
-self.planner_agent = SimpleAgent(
-    name="行程规划专家",
-    system_prompt="你是行程规划专家。你的任务是根据景点信息和天气信息,生成详细的旅行计划。"
-)
-```
-
----
-
-## 总结
-
-### 核心要点
-
-1. **选择合适的 Agent 类型**
-   - SimpleAgent:基础对话
-   - ReActAgent:需要工具调用
-   - ReflectionAgent:需要高质量输出
-   - PlanAndSolveAgent:复杂任务分解
-   - FunctionCallAgent:精确函数调用
-
-2. **工具系统**
-   - 使用 `ToolRegistry` 注册工具
-   - 使用 `MCPTool` 集成外部服务
-   - 在多智能体系统中共享工具实例
-
-3. **多智能体协作**
-   - 每个 Agent 专注单一职责
-   - 通过工作流串联多个 Agent
-   - 使用单例模式管理 Agent 实例
-
-4. **项目架构**
-   - 前后端分离
-   - 分层架构(API → Agent → Service)
-   - 配置管理和错误处理
-
-5. **最佳实践**
-   - LLM 实例单例管理
-   - 清晰的提示词设计
-   - 完善的错误处理
-   - 详细的日志输出
-
-### 学习路径
-
-1. **入门**:从 SimpleAgent 开始,理解基础概念
-2. **进阶**:学习 ReActAgent 和工具系统
-3. **高级**:掌握多智能体协作和自定义提示词
-4. **实战**:参考 `helloagents-trip-planner` 项目构建完整系统
-
----
-
-## 参考资源
-
-- **官方案例**:`helloagents-examples/`
-- **实战项目**:`helloagents-trip-planner/`
-- **文档**:HelloAgents 官方文档
-
----
-
-*本文档基于 `helloagents-examples` 和 `helloagents-trip-planner` 项目源码总结,最后更新时间:2024年12月*
-

+ 9 - 0
Co-creation-projects/melxy1997-ColumnWriter/models.py

@@ -91,4 +91,13 @@ class ColumnPlan:
     def get_topic_count(self) -> int:
         """获取话题数量"""
         return len(self.topics)
+    
+    def to_dict(self) -> Dict[str, Any]:
+        """转换为字典(用于缓存)"""
+        return {
+            'column_title': self.column_title,
+            'column_description': self.column_description,
+            'target_audience': self.target_audience,
+            'topics': self.topics
+        }
 

+ 1 - 1
Co-creation-projects/melxy1997-ColumnWriter/orchestrator.py

@@ -3,7 +3,7 @@
 from datetime import datetime
 from typing import Dict, Any, List
 from models import ContentNode, ContentLevel, ColumnPlan
-from agents_advanced import (
+from agents import (
     AdvancedPlannerAgent,
     AdvancedWriterAgent,
     AdvancedReflectionWriterAgent

+ 20 - 2
Co-creation-projects/melxy1997-ColumnWriter/prompts.py

@@ -459,12 +459,30 @@ def get_react_writer_prompt() -> str:
 Thought: 你的思考过程,用于分析问题、拆解任务和规划下一步行动。
 Action: 你决定采取的行动,必须是以下格式之一:
 - `{{tool_name}}[{{tool_input}}]`:调用一个可用工具。
-- `Finish[JSON内容]`:当你完成写作任务,准备好最终的JSON格式的文章时使用。
+- `\n\nFinish[JSON内容]`:当你完成写作任务,准备好最终的JSON格式的文章时使用。
+
+⚠️ **关键要求 - 必须严格遵守:**
+1. **完成写作后,必须使用 `\n\nFinish[JSON内容]` 格式输出结果**
+2. **不要只输出 JSON,必须用 `Finish[...]` 包裹**
+3. **`Finish` 中的内容必须是完整的 JSON 字符串,包含所有必需字段**
+4. **如果你已经写好了文章内容,即使没有调用工具,也必须使用 `Finish` 来结束任务**
 
 重要提示:
 - 你的最终目标是生成一个完整的JSON对象。
 - 在调用 `Finish` 之前,你可以多次使用 `Thought` 和 `Action` 来收集信息或进行构思。
-- `Finish` 的内容必须是一个完整的、符合任务要求的JSON字符串。
+- **当你完成写作后,必须使用 `\n\nFinish[JSON内容]` 格式,这是唯一正确的结束方式**
+- `Finish` 的内容必须是一个完整的、符合任务要求的JSON字符串,格式如下:
+  ```json
+  {{
+    "title": "章节标题",
+    "level": 层级数字,
+    "content": "完整的文章正文(markdown格式)",
+    "word_count": 实际字数,
+    "needs_expansion": true/false,
+    "subsections": [...],
+    "metadata": {{...}}
+  }}
+  ```
 
 现在,请开始解决以下问题:
 Question: {question}

Some files were not shown because too many files changed in this diff