AIGC入门,在Mac上基于Ollama和phi3:mini的完整Agent/Subagent例子

我来为你设计一个在Mac上基于Ollama和phi3:mini的完整Agent/Subagent例子。这个例子会模拟一个简单的"任务分解与执行"工作流,让你直观感受多智能体协作。

🎯 示例场景:智能任务处理器

我们将创建一个主Agent,它接收用户复杂任务,然后协调两个Subagent:

  • 分解专家Subagent:专门拆分复杂任务为具体步骤
  • 执行专家Subagent:专门执行具体步骤并报告结果

📁 项目结构

复制代码
phi3_agent_demo/
├── main.py              # 主程序
├── agents.py           # Agent类定义
├── requirements.txt    # 依赖包
└── README.md          # 说明文档

1. 首先安装必要依赖

bash 复制代码
# 创建项目目录
mkdir phi3_agent_demo && cd phi3_agent_demo

# 创建requirements.txt
echo "requests>=2.31.0
python-dotenv>=1.0.0" > requirements.txt

# 安装依赖
pip install -r requirements.txt

2. 创建Agent核心代码

agents.py - 定义Agent基类和具体Agent

python 复制代码
import requests
import json
import time
from typing import Dict, List, Any, Optional

class BaseAgent:
    """Agent基类,封装与Ollama的通信"""
    
    def __init__(self, name: str, model: str = "phi3:mini", system_prompt: str = ""):
        self.name = name
        self.model = model
        self.system_prompt = system_prompt
        self.ollama_url = "http://localhost:11434/api/generate"
        
    def query_llm(self, prompt: str, max_tokens: int = 500) -> str:
        """向Ollama发送查询"""
        payload = {
            "model": self.model,
            "prompt": f"{self.system_prompt}\n\n用户指令: {prompt}",
            "stream": False,
            "options": {
                "temperature": 0.3,
                "num_predict": max_tokens
            }
        }
        
        try:
            response = requests.post(self.ollama_url, json=payload, timeout=30)
            response.raise_for_status()
            result = response.json()
            return result.get("response", "").strip()
        except requests.exceptions.RequestException as e:
            return f"错误: 无法连接Ollama服务 - {str(e)}"
    
    def process(self, input_data: Any) -> Any:
        """处理输入,子类需要重写"""
        raise NotImplementedError("子类必须实现process方法")

class TaskDecomposerAgent(BaseAgent):
    """任务分解专家 - Subagent 1: 专门拆分复杂任务"""
    
    def __init__(self):
        system_prompt = """你是一个专业的任务分解专家。你的工作是将用户提出的复杂任务拆解为具体的、可执行的步骤。
        
        输出格式要求:
        1. 始终以JSON格式输出,包含一个"steps"数组
        2. 每个步骤是一个对象,包含"id"、"description"和"type"字段
        3. type可以是:research(研究)、calculate(计算)、write(写作)、review(审查)等
        
        示例:
        {"steps": [
            {"id": 1, "description": "搜索相关主题的最新信息", "type": "research"},
            {"id": 2, "description": "计算关键数据指标", "type": "calculate"}
        ]}
        
        现在开始处理用户任务:"""
        
        super().__init__("任务分解专家", system_prompt=system_prompt)
    
    def process(self, complex_task: str) -> List[Dict[str, Any]]:
        print(f"🔍 [{self.name}] 正在分析任务: {complex_task}")
        
        prompt = f"请将以下任务分解为具体步骤:\n\n任务: {complex_task}"
        response = self.query_llm(prompt)
        
        # 尝试解析JSON响应
        try:
            # 提取JSON部分(模型有时会在JSON前后添加文本)
            import re
            json_match = re.search(r'\{.*\}', response, re.DOTALL)
            if json_match:
                json_str = json_match.group()
                result = json.loads(json_str)
                steps = result.get("steps", [])
                
                print(f"✅ [{self.name}] 分解完成,共{len(steps)}个步骤")
                for step in steps:
                    print(f"   - 步骤{step['id']}: {step['description']} ({step['type']})")
                
                return steps
            else:
                # 如果无法解析为JSON,创建默认步骤
                return [{"id": 1, "description": response[:100], "type": "general"}]
                
        except json.JSONDecodeError:
            print(f"⚠️  [{self.name}] JSON解析失败,使用原始响应")
            return [{"id": 1, "description": response[:100], "type": "general"}]

class TaskExecutorAgent(BaseAgent):
    """任务执行专家 - Subagent 2: 专门执行具体任务"""
    
    def __init__(self, expertise: str = "general"):
        self.expertise = expertise
        system_prompt = f"""你是一个专业的{expertise}任务执行专家。你的工作是具体执行分配给你的任务步骤。
        
        你需要:
        1. 理解任务要求
        2. 执行具体操作(思考、计算、分析等)
        3. 提供清晰的执行结果
        
        输出格式:
        {{"status": "success|partial|failed", "result": "具体执行结果", "details": "详细说明"}}
        
        现在请执行以下任务:"""
        
        super().__init__(f"{expertise}执行专家", system_prompt=system_prompt)
    
    def process(self, task_step: Dict[str, Any]) -> Dict[str, Any]:
        step_id = task_step.get("id", 0)
        description = task_step.get("description", "")
        step_type = task_step.get("type", "general")
        
        print(f"🛠️  [{self.name}] 正在执行步骤{step_id}: {description}")
        
        prompt = f"任务类型: {step_type}\n任务描述: {description}\n\n请执行此任务并报告结果:"
        response = self.query_llm(prompt)
        
        # 尝试解析响应中的JSON
        try:
            import re
            json_match = re.search(r'\{.*\}', response, re.DOTALL)
            if json_match:
                result = json.loads(json_match.group())
            else:
                result = {"status": "success", "result": response, "details": "模型返回了非JSON格式"}
        except:
            result = {"status": "partial", "result": response[:200], "details": "响应解析异常"}
        
        print(f"✅ [{self.name}] 步骤{step_id}完成,状态: {result.get('status', 'unknown')}")
        return result

class OrchestratorAgent(BaseAgent):
    """主协调Agent - 负责管理整个工作流"""
    
    def __init__(self):
        system_prompt = """你是智能任务协调员,负责协调多个专家完成复杂任务。
        
        你的工作流程:
        1. 接收用户的复杂任务
        2. 调用任务分解专家拆解任务
        3. 为每个步骤分配合适的执行专家
        4. 汇总所有结果并生成最终报告
        
        现在开始协调:"""
        
        super().__init__("主协调员", system_prompt=system_prompt)
        
        # 初始化Subagents
        self.decomposer = TaskDecomposerAgent()
        
        # 根据任务类型创建不同的执行专家
        self.executors = {
            "research": TaskExecutorAgent("研究"),
            "calculate": TaskExecutorAgent("计算"),
            "write": TaskExecutorAgent("写作"),
            "review": TaskExecutorAgent("审查"),
            "general": TaskExecutorAgent("综合")
        }
    
    def process(self, user_task: str) -> Dict[str, Any]:
        print(f"\n🎯 [{self.name}] 接收任务: {user_task}")
        print("=" * 50)
        
        # 阶段1: 任务分解
        print("📋 阶段1: 任务分解")
        steps = self.decomposer.process(user_task)
        
        if not steps:
            return {"status": "failed", "error": "任务分解失败"}
        
        # 阶段2: 并行执行各步骤
        print(f"\n🚀 阶段2: 执行{len(steps)}个步骤")
        results = []
        
        for step in steps:
            step_type = step.get("type", "general")
            executor = self.executors.get(step_type, self.executors["general"])
            
            # 执行当前步骤
            step_result = executor.process(step)
            step_result["step_info"] = step
            results.append(step_result)
            
            # 添加小延迟,避免请求过快
            time.sleep(1)
        
        # 阶段3: 汇总结果
        print(f"\n📊 阶段3: 汇总{len(results)}个步骤的结果")
        final_result = self._summarize_results(user_task, results)
        
        return final_result
    
    def _summarize_results(self, original_task: str, step_results: List[Dict]) -> Dict[str, Any]:
        """汇总所有步骤的结果"""
        prompt = f"""原始任务: {original_task}

已完成的所有步骤结果:
{json.dumps(step_results, indent=2, ensure_ascii=False)}

请基于以上执行结果,生成最终的任务完成报告。
报告应包含:总体完成情况、关键发现、下一步建议。

请用JSON格式输出:
{{"overall_status": "completed|partial|failed", "summary": "总体摘要", "key_findings": ["发现1", "发现2"], "next_steps": ["建议1", "建议2"]}}"""
        
        response = self.query_llm(prompt)
        
        try:
            import re
            json_match = re.search(r'\{.*\}', response, re.DOTALL)
            if json_match:
                summary = json.loads(json_match.group())
            else:
                summary = {"overall_status": "completed", "summary": response[:300]}
        except:
            summary = {"overall_status": "completed", "summary": "任务执行完成"}
        
        return {
            "original_task": original_task,
            "step_results": step_results,
            "final_summary": summary
        }

3. 主程序入口

main.py - 运行演示

python 复制代码
#!/usr/bin/env python3
"""
基于Ollama phi3:mini的多智能体演示
确保Ollama服务已运行: ollama serve
"""

import sys
from agents import OrchestratorAgent
import json

def check_ollama():
    """检查Ollama服务是否运行"""
    import requests
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        return response.status_code == 200
    except:
        return False

def main():
    print("=" * 60)
    print("🤖 基于Ollama phi3:mini的多智能体演示")
    print("=" * 60)
    
    # 检查Ollama服务
    print("🔍 检查Ollama服务...")
    if not check_ollama():
        print("❌ 错误: Ollama服务未运行!")
        print("请先启动Ollama服务:")
        print("  1. 打开新终端窗口")
        print("  2. 运行: ollama serve")
        print("  3. 保持终端打开,然后重新运行此程序")
        return
    
    print("✅ Ollama服务正常")
    
    # 创建主协调Agent
    print("\n🚀 初始化多智能体系统...")
    orchestrator = OrchestratorAgent()
    
    # 示例任务列表
    sample_tasks = [
        "帮我规划一个周末杭州旅行行程,包括景点、美食和预算",
        "分析苹果公司2024年第一季度的财务表现和未来展望",
        "写一篇关于人工智能在教育领域应用的短文",
        "制定一个学习Python编程的3个月计划"
    ]
    
    print("\n📝 示例任务:")
    for i, task in enumerate(sample_tasks, 1):
        print(f"  {i}. {task[:50]}...")
    
    while True:
        print("\n" + "=" * 50)
        print("请选择:")
        print("  1-4: 运行示例任务")
        print("  5: 输入自定义任务")
        print("  0: 退出")
        
        choice = input("\n请选择 (0-5): ").strip()
        
        if choice == "0":
            print("👋 再见!")
            break
        elif choice in ["1", "2", "3", "4"]:
            task_index = int(choice) - 1
            user_task = sample_tasks[task_index]
        elif choice == "5":
            user_task = input("请输入你的任务: ").strip()
            if not user_task:
                print("⚠️  任务不能为空")
                continue
        else:
            print("⚠️  无效选择")
            continue
        
        print(f"\n📨 任务: {user_task}")
        print("⏳ 开始处理...")
        
        # 执行任务
        final_result = orchestrator.process(user_task)
        
        # 显示结果
        print("\n" + "=" * 50)
        print("📋 最终报告")
        print("=" * 50)
        
        summary = final_result.get("final_summary", {})
        print(f"📈 总体状态: {summary.get('overall_status', 'unknown')}")
        print(f"📝 摘要: {summary.get('summary', '')[:200]}...")
        
        if 'key_findings' in summary:
            print("\n🔑 关键发现:")
            for finding in summary['key_findings']:
                print(f"  • {finding}")
        
        # 保存详细结果到文件
        output_file = f"task_result_{int(time.time())}.json"
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(final_result, f, indent=2, ensure_ascii=False)
        
        print(f"\n💾 详细结果已保存到: {output_file}")

if __name__ == "__main__":
    import time
    main()

4. 创建配置文件

.env (可选,用于未来扩展)

env 复制代码
OLLAMA_HOST=http://localhost:11434
DEFAULT_MODEL=phi3:mini
MAX_TOKENS=1000

5. 运行演示

bash 复制代码
# 1. 确保Ollama服务运行(在新终端中)
ollama serve

# 2. 确保phi3:mini模型已下载
ollama list
# 如果没看到phi3:mini,运行: ollama pull phi3:mini

# 3. 在另一个终端中,运行演示程序
cd phi3_agent_demo
python main.py

6. 示例运行输出

当你运行程序并选择任务时,会看到类似输出:

复制代码
🎯 [主协调员] 接收任务: 帮我规划一个周末杭州旅行行程
📋 阶段1: 任务分解
🔍 [任务分解专家] 正在分析任务...
✅ [任务分解专家] 分解完成,共4个步骤
   - 步骤1: 搜索杭州主要景点 (research)
   - 步骤2: 计算交通和住宿预算 (calculate)
   - 步骤3: 撰写详细行程安排 (write)
   - 步骤4: 审查并优化计划 (review)

🚀 阶段2: 执行4个步骤
🛠️  [研究执行专家] 正在执行步骤1...
✅ [研究执行专家] 步骤1完成,状态: success
🛠️  [计算执行专家] 正在执行步骤2...
...

📊 阶段3: 汇总结果
📋 最终报告
总体状态: completed
摘要: 已成功规划杭州周末行程...

🔧 故障排查

  1. Ollama连接失败

    bash 复制代码
    # 检查Ollama是否运行
    curl http://localhost:11434/api/tags
    
    # 如果没有响应,重启Ollama
    pkill ollama
    ollama serve &
  2. 模型未找到

    bash 复制代码
    # 列出已安装模型
    ollama list
    
    # 如果phi3:mini不存在,下载它
    ollama pull phi3:mini
  3. 响应速度慢

    • phi3:mini在CPU上运行可能较慢,这是正常的
    • 可以尝试减小MAX_TOKENS或增加步骤间延迟

🎯 这个例子展示了什么?

  1. 角色分工:主Agent协调,Subagent专业执行
  2. 工作流管理:分解→执行→汇总的标准流程
  3. 上下文隔离:每个Agent有自己的系统提示和专长
  4. 错误处理:基本的异常处理和降级方案
  5. 结果整合:最终报告生成和持久化

你可以基于这个框架扩展更多Subagent,添加工具调用(如网络搜索、文件操作),或实现更复杂的协作逻辑。这是理解多智能体系统的绝佳起点!

相关推荐
九河云17 小时前
数据驱动未来,华为云DWS为智能决策提速
大数据·人工智能·安全·机器学习·华为云
华清远见成都中心18 小时前
机器学习怎么学?
人工智能·机器学习
碎碎思18 小时前
在 FPGA 上实现并行脉冲神经网络(Spiking Neural Net)
人工智能·深度学习·神经网络·机器学习·fpga开发
Terrence Shen18 小时前
【CUDA编程系列】之01
c++·人工智能·深度学习·机器学习
综合热讯18 小时前
脑机接口赋能 认知障碍诊疗迈入精准时代
人工智能·机器学习·数据挖掘
AI科技星19 小时前
引力与电磁的动力学耦合:变化磁场产生引力场与电场方程的第一性原理推导、验证与统一性意义
服务器·人工智能·科技·线性代数·算法·机器学习·生活
视觉&物联智能19 小时前
【杂谈】-多智能体系统的效能悖论:协作优势的认知边界
ai·llm·agent·智能体·人工 智能
xiao5kou4chang6kai419 小时前
面向自然科学领域机器学习与深度学习(高维数据预处理—可解释ML/DL—时空建模—不确定性量化-全程AI+Python)
人工智能·深度学习·机器学习·不确定性量化·时空建模·高维数据预处理·可解释ml/dl
光羽隹衡19 小时前
机器学习——DBSCAN算法
人工智能·算法·机器学习