项目05-手搓Agent之任务通信+任务编排的实现

核心架构

  • 通讯层: TeamCollaboration → 邮箱、发消息、日志、任务状态管理;
  • 调度层: DAGTaskOrchestrator → 控制任务依赖、执行顺序;
  • 执行层: AgentTeam → 智能体异步执行任务;

顶层入口

python 复制代码
def demo_complete_workflow():
    """完整演示:团队通信 + DAG编排 + 智能体执行"""
    print("===== 完整流程演示:DAG + 团队协作 =====")

    client = OpenAI()

    # 初始化三大层
    collaboration = TeamCollaboration() # 团队通信层
    team = AgentTeam(client) # 任务执行逻辑层
    team.start()
    orchestration = DAGOrchestration(team, collaboration) # 任务编排层

    # 初始化邮箱
    collaboration.init_agent_mailbox("coder")
    collaboration.init_agent_mailbox("tester")

    # ========== 核心:创建带依赖的任务 ==========
    print("\n[1] 创建依赖任务链...")
    t1 = orchestration.add_task("分析登录需求", assigned_to="coder")
    t2 = orchestration.add_task("开发登录功能", assigned_to="coder", deps=[t1])
    t3 = orchestration.add_task("测试登录功能", assigned_to="tester", deps=[t2])

    # 查看执行顺序
    print(f"✅ 任务执行顺序:{orchestration.get_order()}")
    print(f"✅ 当前可执行任务:{orchestration.get_ready()}")

    # 模拟任务完成(自动解锁下一个任务)
    print("\n[2] 模拟执行任务...")
    orchestration.finish_task(t1)
    print(f"完成 t1 → 可执行任务:{orchestration.get_ready()}")

    orchestration.finish_task(t2)
    print(f"完成 t2 → 可执行任务:{orchestration.get_ready()}")

    orchestration.finish_task(t3)
    print("所有任务执行完成!")

    # 统计信息
    print(f"\n📊 协作统计:总消息数 = {len(collaboration.collaboration_log)}")

# 运行完整演示
if __name__ == "__main__":
    demo_complete_workflow()

第一步: 初始化通讯层 TeamCollaboration、任务分配层 DAGOrchestration、Agent 执行层 AgentTeam
第二步: 初始化邮箱,用于通信;
第三步: 创建带依赖的任务;
第四步: Agent 完成任务;

txt 复制代码
===== 完整流程演示:DAG + 团队协作 =====

[1] 创建依赖任务链...
✅ 任务执行顺序:[t1, t2, t3]
✅ 当前可执行任务:[t1]

[2] 模拟执行任务...
完成 t1 → 可执行任务:[t2]
完成 t2 → 可执行任务:[t3]
所有任务执行完成!

📊 协作统计:总消息数 = 3

1 任务编排器

功能: 将【团队协作】、【DAG依赖】、【智能体执行】三层完全打通;
职责:

  1. 通过 通信层 创建带依赖的协作任务;
  2. 通过 任务编排层 管理任务执行顺序;
  3. 通过 通信层 自动发送消息通知智能体;
  4. 通过 执行层 任务完成后同步更新状态与依赖;
python 复制代码
# DAG编排器(调度+依赖+协作融合)
class DAGOrchestration:
    def __init__(self, team: AgentTeam, collaboration: TeamCollaboration):
        self.team = team # Agent 执行层
        self.collab = collaboration # 通信层
        self.dag = DAGScheduler() # 任务调度层
        self.pending_tasks = {}   # ✅ 所有任务缓存(不直接进队列)

    def add_task(self, content: str, assigned_to: str, deps: Optional[List[str]] = None) -> str:
   		 """
        🚀 添加一个带依赖、带分配、带消息通知的完整 DAG 任务(最核心方法)
			        :param content: 任务具体内容(字符串),例如:"开发登录页面"
			        :param assigned_to: 任务分配给哪个智能体,例如:"coder" / "tester"
			        :param deps: 依赖的任务 ID 列表,代表必须等这些任务完成才能执行
			                     默认为 None = 无依赖
			        :return: 返回创建好的唯一任务 ID
        """
        # 1. 团队协作:创建任务 + 记录状态
        task_id = self.collab.create_task(content, assigned_to, deps)
        # 2. DAG:添加依赖关系
        self.dag.add_task(task_id, deps)

				# 3. 缓存任务,所有任务先放这里,不直接执行(候选室)
        self.pending_tasks[task_id] = {
            "id": task_id,
            "content": content,
            "assigned_to": assigned_to
        }
        # 4. 通信:主管发消息通知智能体
        self.collab.send_message("lead", assigned_to, f"已安排任务:{content}")

        return task_id

		def submit_ready_tasks(self):
        """
        ✅【核心】提交当前【依赖已完成】的任务到执行队列
        自动过滤未就绪任务 → 真正实现 DAG 阻塞执行
        """
        ready_task_ids = self.dag.get_ready_tasks() # 可执行任务的 ids

        for task_id in ready_task_ids: # 遍历
            if task_id in self.pending_tasks: # 从候选室中挑选出对应的 id 执行
                # 取出任务并提交执行
                task = self.pending_tasks.pop(task_id)
                self.team.submit(task)
                print(f"🚀 启动任务:{task_id} → {task['content']}")

    def finish_task(self, task_id: str):
        """
        ✅ 标记完成 → 自动解锁下一批任务 → 自动提交执行
        这才是完整 DAG!
        """
        # 1. 标记状态完成
        self.dag.mark_complete(task_id)

        # 2. ✅ 自动提交新解锁的可执行任务(核心!)
        self.submit_ready_tasks()

    def get_order(self):
        return self.dag.topological_sort()

    def get_ready(self):
        return self.dag.get_ready_tasks()

DAG 依赖类:

python 复制代码
class DAGScheduler:
    """
    🧠 DAG 任务调度器(核心依赖管理层)
    功能:基于有向无环图(DAG)管理任务的依赖关系、执行顺序、可执行状态
    作用:
        1. 添加任务与依赖
        2. 判断哪些任务可以执行(依赖全部完成)
        3. 标记任务完成
        4. 拓扑排序获取全局执行顺序
    """

    def __init__(self):
        """初始化 DAG 调度器"""
        # 存储所有任务:key=任务ID,value={"deps": [依赖任务ID列表]}
        self.tasks = {}
        # 存储已完成的任务ID集合(用于快速判断)
        self.completed = set()

    def add_task(self, task_id: str, dependencies: List[str] = None):
        """
        添加任务及其依赖
        :param task_id: 任务唯一ID
        :param dependencies: 该任务依赖的任务ID列表,默认为无依赖
        """
        self.tasks[task_id] = {"deps": dependencies or []}

    def get_ready_tasks(self) -> List[str]:
        """
        🎯 获取【可执行任务】列表
        规则:
            1. 任务未被标记为完成
            2. 该任务的**所有依赖任务都已经完成**
        :return: 符合条件的任务ID列表
        """
        ready = []
        # 遍历所有任务,检查是否满足执行条件
        for tid, info in self.tasks.items():
            # 任务未完成 + 所有依赖都已完成
            if tid not in self.completed and all(dep in self.completed for dep in info["deps"]):
                ready.append(tid)
        return ready

    def mark_complete(self, task_id: str):
        """
        ✅ 标记任务为已完成
        会自动解锁依赖它的后续任务
        :param task_id: 要标记完成的任务ID
        """
        self.completed.add(task_id)

    def topological_sort(self) -> List[str]:
        """
        📊 拓扑排序(DFS 实现)
        作用:根据依赖关系,生成**合法的任务执行顺序**
        例如:t1 → t2 → t3
        :return: 按执行顺序排列的任务ID列表
        """
        visited = set()  # 记录已访问节点
        res = []         # 存储排序结果

        # 深度优先遍历
        def dfs(n):
            if n in visited:
                return
            visited.add(n)
            # 先递归处理所有依赖任务
            for dep in self.tasks[n]["deps"]:
                dfs(dep)
            # 依赖处理完,再加入自身
            res.append(n)

        # 对所有任务执行 DFS
        for task in self.tasks:
            dfs(task)

        return res

2 通信层+任务状态层

核心功能:

  1. 智能体之间的消息通信(邮箱系统)
  2. 协作日志持久化(保存到 JSON 文件)
  3. 任务状态管理(待办 / 已完成)
  4. 任务分配与消息通知
python 复制代码
class TeamCollaboration:
    """
    👥 团队协作核心类(通信层 + 任务状态层)
    核心功能:
        1. 智能体之间的消息通信(邮箱系统)
        2. 协作日志持久化(保存到 JSON 文件)
        3. 任务状态管理(待办 / 已完成)
        4. 任务分配与消息通知
    与 DAG 关系:只负责通信和状态,不控制执行顺序
    """

    def __init__(self):
        """
        初始化团队协作系统
        包含:邮箱系统、任务管理器、日志系统、文件存储
        """
        # 邮箱系统:key = 智能体名称,value = Mailbox 实例
        self.mailbox_system = {}
        # 协作日志列表:记录所有消息发送记录
        self.collaboration_log = []
        # 团队数据存储目录
        self.team_dir = ".team"
        # 协作日志保存路径
        self.log_file = os.path.join(self.team_dir, "collaboration_log.json")
        # 创建目录(不存在则创建,存在不报错)
        os.makedirs(self.team_dir, exist_ok=True)
        # 启动时加载历史日志
        self._load_logs()

    def _load_logs(self):
        """
        🔒 私有方法:从文件加载历史协作日志
        如果日志文件存在,则读取;不存在则保持空列表
        """
        if os.path.exists(self.log_file):
            with open(self.log_file, encoding="utf-8") as f:
                self.collaboration_log = json.load(f)

    def _save_logs(self):
        """
        🔒 私有方法:保存当前协作日志到 JSON 文件
        每次发送消息后自动调用,实现持久化
        """
        with open(self.log_file, "w", encoding="utf-8") as f:
            json.dump(self.collaboration_log, f, indent=2, ensure_ascii=False)

    def init_agent_mailbox(self, agent_name: str):
        """
        ✉️ 初始化指定智能体的邮箱
        每个智能体必须拥有邮箱才能接收消息
        :param agent_name: 智能体名称,如 coder / tester
        """
        self.mailbox_system[agent_name] = Mailbox(agent_name)

    def send_message(self, from_agent: str, to_agent: str, content: str, priority=5) -> str:
        """
        📤 智能体之间发送消息(核心通信方法)
        自动创建邮箱、记录日志、持久化到文件
        :param from_agent: 发送方智能体名称(如 lead)
        :param to_agent: 接收方智能体名称(如 coder)
        :param content: 消息内容(任务/通知/指令)
        :param priority: 消息优先级 1-10,默认 5
        :return: 生成的唯一消息 ID
        """
        # 如果接收方没有邮箱,自动初始化
        if to_agent not in self.mailbox_system:
            self.init_agent_mailbox(to_agent)
        
        # 向目标邮箱推送消息,获取消息ID
        msg_id = self.mailbox_system[to_agent].push(
            from_agent=from_agent, 
            content=content, 
            priority=priority
        )
        
        # 构造日志结构:时间 + 发送方 + 接收方 + 消息ID
        log = {
            "time": datetime.now().isoformat(),
            "from": from_agent,
            "to": to_agent,
            "msg_id": msg_id
        }
        
        # 加入日志并保存
        self.collaboration_log.append(log)
        self._save_logs()
        
        return msg_id

    def create_task(self, description: str, 
                   assigned_to: str = None, priority: int = 5,
                   dependencies: List[str] = None) -> str:
        """✨ 创建新任务"""
        task_id = f"task_{uuid.uuid4().hex[:8]}"
        task = {
            "id": task_id,
            "description": description,
            "status": TaskStatus.PENDING.value,
            "priority": priority,  # 1-10
            "assigned_to": assigned_to,  # None = any agent can pick
            "dependencies": dependencies or [],
            "created_at": datetime.now().isoformat(),
            "updated_at": datetime.now().isoformat(),
            "result": None,
            "error": None
        }
        self._tasks[task_id] = task
        # 保存任务详情
        self._save_task_file(task_id, task)
        self._save_index()
        return task_id

核心: 这里的 TeamCollaboration 本质上已经具备了 (1)邮箱初始化、(2)任务创建、(3)发送消息、(4)团队消息持久化;的功能

3 执行层

作用: 启动线程、消费队列、真正执行任务;

python 复制代码
class AgentTeam:
    """
    🤖 智能体团队执行类(任务执行层)
    核心功能:
        1. 管理多个子智能体(编码员、测试员等)
        2. 基于生产者-消费者模型实现异步任务执行
        3. 多线程并发处理任务,提高执行效率
        4. 接收并执行来自 DAG 编排器的任务
    定位:只负责执行任务,不管理通信、不管理依赖顺序
    """

    def __init__(self, client, model="gpt-4o"):
        """
        初始化智能体团队
        :param client: LLM 客户端实例(OpenAI 或其他模型客户端)
        :param model: 使用的大模型名称,默认为 gpt-4o
        """
        # LLM 模型客户端,用于智能体调用 AI 能力
        self.client = client
        # 使用的大模型版本/名称
        self.model = model

        # 主管智能体:负责统筹、分配任务(不执行具体工作)
        self.lead = LeadAgent("lead", model, client)

        # 子智能体集群:真正执行具体任务的角色
        self.sub_agents = {
            "coder": SubAgent("coder", "coding", model, client),   # 编码智能体
            "tester": SubAgent("tester", "testing", model, client),  # 测试智能体
        }

        # 任务队列:生产者-消费者模型核心,存储待执行的任务
        self.task_queue = queue.Queue()

        # 运行中的智能体线程字典:key=智能体名称,value=线程实例
        self.running_agents = {}

    def start(self):
        """
        🚀 启动智能体团队工作线程
        为每个子智能体创建一个守护线程,开始循环监听并执行任务
        主线程退出时,工作线程自动退出
        """
        # 遍历所有子智能体,为每个创建工作线程
        for name, agent in self.sub_agents.items():
            # 创建守护线程,执行 _worker 循环方法
            t = threading.Thread(target=self._worker, args=(agent,), daemon=True)
            # 启动线程
            t.start()
            # 记录线程,方便管理/查看状态
            self.running_agents[name] = t

    def _worker(self, agent: SubAgent):
        """
        🔄 智能体工作循环(消费者核心逻辑)
        私有方法:持续从任务队列获取任务并执行
        :param agent: 当前线程绑定的子智能体实例
        """
        # 无限循环,持续监听任务
        while True:
            try:
                # 从队列获取任务,超时 2 秒避免无限阻塞
                # 超时后会抛出 queue.Empty 异常,重新循环
                task = self.task_queue.get(timeout=2)

                # 调用智能体的方法,执行当前任务
                agent.process_task(task)

                # 标记任务完成:队列内部计数 -1,表示任务已处理完毕
                self.task_queue.task_done()

            except queue.Empty:
                # 队列为空,无任务可执行,继续循环等待新任务
                continue

    def submit(self, task: Dict):
        """
        📥 提交任务到团队队列(生产者方法)
        将任务放入队列,等待空闲智能体获取并执行
        :param task: 任务字典,必须包含 id 和 content 等信息
        """
        self.task_queue.put(task)
相关推荐
weixin199701080166 分钟前
《识货商品详情页前端性能优化实战》
前端·性能优化
Forever7_7 分钟前
重磅!Vue3 手势工具正式发布!免费使用!
前端·前端框架·前端工程化
用户806138166598 分钟前
发布为一个 npm 包
前端·javascript
开开心心_Every17 分钟前
限时免费加密、隐藏、锁定文件文件夹好工具
运维·服务器·人工智能·edge·pdf·逻辑回归·深度优先
树上有只程序猿38 分钟前
低代码何时能出个“秦始皇”一统天下?我是真学不动啦!
前端·后端·低代码
TT_哲哲39 分钟前
小程序双模式(文件 / 照片)上传组件封装与解析
前端·javascript
野犬寒鸦43 分钟前
Redis复习记录day1
服务器·开发语言·数据库·redis·缓存
龙俊俊1 小时前
服务器模型部署与加载
服务器·人工智能·深度学习
菜果果儿1 小时前
Vue 3 + TypeScript 常用代码示例总结
前端
前端付豪1 小时前
实现多角色模式切换
前端·架构