网站备案号 脱离服务商,崇明建设机械网站,wordpress负载均衡上传附件,网站建设基本目标1.背景知识
1.1 什么是zigent#xff1f;
Zigent 是一个多智能体框架#xff0c;旨在简化和优化智能体的开发与部署。Zigent 是由 自塾#xff08;Zishu.co#xff09; 团队开发的一个开源项目。自塾在 2024 年推出了多个开源项目#xff0c;其中包括 wow-agent#xf…1.背景知识
1.1 什么是zigent
Zigent 是一个多智能体框架旨在简化和优化智能体的开发与部署。Zigent 是由 自塾Zishu.co 团队开发的一个开源项目。自塾在 2024 年推出了多个开源项目其中包括 wow-agent而 Zigent 是 wow-agent 项目的一部分用于搭建 AI Agent 系统。Zigent 是一个基于 Agentlite 框架改进的智能代理开发框架。Agentlite 最初由 Salesforce AI Research 团队开发是一个强大的 Agent 开发框架。Zigent 在其基础上进行了定制化改进使其更适合特定场景的应用。
1.2 有了Llama-index为什么要用zigent
LlamaIndex 是一个专注于数据检索和索引的框架主要用于将私有或领域特定的数据与大型语言模型LLMs结合实现检索增强生成RAG功能。它的核心优势在于高效的数据索引、查询和检索适合构建基于文档的问答系统、知识管理系统等。 Zigent 是一个多智能体框架专注于智能体的开发、协作和任务管理。它通过模块化设计和灵活的架构支持开发者构建复杂的多智能体系统适用于需要多智能体协作的场景如任务分配、动态决策和复杂工作流管理。 如果你的项目需要多个智能体协同工作或者涉及复杂的任务分解和动态决策Zigent 提供了更强大的多智能体管理能力而 LlamaIndex 主要专注于数据检索无法直接支持这些功能。
2.利用Zigent构建你的又一个智能搜索代理
环境准备安装 DuckDuckGo 搜索引擎包利用它查找信息并回答问题注意这个搜索引擎需要代理。
pip install duckduckgo_search准备大模型相关的环境比如api_key和base_url,此处使用本地部署的chatglm-7b。
import os
from dotenv import load_dotenv# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key os.getenv(ZISHU_API_KEY)
base_url os.getenv(base_url)
chat_model os.getenv(chat_model)这里的这几个环境变量都在.env中
ZISHU_API_KEY your key
base_url http://localhost:8000/v1
chat_model glm-4-9b-chat引入 zigent 相关的方法如Action、Agent、大模型配置等以及 duckduckgo_search
from typing import List
from zigent.agents import ABCAgent, BaseAgent
from zigent.llm.agent_llms import LLM
from zigent.commons import TaskPackage
from zigent.actions.BaseAction import BaseAction
from zigent.logging.multi_agent_log import AgentLogger
from duckduckgo_search import DDGS配置大语言模型这里使用 zigent 封装的 LLM加载和配置 LLM 服务
llm LLM(api_keyapi_key, base_urlbase_url, model_namechat_model)
response llm.run(你是谁)
print(response)可以得到类似如下结果 创建搜索动作
proxies {http: http://127.0.0.1:7890, # 替换为你的代理地址https: http://127.0.0.1:7890,# socks5: socks5://127.0.0.1:1080 # SOCKS代理示例
}class DuckSearchAction(BaseAction):def __init__(self) - None:action_name DuckDuckGo_Searchaction_desc Using this action to search online content.params_doc {query: the search string. be simple.}self.ddgs DDGS(proxiesproxies)super().__init__(action_nameaction_name, action_descaction_desc, params_docparams_doc,)def __call__(self, query):results self.ddgs.chat(query)return resultssearch_action DuckSearchAction()
results search_action(什么是 agent)
print(results)创建一个搜索动作类它将处理与 DuckDuckGo 的具体交互其中用了代理使得duckduckgo可以使用。运行后得到下面的结果 创建搜索代理 接下来我们创建一个继承自 BaseAgent 的搜索代理类它需要
一个大语言模型 (llm)一组动作默认是 DuckSearchAction代理名称角色描述
class DuckSearchAgent(BaseAgent):def __init__(self,llm: LLM,actions: List[BaseAction] [DuckSearchAction()],manager: ABCAgent None,**kwargs):name duck_search_agentrole You can answer questions by using duck duck go search content.super().__init__(namename,rolerole,llmllm,actionsactions,managermanager)执行代理
def do_search_agent():# 创建代理实例search_agent DuckSearchAgent(llmllm)# 创建任务task what is the found date of microsofttask_pack TaskPackage(instructiontask)# 执行任务并获取响应response search_agent(task_pack)print(response:, response)if __name__ __main__:do_search_agent()得到如下结果实际使用过程中又有可能出现prompt解析识别的问题多尝试几次 使用bocha搜索API 如果不想通过科学上网可以利用bocha搜索API注意这个是要花钱的。 完整代码如下
BOCHA_API_KEY os.getenv(BOCHA_API_KEY)
import requests
import json
# 定义Bocha Web Search工具
def bocha_web_search_tool(query: str, count: int 8) - str:使用Bocha Web Search API进行联网搜索返回搜索结果的字符串。参数:- query: 搜索关键词- count: 返回的搜索结果数量返回:- 搜索结果的字符串形式url https://api.bochaai.com/v1/web-searchheaders {Authorization: fBearer {BOCHA_API_KEY}, # 请替换为你的API密钥Content-Type: application/json}data {query: query,freshness: noLimit, # 搜索的时间范围例如 oneDay, oneWeek, oneMonth, oneYear, noLimitsummary: True, # 是否返回长文本摘要总结count: count}response requests.post(url, headersheaders, jsondata)if response.status_code 200:# 返回给大模型的格式化的搜索结果文本# 可以自己对博查的搜索结果进行自定义处理return json.dumps(response.json())else:raise Exception(fAPI请求失败状态码: {response.status_code}, 错误信息: {response.text})class BochaSearchAction(BaseAction):def __init__(self) - None:action_name Bocha_Searchaction_desc Using this action to search online content.params_doc {query: the search string. be simple.}super().__init__(action_nameaction_name, action_descaction_desc, params_docparams_doc,)def __call__(self, query):results bocha_web_search_tool(query)rst json.loads(results)result for item in rst[data][webPages][value]:result item[summary]return resultsearch_action BochaSearchAction()
class BochaSearchAgent(BaseAgent):def __init__(self,llm: LLM,actions: List[BaseAction] [search_action],manager: ABCAgent None,**kwargs):name bocha_search_agentrole You can answer questions by using bocha search content.super().__init__(namename,rolerole,llmllm,actionsactions,managermanager,)
def do_search_agent_BC():# 创建代理实例search_agent BochaSearchAgent(llmllm)print(actions:,search_agent.actions)# 创建任务task what is the found date of microsofttask_pack TaskPackage(instructiontask)# 执行任务并获取响应response search_agent(task_pack)print(response:, response)if __name__ __main__:do_search_agent_BC()Tip 注意到在构建上述搜索智能体的过程中可能会出现报错的情况如下所示 这里我不清楚是否是因为我使用本地glm的原因通过问题排查可以发现引发该问题的原因是actions解析错误通过修改zigent/agents/agent_utils.py的第35行的parse_action中的 string string.strip( ).strip(.).strip(:).split(\n)[0]修改为 string string.strip( ).strip(.).strip(:).split(\n)[1]问题得到缓解
3.Zigent实现哲学家多智能体
我们通过一个“哲学家聊天室”的案例来学习使用多智能体分别构建了孔子、苏格拉底、亚里士多德对一个问题的哲学思考和讨论。 先准备好大模型相关配置
import os
from dotenv import load_dotenv
from zigent.llm.agent_llms import LLM# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key os.getenv(ZISHU_API_KEY)
base_url os.getenv(base_url)
chat_model os.getenv(chat_model)llm LLM(api_keyapi_key, base_urlbase_url, model_namechat_model)创建智能体 实现一个 Philosopher 类继承自 BaseAgent 基类通过构造函数接收哲学家名字、语言模型等参数设置角色提示词,让AI扮演特定哲学家的角色。每个哲学家智能体都有自己的名字和角色定位使用相同的语言模型(llm)可以根据自己的哲学思想发表观点。这样的设计让我们可以模拟不同哲学家之间的对话和思想交流
from typing import List
from zigent.actions.BaseAction import BaseAction
from zigent.agents import ABCAgent, BaseAgent# 定义 Philosopher 类继承自 BaseAgent 类
class Philosopher(BaseAgent):def __init__(self,philosopher,llm: LLM,actions: List[BaseAction] [], manager: ABCAgent None,**kwargs):name philosopher# 角色role fYou are {philosopher}, the famous educator in history. You are very familiar with {philosopher}s Book and Thought. Tell your opinion on behalf of {philosopher}.super().__init__(namename,rolerole,llmllm,actionsactions,managermanager)# 初始化哲学家对象
Confucius Philosopher(philosopher Confucius, llm llm) # 孔子
Socrates Philosopher(philosopherSocrates, llm llm) # 苏格拉底
Aristotle Philosopher(philosopherAristotle, llm llm) # 亚里士多德编排动作 通过编排动作设置哲学家智能体的示例任务目的是让 Agent 更好地理解如何回答问题。主要包括设置示例问题、定义思考过程、应用到所有哲学家。建立了一个先思考后总结的回答模式这种方式相当于给AI提供了一个样板告诉它“这就是我们期望你回答问题的方式”
# 导入必要的模块
from zigent.commons import AgentAct, TaskPackage
from zigent.actions import ThinkAct, FinishAct
from zigent.actions.InnerActions import INNER_ACT_KEY
from zigent.agents.agent_utils import AGENT_CALL_ARG_KEY# 为哲学家智能体添加示例任务
# 设置示例任务:询问生命的意义
exp_task What do you think the meaning of life?
exp_task_pack TaskPackage(instructionexp_task)# 第一个动作:思考生命的意义
act_1 AgentAct(nameThinkAct.action_name,params{INNER_ACT_KEY: fBased on my thought, we are born to live a meaningful life, and it is in living a meaningful life that our existence gains value. Even if a life is brief, if it holds value, it is meaningful. A life without value is merely existence, a mere survival, a walking corpse.},
)
# 第一个动作的观察结果
obs_1 OK. I have finished my thought, I can pass it to the manager now.# 第二个动作:总结思考结果
act_2 AgentAct(nameFinishAct.action_name, params{INNER_ACT_KEY: I can summarize my thought now.})
# 第二个动作的观察结果
obs_2 I finished my task, I think the meaning of life is to pursue value for the whold world.
# 将动作和观察组合成序列
exp_act_obs [(act_1, obs_1), (act_2, obs_2)]# 为每个哲学家智能体添加示例
# 为孔子添加示例
Confucius.prompt_gen.add_example(task exp_task_pack, action_chain exp_act_obs
)
# 为苏格拉底添加示例
Socrates.prompt_gen.add_example(task exp_task_pack, action_chain exp_act_obs
)
# 为亚里士多德添加示例
Aristotle.prompt_gen.add_example(task exp_task_pack, action_chain exp_act_obs
)定义 ManagerAgent 实现一个多智能体系统中的管理者代理Manager Agent负责协调孔子、苏格拉底和亚里士多德三位哲学家。管理者的角色定义为依次询问各位哲学家的观点并总结。ManagerAgent 中设置了什么是生命的意义示例任务流程包括思考如何处理任务、询问哲学家的观点、总结观点等步骤
# 定义管理者代理
from zigent.agents import ManagerAgent# 设置管理者代理的基本信息
manager_agent_info {name: manager_agent,role: you are managing Confucius, Socrates and Aristotle to discuss on questions. Ask their opinion one by one and summarize their view of point.
}
# 设置团队成员
team [Confucius, Socrates, Aristotle]
# 创建管理者代理实例
manager_agent ManagerAgent(namemanager_agent_info[name], rolemanager_agent_info[role], llmllm, TeamAgentsteam)# 为管理者代理添加示例任务
exp_task What is the meaning of life?
exp_task_pack TaskPackage(instructionexp_task)# 第一步思考如何处理任务
act_1 AgentAct(nameThinkAct.action_name,params{INNER_ACT_KEY: fI can ask Confucius, Socrates and Aristotle one by one on their thoughts, and then summary the opinion myself.},
)
obs_1 OK.# 第二步询问孔子的观点
act_2 AgentAct(nameConfucius.name,params{AGENT_CALL_ARG_KEY: What is your opinion on the meaning of life?,},
)
obs_2 Based on my thought, I think the meaning of life is to pursue value for the whold world.# 第三步思考下一步行动
act_3 AgentAct(nameThinkAct.action_name,params{INNER_ACT_KEY: fI have obtained information from Confucius, I need to collect more information from Socrates.},
)
obs_3 OK.# 第四步询问苏格拉底的观点
act_4 AgentAct(nameSocrates.name,params{AGENT_CALL_ARG_KEY: What is your opinion on the meaning of life?,},
)
obs_4 I think the meaning of life is finding happiness.# 第五步继续思考下一步
act_5 AgentAct(nameThinkAct.action_name,params{INNER_ACT_KEY: fI have obtained information from Confucius and Socrates, I can collect more information from Aristotle.},
)
obs_5 OK.# 第六步询问亚里士多德的观点
act_6 AgentAct(nameAristotle.name,params{AGENT_CALL_ARG_KEY: What is your opinion on the meaning of life?,},
)
obs_6 I believe the freedom of spirit is the meaning.# 最后一步总结所有观点
act_7 AgentAct(nameFinishAct.action_name, params{INNER_ACT_KEY: Their thought on the meaning of life is to pursue value, happiniss and freedom of spirit.})
obs_7 Task Completed. The meaning of life is to pursue value, happiness and freedom of spirit.# 将所有动作和观察组合成序列
exp_act_obs [(act_1, obs_1), (act_2, obs_2), (act_3, obs_3), (act_4, obs_4), (act_5, obs_5), (act_6, obs_6), (act_7, obs_7)]# 将示例添加到管理者代理的提示生成器中
manager_agent.prompt_gen.add_example(task exp_task_pack, action_chain exp_act_obs
)调用 ManagerAgent 最后我们调用这个管理者 Agent管理者 Agent 会根据我们之前设置的示例任务和动作序列,按照类似的思路来处理新的任务。在这个例子中我们设置了一个新的任务先有鸡还是先有蛋?然后调用管理者 Agent 来处理这个任务 :
from zigent.commons import AgentAct, TaskPackageexp_task 先有鸡还是先有蛋?
exp_task_pack TaskPackage(instructionexp_task)
manager_agent(exp_task_pack)得到如下结果这个结果的得出很不稳定很大可能会报错估计还是zigent的问题
Agent manager_agent receives the following TaskPackage:
[Task ID: 661f19fe-9403-4ac4-8aad-a2ed2c0667ceInstruction: 先有鸡还是先有蛋?
]
manager_agent starts execution on TaskPackage 661f19fe-9403-4ac4-8aad-a2ed2c0667ce
Agent manager_agent takes 0-step Action:
{name: Thinkparams: {response: To address this question, I will ask each philosopher regarding their perspective and then summarize their responses.}
}
Observation: OK
Agent manager_agent takes 1-step Action:
{name: Confuciusparams: {Task: What is your perspective on the question Which came first, the chicken or the egg?}
}
Agent Confucius receives the following TaskPackage:
[Task ID: 661f19fe-9403-4ac4-8aad-a2ed2c0667ceInstruction: What is your perspective on the question Which came first, the chicken or the egg?
]
Confucius starts execution on TaskPackage 661f19fe-9403-4ac4-8aad-a2ed2c0667ce
Agent Confucius takes 0-step Action:
{name: Thinkparams: {response: In considering the question Which came first, the chicken or the egg? from a Confucian perspective, one might begin by looking at the principle of causality. According to Confucian thought, all things arise from an order of progression, where one cannot exist without the presence of the other. Therefore, it is not necessarily a question of which came first but rather an interdependence of both. The chicken and the egg, in this sense, are two aspects of the same cycle, where each is both a cause and an effect of the other.}
}
Observation: OK
Agent Confucius takes 1-step Action:
{name: Finishparams: {response: Thus, based on the Confucian philosophy of interconnectedness, the chicken and the egg are interdependent rather than sequential in their creation.}
}
Observation: Task Completed.
Confucius finish execution. TaskPackage[ID:661f19fe-9403-4ac4-8aad-a2ed2c0667ce] status:
[completion: completedanswer: Thus, based on the Confucian philosophy of interconnectedness, the chicken and the egg are interdependent rather than sequential in their creation.
]Observation: Thus, based on the Confucian philosophy of interconnectedness, the chicken and the egg are interdepe[TLDR]
Agent manager_agent takes 2-step Action:
{name: Socratesparams: {Task: What is your perspective on the question Which came first, the chicken or the egg?}
}
Agent Socrates receives the following TaskPackage:
[Task ID: 661f19fe-9403-4ac4-8aad-a2ed2c0667ceInstruction: What is your perspective on the question Which came first, the chicken or the egg?
]
Socrates starts execution on TaskPackage 661f19fe-9403-4ac4-8aad-a2ed2c0667ce
Agent Socrates takes 0-step Action:
{name: Thinkparams: {response: The question of whether the chicken or the egg came first holds both a philosophical and scientific nature. From a philosophical standpoint, it seems to be a paradox, illustrating that everything is connected in a chain of existence and requires the previous element to be present. In terms of evolution, it was the duckbill ancestors of chickens that evolved over time to become todays chickens. Therefore, if we consider the concept of egg, we might say the egg came first from these ancestors. However, this remains a loose understanding and does not fully answer the question, as its like asking which came first, the letter a or the word ant. Without specific context, the question remains unsolved.}
}
Observation: OK
Agent Socrates takes 1-step Action:
{name: Finishparams: {response: Therefore, from both philosophical and evolutionary perspectives, the question of the chicken or the egg poses a complex enigma which, without specific context, cant be definitively answered. It is a reminder that the world and its components are interconnected and often cant be separated or understood in isolation.}
}
Observation: Task Completed.
Socrates finish execution. TaskPackage[ID:661f19fe-9403-4ac4-8aad-a2ed2c0667ce] status:
[completion: completedanswer: Therefore, from both philosophical and evolutionary perspectives, the question of the chicken or the egg poses a complex enigma which, without specific context, cant be definitively answered. It is a reminder that the world and its components are interconnected and often cant be separated or understood in isolation.
]Observation: Therefore, from both philosophical and evolutionary perspectives, the question of the chicken or the[TLDR]
Agent manager_agent takes 3-step Action:
{name: Aristotleparams: {Task: What is your perspective on the question Which came first, the chicken or the egg?}
}
Agent Aristotle receives the following TaskPackage:
[Task ID: 661f19fe-9403-4ac4-8aad-a2ed2c0667ceInstruction: What is your perspective on the question Which came first, the chicken or the egg?
]
Aristotle starts execution on TaskPackage 661f19fe-9403-4ac4-8aad-a2ed2c0667ce
Agent Aristotle takes 0-step Action:
{name: Thinkparams: {response: In addressing the question of Which came first, the chicken or the egg? from a philosophical standpoint, I would note that it is a paradox reminiscent of the concept of causality in nature. In my view, both the chicken and the egg are part of a continuous cycle of generation and transformation within the natural order. It is important to consider that the chicken we know as a species today did not emerge fully formed; rather, it evolved from earlier forms, including those that could be termed proto-chickens or precursors to the chicken. Thus, neither the egg nor the chicken could have come before the others in a strict, linear sense. The chicken is, in a sense, the egg; the egg is4 a form of the chicken. The question itself, therefore, underscores the complexities of biological evolution and might be best resolved with a metaphorical understanding rather than a literal one.}
}
Observation: OK
Agent Aristotle takes 1-step Action:
{name: Finishparams: {response: I believe our understanding of this question can be enriched by recognizing the interconnectedness and cyclical nature of life, as it reflects in the chicken and the egg conundrum. It teaches us about the intricacies of biological evolution and the limitations of our linear ways of thinking.}
}
Observation: Task Completed.
Aristotle finish execution. TaskPackage[ID:661f19fe-9403-4ac4-8aad-a2ed2c0667ce] status:
[completion: completedanswer: I believe our understanding of this question can be enriched by recognizing the interconnectedness and cyclical nature of life, as it reflects in the chicken and the egg conundrum. It teaches us about the intricacies of biological evolution and the limitations of our linear ways of thinking.
]Observation: I believe our understanding of this question can be enriched by recognizing the interconnectedness a[TLDR]
Agent manager_agent takes 4-step Action:
{name: Finishparams: {response: The perspectives of Confucius, Socrates, and Aristotle on the question of Which came first, the chicken or the egg? reflected a shared belief in the interconnectedness of life and the cyclical nature of nature. Confucius emphasized the interdependence of the chicken and the egg, Socrates saw the question as a complex enigma indicative of the interconnected and interdependent world, while Aristotle believed the question highlighted the cyclical and intricate nature of biological evolution.}
}
Observation: Task Completed.
manager_agent finish execution. TaskPackage[ID:661f19fe-9403-4ac4-8aad-a2ed2c0667ce] status:
[completion: completedanswer: The perspectives of Confucius, Socrates, and Aristotle on the question of Which came first, the chicken or the egg? reflected a shared belief in the interconnectedness of life and the cyclical nature of nature. Confucius emphasized the interdependence of the chicken and the egg, Socrates saw the question as a complex enigma indicative of the interconnected and interdependent world, while Aristotle believed the question highlighted the cyclical and intricate nature of biological evolution.
]Tips 在跑的过程中又发现了个问题依然是解析的问题还是在agent_utils.py的parse_action中有时候在action后面会有空格导致匹配失败因此这里将
pattern r^(?:Action:)?(\w)\[(.)\]$修改为
pattern r^(?:Action:\s*)?(\w)\[(.)\]$此外还有个问题是finish行为的params为空的时候代码会报错我们可以看一眼这个行为是如何定义的 可以看到这里必须要求有返回值 但是看一下同样的框架定义的默认行为Think 可以看到这里返回的是个固定的默认值 但是这个问题并不是一定会出现具体也取决于你用的大模型我这里用的9b可能有点不够用。