当前位置: 首页 > news >正文

Agentic AI 多智能体协作:开发实战、框架选型与踩坑指南

做智能制造系统时,曾遇到一个棘手问题:单智能体既要处理设备数据采集,又要做故障预测和 AGV 调度,结果内存占满、响应延迟超 5 秒。后来拆成 3 个协作智能体,各司其职又动态配合,延迟直接降到 200ms 以内 —— 这就是多智能体协作的实战价值。

作为开发人员,我们更关心 “怎么搭架构”“用哪个框架”“如何避坑”。本文结合 3 个工业级项目经验,从技术落地角度拆解 Agentic AI 多智能体系统的开发全流程,包含可直接复用的代码片段、框架选型对比和资源优化技巧,帮你少走弯路。

一、先搞懂:自主智能体的 “开发三要素”

要做多智能体协作,先得摸清单个智能体的核心组件 —— 这是后续协作的基础。OpenAI 提出的 “规划 - 记忆 - 工具” 三模块,在开发中可直接落地为代码架构。

1.1 规划系统:让智能体 “会拆任务”

规划的核心是把 “优化工厂能耗” 这类模糊目标,拆成 “采集设备功率→分析高耗设备→调整运行参数” 的可执行步骤。开发中常用两种方案:

方案 1:基于 ReAct 框架的轻量化规划(适合中小任务)

用 LLM 生成 “思考 - 行动” 序列,比如用 GPT-4o-mini 做设备调度规划,关键代码如下:

from openai import OpenAI

client = OpenAI(api_key="your-key")

def react_planner(goal, history=[]):

    # 1. 思考:分析当前目标和历史,确定下一步动作

    thought_prompt = f"""

    目标:{goal}

    已完成动作:{history}

    请思考:下一步需要做什么?(用1句话说明)

    """

    thought = client.chat.completions.create(

        model="gpt-4o-mini",

        messages=[{"role": "user", "content": thought_prompt}]

    ).choices[0].message.content

    # 2. 行动:生成具体执行指令(如调用设备API)

    action_prompt = f"""

    思考:{thought}

    请生成行动指令:格式为["动作类型(如call_api/analyze_data)", "参数"]

    示例:["call_api", {"url": "http://device/power", "method": "GET"}]

    """

    action = eval(client.chat.completions.create(

        model="gpt-4o-mini",

        messages=[{"role": "user", "content": action_prompt}]

    ).choices[0].message.content)

    

    return {"thought": thought, "action": action}

# 测试:规划“降低机床A能耗”

goal = "将机床A的能耗从15kW降至12kW"

first_step = react_planner(goal)

print(first_step)

# 输出示例:

# {

#   "thought": "需要先获取机床A当前的功率数据和运行参数",

#   "action": ["call_api", {"url": "http://device/machineA", "method": "GET"}]

# }

方案 2:LLM+PDDL 专业规划(适合复杂任务)

当任务涉及多约束(如 “AGV 调度不能冲突 + 优先运输紧急物料”),可把自然语言转成规划领域定义语言(PDDL),调用专业规划器(如 Fast Downward)。开发要点:

  • 用 LLM 生成 PDDL 文件(避免手动写语法);
  • 规划器输出结果后,再用 LLM 转成代码可执行的指令。

1.2 记忆系统:让智能体 “记事儿”

开发中最容易踩的坑是 “内存爆炸”—— 如果把所有历史数据都塞 LLM 上下文,token 会超限制。正确做法是分层存储:

记忆类型

存储方式

开发实操

短期记忆

LLM 上下文窗口

只存当前任务的最近 10 步动作 + 结果,用列表维护

长期记忆

向量数据库(如 Milvus)

把历史经验(如 “2024-05 机床 B 故障解决方案”)转成向量存储,查询时用相似性匹配召回

长期记忆的核心代码示例(用 Milvus 存储故障经验):

from pymilvus import connections, Collection

import numpy as np

from sentence_transformers import SentenceTransformer

# 1. 初始化向量模型和Milvus

model = SentenceTransformer('all-MiniLM-L6-v2')

connections.connect("default", host="localhost", port="19530")

collection = Collection("equipment_fault_memory")  # 提前创建好的集合

# 2. 存储故障经验(长期记忆写入)

def save_memory(fault_desc, solution):

    memory_text = f"故障:{fault_desc},解决方案:{solution}"

    embedding = model.encode([memory_text])  # 转向量

    data = [

        [1],  # id(实际用自增ID)

        embedding.tolist(),  # 向量

        [memory_text]  # 原始文本

    ]

    collection.insert(data)

# 3. 查询相似经验(长期记忆读取)

def recall_memory(current_fault):

    query_emb = model.encode([current_fault])

    search_params = {"metric_type": "L2", "params": {"nprobe": 10}}

    results = collection.search(

        data=query_emb,

        anns_field="embedding",

        param=search_params,

        limit=1  # 取最相似的1条

    )

    return results[0][0].entity.get("text") if results else "无相似经验"

# 测试:存储+查询

save_memory("机床A温度超80℃", "关闭设备10分钟,清理散热片")

print(recall_memory("机床A温度过高"))  # 输出存储的解决方案

1.3 工具系统:让智能体 “能干活”

工具是智能体与物理世界交互的桥梁,开发时要做好 “工具注册 - 参数校验 - 结果解析” 三步:

  • 常用工具类型:API 调用(如传感器数据接口)、代码执行(如 Python 计算能耗)、硬件控制(如 AGV 调度指令);
  • 关键:用 JSON Schema 定义工具参数,避免 LLM 生成无效调用。

工具调用的核心代码(以调用设备 API 为例):

import requests

from jsonschema import validate

# 1. 定义工具 schema(参数校验规则)

api_tool_schema = {

    "type": "object",

    "properties": {

        "url": {"type": "string", "format": "uri"},

        "method": {"type": "string", "enum": ["GET", "POST"]},

        "params": {"type": "object", "additionalProperties": True}

    },

    "required": ["url", "method"]

}

# 2. 工具执行函数

def call_api_tool(tool_params):

    # 先校验参数

    validate(instance=tool_params, schema=api_tool_schema)

    try:

        if tool_params["method"] == "GET":

            response = requests.get(

                tool_params["url"],

                params=tool_params.get("params", {})

            )

        else:

            response = requests.post(

                tool_params["url"],

                json=tool_params.get("params", {})

            )

        return {"status": "success", "data": response.json()}

    except Exception as e:

        return {"status": "fail", "error": str(e)}

# 测试:调用机床功率API

tool_params = {

    "url": "http://device/machineA/power",

    "method": "GET",

    "params": {"time_range": "last_1h"}

}

result = call_api_tool(tool_params)

print(result)  # 输出API返回的功率数据

二、多智能体协作:开发中要解决的 3 个核心问题

单个智能体跑通后,多智能体协作的难点在于 “怎么通信”“怎么分工”“怎么解决冲突”—— 这三点直接决定系统稳定性。

2.1 通信机制:选直接还是间接?

开发中两种通信方式各有适用场景,别盲目跟风分布式。

通信方式

技术方案

代码示例

适合场景

直接消息传递

ZeroMQ(轻量)、gRPC(高并发)

用 ZeroMQ 实现智能体间点对点通信

小规模集群(<50 个智能体)、低延迟需求(如 AGV 协作)

间接协调

Redis 共享缓存、MQ 消息队列

智能体读写 Redis 的 “任务状态” 键值对

大规模集群(>100 个)、网络不稳定(如边缘设备)

直接通信示例(ZeroMQ)

import zmq

# 智能体A(发送方:设备监测智能体)

context = zmq.Context()

socket = context.socket(zmq.PUB)

socket.bind("tcp://*:5555")  # 绑定端口

# 发送故障消息

fault_msg = {

    "from": "device_monitor_agent",

    "to": "maintenance_agent",

    "type": "fault_alert",

    "data": {"machine_id": "A123", "fault": "temperature_high"}

}

socket.send_json(fault_msg)

# 智能体B(接收方:维修智能体)

socket_sub = context.socket(zmq.SUB)

socket_sub.connect("tcp://localhost:5555")

socket_sub.setsockopt_string(zmq.SUBSCRIBE, "fault_alert")  # 订阅故障主题

while True:

    topic, msg = socket_sub.recv_multipart()

    print(f"收到故障:{msg.decode()}")  # 处理故障消息

间接协调示例(Redis)

import redis

import json

r = redis.Redis(host='localhost', port=6379, db=0)

# 智能体1(交通信号智能体)写入车流数据

traffic_data = {

    "intersection_id": "X01",

    "car_count": 25,

    "update_time": "2024-09-20 14:30:00"

}

r.set(f"traffic:{traffic_data['intersection_id']}", json.dumps(traffic_data))

# 智能体2(全局调度智能体)读取车流数据

intersection_ids = ["X01", "X02", "X03"]

for id in intersection_ids:

    data = r.get(f"traffic:{id}")

    if data:

        print(f"路口{id}车流:{json.loads(data)['car_count']}")

2.2 分工策略:别让智能体 “抢活干”

开发中常用 “角色定义 + 任务契约” 模式,参考 MetaGPT 的团队协作思想:

  1. 给每个智能体分配明确角色(如 “数据采集员”“分析师”“执行员”);
  2. 用 “任务契约” 定义谁该做什么(如 “能耗 > 15kW 时,自动触发执行员调整参数”)。

MetaGPT 快速搭建分工示例(需先安装metagpt包):

pip install metagpt

from metagpt.roles import Role, Engineer, ProductManager

from metagpt.team import Team

from metagpt.tasks import Task

# 1. 定义角色(产品经理:提需求;工程师:写代码)

pm = ProductManager()

engineer = Engineer()

# 2. 创建团队

team = Team()

team.add_members([pm, engineer])

# 3. 分配任务(产品经理写需求文档,工程师实现代码)

req_task = Task(

    name="设备能耗监测需求",

    content="写一个监测机床能耗的需求文档,包含数据采集频率和异常阈值",

    assignee=pm

)

code_task = Task(

    name="能耗监测代码",

    content="根据需求文档,写一个Python脚本调用设备API采集能耗",

    assignee=engineer,

    dependencies=[req_task]  # 依赖产品经理的任务结果

)

# 4. 启动团队

team.run_tasks([req_task, code_task])

2.3 冲突解决:避免 “各干各的”

开发中遇到最多的冲突是 “资源竞争”(如两个智能体同时想控制同一台 AGV),两种解决思路:

  • 规则优先:预设优先级(如 “故障维修智能体优先级> 日常调度智能体”);
  • 协商优先:用 “投标机制”(如多个智能体投标抢任务,系统选成本最低的)。

规则优先冲突解决代码:

def resolve_conflict(task, competing_agents):

    # 预设优先级:故障维修>日常调度>数据采集

    priority = {

        "maintenance_agent": 3,

        "scheduler_agent": 2,

        "data_agent": 1

    }

    # 按优先级排序,选最高的

    competing_agents.sort(key=lambda x: priority.get(x.role, 0), reverse=True)

    return f"任务{task}分配给:{competing_agents[0].name}"

# 测试:AGV控制任务冲突

class Agent:

    def __init__(self, name, role):

        self.name = name

        self.role = role

agents = [

    Agent("AGV调度1号", "scheduler_agent"),

    Agent("故障维修1号", "maintenance_agent")

]

print(resolve_conflict("控制AGV-001运输零件", agents))  # 分配给故障维修

三、框架选型与落地踩坑:这些经验能省 3 个月时间

3.1 主流框架怎么选?别只看星标

2024 年多智能体框架各有侧重,开发时要结合场景选,别盲目上 “大而全” 的框架:

框架

核心优势

踩坑点

适合场景

MetaGPT

角色化协作成熟,支持从需求到代码全流程

资源占用高(单机跑 3 个角色就占 2GB 内存)

软件开发、流程自动化(如需求分析→测试用例生成)

CAMEL-AI

社会模拟能力强,工具链丰富

文档少,定制化开发成本高

服务机器人、场景仿真(如餐厅服务员协作)

AWorld

支持大规模智能体进化,容错性好

部署复杂(需搭分布式集群)

智能制造、智慧城市(如 100 + 设备协同)

新手入门建议:先用 MetaGPT 做小项目(如 “智能体协作生成 API 文档”),熟悉分工机制后,再根据场景换框架。

3.2 落地踩坑实录:3 个高频问题的解决方案

坑 1:边缘设备(如 ARM 工业网关)内存不够
  • 问题:单个智能体 + Sidecar 占 500MB 内存,边缘设备只有 1GB;
  • 解决:

from transformers import AutoModelForCausalLM, AutoTokenizer

# 加载量化后的Phi-2(4-bit量化)

model = AutoModelForCausalLM.from_pretrained(

    "microsoft/phi-2",

    load_in_4bit=True,

    device_map="auto"

)

tokenizer = AutoTokenizer.from_pretrained("microsoft/phi-2")

# 生成规划指令(内存占用<500MB)

def mini_planner(goal):

    prompt = f"为目标生成1步行动指令:{goal}\n指令:"

    inputs = tokenizer(prompt, return_tensors="pt").to("cuda")

    outputs = model.generate(**inputs, max_new_tokens=50)

    return tokenizer.decode(outputs[0], skip_special_tokens=True)

    1. 用微型 LLM(如 Phi-2-2.7B,量化后仅占 800MB)替代 GPT-4;
    2. 关闭智能体的 “实时反思” 功能(非核心场景),改为定时反思;
    3. 代码示例(Phi-2 本地化部署):
坑 2:多智能体通信断连(如 4G 网络波动)
  • 问题:边缘智能体与云端断连后,任务执行中断;
  • 解决:

import paho.mqtt.client as mqtt

def on_disconnect(client, userdata, rc):

    if rc != 0:

        print("意外断连,正在重连...")

        client.reconnect()  # 自动重连

client = mqtt.Client()

client.on_disconnect = on_disconnect

client.connect("mqtt.broker.com", 1883, 60)  # 连接 broker

client.loop_forever()  # 保持连接

    1. 本地缓存核心配置(如 “断连时,AGV 默认返回充电站”);
    2. 用 MQTT 协议(支持断连重连)替代 HTTP 通信;
    3. 代码示例(MQTT 断连重连):
坑 3:智能体 “幻觉决策”(如误判设备故障)
  • 问题:LLM 生成错误的故障解决方案,导致设备停机;
  • 解决:
    1. 给规划系统加 “事实校验” 步骤(调用设备历史故障数据库);
    2. 关键决策需人工确认(如 “停机维修” 类操作,发送告警给运维人员);

四、开放性问题:等你来分享经验

  1. 用 MetaGPT 开发多智能体时,有没有遇到 “角色间任务依赖死锁”(如 A 等 B 的结果,B 等 A 的结果)?你是怎么设计任务依赖关系的?
  2. 在 ARMv7 架构的低端边缘设备上,用微型 LLM(如 Phi-2)做智能体决策时,推理速度能到多少?有没有进一步优化的技巧(如模型剪枝)?
  3. 多智能体系统中,怎么实现 “动态角色调整”(如某个智能体故障后,其他智能体自动接管其任务)?有没有成熟的中间件推荐?

结语

多智能体开发不是 “堆智能体数量”,而是 “精准分工 + 高效协作”。从单个智能体的 “规划 - 记忆 - 工具” 落地,到多智能体的通信与冲突解决,每一步都要结合场景做取舍 —— 比如边缘场景别追求全功能,稳定优先;工业场景别忽视安全,关键操作加校验。

希望本文的代码示例和踩坑经验能帮你快速上手,也期待在评论区看到你的实战分享!如果有具体场景的技术难题,也可以提出来一起讨论~

(注:文档部分内容由 AI 生成)

http://www.dtcms.com/a/394380.html

相关文章:

  • [优选算法专题三二分查找——NO.17二分查找]
  • 一文学会c++哈希
  • 【06】EPGF 架构搭建教程之 本地环境管理工具的本地化
  • 【开发实践】DNS 报文分析与 CDN 架构可视化方案
  • Ubuntu 系统下 Nginx + PHP 环境搭建教程
  • AI 如何改变日常生活
  • 字典树 Trie 介绍、实现、封装与模拟 C++STL 设计
  • 第一性原理(First Principles Thinking)
  • 1.UE-准备环境(一)-账号注册和打开虚幻引擎源码页面
  • javascript `AbortController`
  • 时间复杂度与空间复杂度
  • rocketmq队列和消费者关系
  • RAG评估指南:从核心指标到开源框架,打造高效检索生成系统
  • xtuoj 0x05-A 前缀和
  • 防误删 (实时) 文件备份系统 (btrfs 快照 + rsync)
  • 【FreeRTOS】第七课(1):任务间通信(使用队列)
  • OD C卷 - 二叉树计算
  • DiffDock 环境安装和使用教程
  • NVIC中的不可屏蔽中断NMI(Non-Maskable Interrupt)是什么?
  • TypeORM 浅析
  • 2.4 死锁 (答案见原书 P165)
  • 算法与数据结构:常见笔试题总结
  • trae使用playwright MCP方法流程
  • anaconda安装tensorflow遇到的一个错误
  • 不同浏览器对 http.server 提供MP4 文件支持差异分析
  • Python 实战:内网渗透中的信息收集自动化脚本(10)
  • leetcode 206 反转链表
  • AI智能的网站SEO优化服务商
  • 生产者客户端
  • Puppeteer 在爬取电商 JavaScript 页面的使用