手 把 手 做 多 智 能 体 系 统 !

一意AI 一意AI增效家 2024年11月04日 20:37

hi~

上一篇,雄哥做了:

把GraphRAG当工具接入Agent的示例!

智能体自主决策何时查知识图谱数据,让KG始终支撑Agent干活!

实际,Agent支持接入任何数据库/外部工具,沿本方向跑,可拓展无数实践!

但这,只是在整个MAS(多智能体系统)中,最简单示例!

函数生成+执行=执行决策+获取信息动作!

还,干不了复杂任务!

因为:MAS远远不止函数调用

那,究竟什么是多智能体系统?如何做?

今天,跟着雄哥动手做一个“五脏俱全”的多智能体系统!

同时!

这也是MAS系列的补充,接下来几个月时间,雄哥也会在Agent领域,动手做实践!

一边动手一边学技能点!

未看之前内容?

MAS | 什么是多智能体系统 MAS?

图片

简单来说就是:目标分解、计划、协调、共享记忆、反馈感知、执行...!

许多朋友可能已经看过很多这样介绍!后面雄哥用代码说明;

这好比:

在公司,项目经理,将复杂项目(比如写代码/写报告/洗数据..)拆分为较小任务,分配不同专业员工,去执行,回收结果,持续优化,达成目标!

沿着这条线,继续深入!

雄哥准备了这些内容,理论+代码:

① 巅峰的Agent有哪些关键组件?

② 细拆!MAS(多智能体系统)是怎样工作的?

③ 动手跑代码!边跑边聊细节!实现Agent+MAS!


以上,学完需1小时左右!

你一定要花一个下班时间,老实坐在电脑前,动手做!才能学会!

否则只是泛泛之识,恐怕吸收不到!

除了这些,雄哥已围绕大模型,做过微调、数据预处理、RAG0-1、知识图谱、Agent等内容了!

成为【意友圈】会员,全部系统地学一次!能帮你提速至少90天!

许多会员,都在社区,保持自己的项目,始终在正途发展的!

识别下方二维码即可加入

图片

人的专注力只有10分钟,那,话不多说,开始今天内容!


第一部分:有哪些关键组件?如何工作?


AI Agent的核心,是由大型语言模型(LLM)驱动支持的实例。

至于什么是Agent,这样的知识,雄哥之前分享过无数次,默认你学过;

它将复杂的任务分解为可管理的步骤,使用各种工具来完成这些步骤,并学习经验,然后计划、推理、评估监管和采取行动,实现目标。

这就区别于当下市面大部分的LLM服务!

绝大部分的交互还知识chat对话,不具备复杂任务能力!

少部分产品,也仅仅做到单Agent+单线程驱动,确保尽可能安全可控情况下:

智能体  都在--> 多智能体系统 

图片

今天,跟着雄哥,把MAS拆开,把5个关键组件拎出来!

即:

组件描述
LLM(大脑)代理的核心,负责文本处理、理解上下文并做出决策。
规划将目标分解为一系列可管理任务,按优先级排序并根据新信息调整计划。
行动使用工具和API与环境交互,执行如搜索、代码执行、数据访问等任务。
评估与监督定义代理的行为、个性、沟通风格、专业化,确保响应符合预期目标。
记忆存储和回忆过往交互,保持对话上下文,支持个性化和长期学习。


1.1 LLM(大脑)

代理的核心,负责文本处理、理解上下文并做出决策。

MAS系统中,每一个LLM都是各司其职,1个LLM=1个人

1个财务岗,他可以处理销售部的任务,当然也可以处理开发部的任务;

所以整个系统是并行多线程的,从不是单个Agent就能干完这些事

那如何能让一个Agent,掌握胜任“财务岗”的能力呢?

这里有两种方法:

1(明文提示)-是手把手教,把工作过程一步步写出来,照葫芦画瓢

2(微调训练)-是把知识真正从0学到1

后面雄哥会基于这两种方法,独立做一个系列,如何合成数据、如何微调、如何评估等,关注雄哥!

下面提到的规划、行动、评估、记忆,都离不开多个LLM来完成;


1.2 规划

代理的关键能力之一,是其规划能力。

此组件允许代理将复杂的目标,分解为一系列可管理的任务,规划模块能够:

#A 分析给定目标

#B 确定实现目标的必要步骤

#C 按逻辑顺序确定这些步骤的优先级

#D 根据获取的结果调整计划

有效规划=有效解决问题

尤其是复杂的多步骤问题,这里,简单做个生成式 AI 任务:

{  "task""使用AI代理生成医疗建议",  "planning": {    "inputs": {      "user_preferences": [        "主题",         "关键词",         "语气"       ],      "trending_data""获取用户偏好的内容"    },    "workflow": [      {        "step": "收集输入",        "description": "收集用户偏好和热门数据",        "actions": [          "请求用户输入(例如,主题、关键词、语气)",          "从API获取话题和标签"        ]      },      {        "step": "生成推文",        "description": "根据输入和趋势创建推文",        "actions": [          "使用AI模型生成不超过280个字符的健康贴士",          "结合用户偏好和热门数据以提高相关性"        ]      },      {        "step": "优化参与度",        "description": "增强内容以提高参与度",        "actions": [          "添加相关标签和提及",          "调整语气和内容以实现最大参与度"        ]      },      {        "step": "验证内容",        "description": "确保推文符合指导原则",        "actions": [          "检查字符数和格式",          "确保内容符合平台的规则和社区原则"        ]      },      {        "step": "发布内容",        "description": "代表用户发布推文",        "actions": [          "使用API发布",          "确认内容已成功发布"        ]      },      {        "step": "反馈循环",        "description": "收集反馈并改进",        "actions": [          "监控推文参与度(点赞、转发、评论)",          "根据性能数据和用户反馈调整AI模型"        ]      }    ]  }}

后面,雄哥还有更深入内容,以构建它!


1.3 行动-函数调用

Agent执行任务,可以是一组数据库查询/写入,或者某组函数的执行,然后获取结果,反馈给Agent更新下一步的策略,相当于一个人的手手脚脚;

天黑,脚踩水了,肯定就不要再往前了;

这里我们,通常涉及使用各种工具或 API,后面雄哥会专门开一个系列,如何做函数调用,如何评估性能,如何提升tools触达率等;

最简单的实例,是这样的:

## API发布推文{  "endpoint": "/api/post",  "method": "POST",  "description": "将生成的推文发布到小红书。",  "request": {    "body": {      "id": "字符串",      "user_id": "字符串",      "token": "字符串"    }  },  "response": {    "status": 200,    "body": {      "message": "推文发布成功。",      "post_id": "字符串"    }  }}## API获取数据{  "endpoint": "/api/trending",  "method": "GET",  "description""从小红书获取热门话题和标签。",  "request": {    "query_parameters": {      "location": "字符串",      "limit": "数字"    }  },  "response": {    "status": 200,    "body": {      "trending_topics": [        {          "hashtag": "#示例",          "volume": 10000        }      ]    }  }}

这段代码定义了两个API接口:

# 第一个接口

是用来发布推文的,客户端通过POST请求发送推文的ID、用户ID和OAuth令牌,成功后会返回发布成功的消息和推文ID。

# 第二个接口

用于获取热门话题和标签,客户端通过GET请求传递位置和限制数量,成功后返回热门话题列表及其相关的推文量。

系统执行层

当收到了雄哥的交互的时候,他会自动运行,并且执行操作,大概过程是这样的,雄哥发送:

“我想从小红书上获取一些关于人工智能的热门话题,并且发布这条推文到小红书,标题:一意AI今天上市敲钟了!”

系统收到信息后,背后的操作是这样的:

## 使用包含参数的API进行调用{  "endpoint": "/api/trending",  "method": "GET",  "parameters": {    "location""全球",  // 或者特定位置,如"中国",以缩小范围    "limit": 10  // 要检索的热门话题数量  },  "response": {    "status": 200,    "body": {      "trending_topics": [        {          "hashtag": "#人工智能示例1",          "volume": 25000        },        {          "hashtag": "#人工智能示例2",          "volume": 18000        }        // 更多热门话题...      ]    }  }}
## 使用包含参数的POST推文API进行调用{ "endpoint": "/api/post", "method": "POST", "body": { "text": "一意今天上市敲钟了!", "user_id": "你的用户ID", // 用户或应用的唯一ID    "token""你的用户token"  // 用于API认证的令牌 }, "response": { "status": 200, "body": { "message": "推文发布成功。", "post_id": "123456789" } }}

tools使用上,可以定义任何的操作,包括现实环境(拥抱/机器人动作/环境操作)的交,在一意慢病管理项目中,是非常重要模块,后面雄哥会展开这个系列;

1.4 评估与监督

这是一个由上至下的行动指南,多agent的编排,在名义的结构上,还需要对不同层次Agent做规范,定义了其行为、个性和特定功能。

包括:

#A 角色或专业化(如:健康管理师、数据分析师等)

#B 语气和沟通风格

#C道德准则和约束

#D 特定知识领域或专业领域的技能

一句话说完了,但是做好这个版块,一点都不容易,首先我们需要做一个高效的管理架构,然后对这个架构的Agent,做不同程度的管理。

图片

雄哥前几天看到一个国外项目,这是一个Agent世界文明的构建指南,颇为震撼60小时,完成一个超大型的多智能体的复杂文明构建,这是非常非常困难的事,中华文明形成用了上千年人工智能时代,仅60小时;

1.5 记忆

记忆是Agent存储和调用过去交互的信息,主要作用:

#A 在正在进行的任务中保持上下文(不是无限记忆,只记重要的)

#B 从以前的经验中学习

#C 随着时间的推移总结提升能力

#D 根据用户历史记录提供个性化响应

#E 多个Agent间根据架构分配信息

记忆可以是短期的(在单个对话的持续时间内)或长期的(在多个交互中持续存在),这里最难做的是:记忆的规则。

在单个任务或Agent中,是比较容易实现的,但MAS中,是多Agent的协调,这时,下游的Agent需要上游的任务入口,提供有效的信息;

注意,是有效的信息!

代表了部分,不是所有的信息都能共享的,需要一套完备的信息管理系统。

就像一个公司,销售部,是不需要知道公司内部的财务盈亏信息的;

一个完整的MAS系统,需要大量的工作,许多技术当下的实现还是0,这才是AI时代,真正的机会,都需要你,一步步实现,所有人,都有机会;

图片

接下来,跟着雄哥,在已有的技术基础上,在本地搭建一个MAS吧!

这不是最终版,这是跑通,学习用途,生产的话,需要做的路更长!

而且,这是一个产品的核心和优势差异;


第二部分:跑起来!边跑边聊代码!


本次,跟着雄哥完成Agent的关键组件,涵盖:

1. 反思

2.工具使用

3.规划(任务分配)

4.多代理协作

任务是:生成平均气温图表,通过多个agnet调用函数收集数据、生成表格,然后返回到LLM,返回结果给用户,如下图:

图片

最终实现,Agent分析任务,然后把任务拆解,分别给不同的Agent去完成任务,我们的最终输出是让Agent生成代码,做表格+总结输出:

图片

背后干了几件事:

任务:获取过去1年中国广东的GDP并绘制一张图表

动作一:收集过去1年广东的GDP数据(Agent 1)

图片

动作二:总结收到的数据(Agent 2)

图片

动作三:根据数据生成创建图表的代码(Agent 3)

图片

动作四:根据图表和数据做最终回复(Agent 4)


雄哥会把这些组件拆开,组成一个MAS(简易版),实践的环境,如下:

操作系统:无要求,雄哥win11

代码环境:minidonda、jupyter

大模型:openai api(当然可以本地啦)

Agent框架:LangChain、 CrewAI

需要你在本地搭建好AI环境,还未搭建,在这里快速搭建!

第四天!0基础微调大模型+知识库,部署在微信!手把手安装AI必备环境!4/45

所有的实践代码,都已经上传到会员盘(百度),如果你还不是会员,在末尾联系工程师,即可申请加入,加入后就能看到代码,也可以直接找到雄哥;

图片


创建conda环境!

指定mas名称,3.10的Python版本,注意,每一个实践,你都应该是独立的环境,否则容易有依赖版本冲突;

习惯用其他的环境管理工具?怎么顺手怎么来!

新手跟着雄哥走即可!打开conda窗口,输入:

conda create --name mas python=3.10


激活进入mas环境!

conda activate mas


cd进入代码目录

这里要进入你放代码的目录,雄哥放在F:\mas,方便后面打开;

cd F:\mas


安装jupyter

这是一个交互式的工具,可以看到每一行代码的执行结果!

conda install jupyter

图片


进入jupyter环境!

输入以下指令,他会自动跳转到浏览器

jupyter notebook


双击打开代码!

图片


现在开始,正式进入代码环节,这里,雄哥会拿一些核心的代码出来,演示他背后的重要节点,是怎样做的。


添加共享记忆!

agent_executor = create_react_agent(model, tools, checkpointer=memory)
config = {"configurable": {"thread_id""123"}}
for chunk in agent_executor.stream( {"messages": [HumanMessage(content="我是一意AI,一个长期专注AI工程师培养、AI技术支撑、降本增效,始终陪伴伙伴持续成长的学习平台")]}, config): print(chunk) print("----")

测试是否成功,问:我是谁?

回答:

你好,很高兴认识你,一意AI。我会尽我所能为你提供帮助。你有什么问题或者需要我做什么吗?

图片

创建Agent的函数和提示词!

def create_agent(llm, tools, system_message: str):    """Create an agent."""    prompt = ChatPromptTemplate.from_messages(        [            (                "system",                " 你是一个有帮助的AI助手,与其他助手协作."                " 使用提供的工具来推动回答问题."                " 如果你无法完全回答,也没关系,其他具有不同工具的助手会接着你未完成的部分进行帮助."                " 尽你所能地执行,以取得进展."                " 如果你或其他助手有最终答案或交付成果,请在你的回应前加上[最终答案]."                " 这样团队就知道可以停止了."                " 你可以使用以下工具: {tool_names}.\n{system_message}",            ),            MessagesPlaceholder(variable_name="messages"),        ]    )    prompt = prompt.partial(system_message=system_message)    prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))    return prompt | llm.bind_tools(tools)

定义了create_agent 的函数,用于创建一个AI助手

该函数接受三个参数:llm、tools、system_message

函数的主要作用是:使用 ChatPromptTemplate.from_messages 创建一个提示模板,这个模板包含了系统信息和消息占位符。

系统信息部分定义了AI助手的行为准则,包括与其他助手协作、使用提供的工具来回答问题,并在找到最终答案时在回应前加上特定的标记。

将系统消息和工具名称动态地插入到提示模板中。


创建tool!

注意啊,这个tool是可以直接生成代码+执行代码,可能会搞坏你本地环境,注意使用!不要搞花哨操作!

@tooldef python_repl(    code: Annotated[str, "生成图表的Python代码."],):    """如果你想要查看一个值的输出,使用这个来执行Python代码    你应该使用 print(...) 将其打印出来。这是用户可见的."""    try:        result = repl.run(code)    except BaseException as e:        return f"Failed to execute. Error: {repr(e)}"    result_str = f"Successfully executed:\n```python\n{code}\n```\nStdout: {result}"    return (        result_str + "\n\nIf 你已经完成了所有任务,合成最终答案.")

这里是告诉Agent,可以直接生成Python代码,并且执行,生成图表;


创建Agent状态的数据结构!

class AgentState(TypedDict):    messages: Annotated[Sequence[BaseMessage], operator.add]    sender: str

定义 AgentState 的类型字典类,继承自 TypedDict。

TypedDict 是一个在Python中用于类型注解的特殊类型,用户可定义字典的键及其对应的类型。

在 AgentState 类中,定义了两个键:

messages:这是一个键,其值被注解为 Sequence[BaseMessage],并且使用了 operator.add 作为额外的注解。这表示 messages 键的值应该是一个 BaseMessage 对象的序列(比如列表或元组),并且暗示了可能会对这个序列使用加法操作(例如,将两个消息序列合并)。

sender:这是一个键,其值被注解为 str,表示 sender 键的值应该是一个字符串,用于表示消息的发送者。


定义Agent!

# 数据采集agentresearch_agent = create_agent(    llm,    [tavily_tool],    system_message="你应该为 chart_generator 提供准确的数据以供使用.",)research_node = functools.partial(agent_node, agent=research_agent, name="Researcher")# 图表生成agentchart_agent = create_agent(    llm,    [python_repl],    system_message="你展示的任何图表都将被用户看到.",)chart_node = functools.partial(agent_node, agent=chart_agent, name="chart_generator")


定义边和创建逻辑!

# 任何一个代理都可以决定结束from typing import Literal
def router(state) -> Literal["call_tool", "__end__", "continue"]: # 路由 messages = state["messages"] last_message = messages[-1] if last_message.tool_calls: # 前一个代理正在调用一个工具 return "call_tool" if "FINAL ANSWER" in last_message.content: # 任何代理都决定工作已经完成 return "__end__" return "continue"

任务是否完成,现在执行的状态如何,非常重要!

如果上一个代理正在调用一个工具(绑定到代理的 llm),那么它会将状态更新为"call_tool"

如果上一个代理没有"call_tool",建议它更新状态:已完成其工作并且最终答案已准备就绪,则会将状态更新为 END

否则,它将更新 state 以继续


好啦!

现在开始输入一个任务!

events = graph.stream(    {        "messages": [            HumanMessage(                content="获取过去1年中国广东的GDP并绘制一张示意图"            )        ],    },    # M在图中要采取的最大步骤数    {"recursion_limit": 150},)for s in events:    print(s)    print("----")

你就可以看到下图的输出过程了

图片


接下来就会专门做Agent内容,发展飞快,一些价值的进展都想分享给你!

如果你想加群,或者付费成为会员,都可以在这里联系到雄哥的工程师-小胖!