LangChain学习记录(四)Agent

一、基本介绍

        大模型跟人脑一样存储了大量的知识,我们不仅希望用这些知识来做一些简单的问答,我们更希望它也可以像人一样做一些自主决策,这就意味着要求它能够在没有人参与的情况下独立完成一些具有一定复杂度的任务。这个完成任务的过程就包括将任务切分成一些具体的小任务,以及每一步完成后接下来要做什么等这样的推理过程。langchain中的agent就是基于这种目标的一项功能。

        这篇博客用来记录agent的学习过程,主要包括如何根据任务配备不同类型的工具(搜索引擎等),以及如何自定义一些工具让代理能够调用。最后构建了一个基于crew的多代理协同完成一项任务的简单workflow。

二、几种Agent示例

1.维基百科搜索代理

        langchain中内置了很多供代理使用的工具,维基百科工具实际上是一个维基百科的api程序,它允许将输入的内容在维基百科引擎查询并返回结果。通过代码来看一下。

import os
import openai

from langchain_community.chat_models import ChatOpenAI
from langchain.agents import load_tools,initialize_agent
from langchain.agents import AgentType

os.environ["OPENAI_API_KEY"] = 'xxxx'
openai.api_key = os.environ.get("OPENAI_API_KEY")

llm = ChatOpenAI(temperature = 0)
tools = load_tools(['wikipedia'])
agent = initialize_agent(
    tools,  # 工具列表
    llm,    #语言模型
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,   # 代理类型
    handle_parsing_errors = True,
    verbose = True
)
agent('Tom M. Mitchell is an American computer scientistand the Founders University Professor at Carnegie Mellon University (CMU).what book did he write??')

在initialize_agent当中定义了代理使用的工具,使用的大模型,代理类型等信息。当向这个代理提问时,他的执行过程如下:

> Entering new AgentExecutor chain...
Thought: I can use Wikipedia to find out which book Tom M. Mitchell wrote.
Action:
```
{
  "action": "wikipedia",
  "action_input": "Tom M. Mitchell"
}
```
Observation: Page: Tom M. Mitchell
Summary: Tom Michael Mitchell (born August 9, 1951) is an American computer scientist and the Founders University Professor at Carnegie Mellon University (CMU). He is a founder and former Chair of the Machine Learning Department at CMU. Mitchell is known for his contributions to the advancement of machine learning, artificial intelligence, and cognitive neuroscience and is the author of the textbook Machine Learning. He is a member of the United States National Academy of Engineering since 2010. He is also a Fellow of the American Academy of Arts and Sciences, the American Association for the Advancement of Science and a Fellow and past President of the Association for the Advancement of Artificial Intelligence. In October 2018, Mitchell was appointed as the Interim Dean of the School of Computer Science at Carnegie Mellon.

Page: Tom Mitchell (Australian footballer)
Summary: Thomas Mitchell (born 31 May 1993) is a professional Australian rules footballer playing for the Collingwood Football Club in the Australian Football League (AFL). He previously played for the Sydney Swans from 2012 to 2016, and the Hawthorn Football Club between 2017 and 2022. Mitchell won the Brownlow Medal as the league's best and fairest player in 2018 and set the record for the most disposals in a VFL/AFL match, accruing 54 in a game against Collingwood during that season. He would later join them in 2023, en route to winning the 2023 AFL Grand Final and his first AFL premiership.
Thought:I have found the information about the book written by Tom M. Mitchell.
Final Answer: The book written by Tom M. Mitchell is "Machine Learning."

> Finished chain.

可以看到,与直接向大模型提问不同的是,它进行了分步和思考。首先会在我们提供的工具箱中寻找解决问题对应的工具,也就是如果有多个工具时,它会自动选择最适合解决问题的工具来处理(选择源于大模型的推理);选择维基百科引擎得到相关资料后,对资料做进一步分析得到最终答案。本例中其实维基百科返回了两条结果,一个是计算机科学家,一个是足球运动员,显然它排除了运动员,给出了正确结果。

2.数学计算代理

        语言大模型虽然能处理一些简单的数学问题,但是在复杂的数学问题上处理效果不够理想。例如计算简单的个位数加法能够得到正确结果,但问一个较大数值的数,就有极大概率回答错误,因为本质上语言大模型学习的还是语料信息,并不会真的计算。如下所示,当计算23894+987332时他得到了一个与真实结果(1011226)很接近的错误结果。

llm = ChatOpenAI(model_name = 'gpt-3.5-turbo',temperature = 0.0)
prompt = ChatPromptTemplate.from_template('{input}')
chain = LLMChain(llm = llm,prompt = prompt)
print(chain.run('23894 + 987332'))

>>
The sum of 23894 and 987332 is 1015226.

通过代理中的数学工具就能让它调用数学工具来解决问题。在工具当中添加一个‘llm-math’工具,这个工具实际上是个大模型加数学计算工具构成的chain。

tools = load_tools(['wikipedia','llm-math'],llm=llm)
agent = initialize_agent(
    tools,  # 工具列表
    llm,    #语言模型
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,   # 代理类型
    handle_parsing_errors = True,
    verbose = True
)
agent('23894 + 987332')
>>
> Entering new AgentExecutor chain...
Question: 23894 + 987332
Thought: We can use the Calculator tool to find the sum of these two numbers.
Action:
```
{
  "action": "Calculator",
  "action_input": "23894 + 987332"
}
```

Observation: Answer: 1011226
Thought:I now know the final answer

Final Answer: 1011226

可以看到,代理调用了数学工具,并得到了正确的结果。

3.python代理

        也可以让代理帮我们撰写程序脚本并执行,对执行结果进行输出。

from langchain_experimental.agents.agent_toolkits import create_python_agent
from langchain_experimental.tools.python.tool import PythonREPLTool

agent  = create_python_agent(
    llm,
    tool = PythonREPLTool(),
    verbose=True
)
name_list = [["Harrison","Chase"],["Lang","Chain"],["Dolly", "Too"],["Elle","Elem"],["Geoff","Fusion"],["Trance","Former"],[ "Jen","Ayai"]]
agent.run(f"""Sort these people by last name and then first name ,finally print the output.people:{name_list}""")

在上述代码中,代理的任务是对一组人名进行排序,排序规则是先按first name,再按last name。只需要引入PythonREPL工具就能实现这一功能。其处理过程是,让大模型先根据问题生成python代码,然后交给PythonREPL工具执行代码,并返回结果给大模型,最后整合成输出语料。

        最后执行结果如下。

> Entering new AgentExecutor chain...
Python REPL can execute arbitrary code. Use with caution.
We can sort the list of people by their last name and then their first name.
Action: Python_REPL
Action Input:
people = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]
people.sort(key=lambda x: (x[1], x[0]))
print(people)
Observation: [['Jen', 'Ayai'], ['Lang', 'Chain'], ['Harrison', 'Chase'], ['Elle', 'Elem'], ['Trance', 'Former'], ['Geoff', 'Fusion'], ['Dolly', 'Too']]

Thought:The people have been sorted by last name and then first name.
Final Answer: [['Jen', 'Ayai'], ['Lang', 'Chain'], ['Harrison', 'Chase'], ['Elle', 'Elem'], ['Trance', 'Former'], ['Geoff', 'Fusion'], ['Dolly', 'Too']]

> Finished chain.

4.自定义工具代理

        除了利用一些现有的工具外,也可以根据任务需要自定义一些工具供代理使用,只需要一个langchain的tools装饰器就能实现将函数当成工具使用。例如,我需要一个工具来返回今天的日期。

from langchain.agents import tool
from datetime import date
@tool
def time(text:str) ->str:
    """Returns today's date,use this for \
    any questions related to knowing today's \
     date.The input should be always empty str\
     and this function will always \
    return today's date.Any date mathmatics\
    should occur outside this function."""
    return str(date.today())

agent = initialize_agent(
    tools + [time],
    llm,
    agent = AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    handle_parsing_errors = True,
    verbose=True
)

这里需要在函数的注释当中说明输出的格式要求,这段注释也是代理判断在何种情况下使用这个工具的一个说明。看一下运行结果

agent.run('Whats todays holiday?')

>>
> Entering new AgentExecutor chain...
Thought: I should use the time tool to find out today's date and then search for any holidays happening today on Wikipedia.

Action:
```
{
  "action": "time",
  "action_input": ""
}
```


Observation: 2024-06-05
Thought:```
{
  "action": "wikipedia",
  "action_input": "holidays on June 5"
}
```
Observation: Page: June Holiday
Summary: In Ireland, the June Holiday (sometimes called the June Bank Holiday, Irish: Lá Saoire i mí Mheitheamh) is observed on the first Monday of June. It was previously observed as Whit Monday until 1973.



Page: June 5
Summary: June 5 is the 156th day of the year (157th in leap years) in the Gregorian calendar;  209 days remain until the end of the year.

Page: Federal holidays in the United States
Summary: Federal holidays in the United States are 11 calendar dates designated by the U.S. federal government as holidays. On these days non-essential U.S. federal government offices are closed and federal employees are paid for the day off.
Federal holidays are designated by the United States Congress in Title V of the United States Code (5 U.S.C. § 6103). Congress only has authority to create holidays for federal institutions (including federally-owned properties), employees, and the District of Columbia. As a general rule of courtesy, custom, and sometimes regulation, other institutions, such as banks, businesses, schools, and the financial markets, may be closed on national holidays. In various parts of the country, state and city holidays may be observed concurrently with federal holidays.


Thought:Could not parse LLM output: Final Answer
Observation: Invalid or incomplete response
Thought:I will need to search for holidays specifically for today's date to provide the correct answer.

Action:
```
{
  "action": "wikipedia",
  "action_input": "holidays on June 5"
}
```


Observation: Page: June Holiday
Summary: In Ireland, the June Holiday (sometimes called the June Bank Holiday, Irish: Lá Saoire i mí Mheitheamh) is observed on the first Monday of June. It was previously observed as Whit Monday until 1973.



Page: June 5
Summary: June 5 is the 156th day of the year (157th in leap years) in the Gregorian calendar;  209 days remain until the end of the year.

Page: Federal holidays in the United States
Summary: Federal holidays in the United States are 11 calendar dates designated by the U.S. federal government as holidays. On these days non-essential U.S. federal government offices are closed and federal employees are paid for the day off.
Federal holidays are designated by the United States Congress in Title V of the United States Code (5 U.S.C. § 6103). Congress only has authority to create holidays for federal institutions (including federally-owned properties), employees, and the District of Columbia. As a general rule of courtesy, custom, and sometimes regulation, other institutions, such as banks, businesses, schools, and the financial markets, may be closed on national holidays. In various parts of the country, state and city holidays may be observed concurrently with federal holidays.


Thought:I will need to search for holidays specifically for today's date to provide the correct answer.

Action:
```
{
  "action": "wikipedia",
  "action_input": "holidays on June 5"
}
``` 


Observation: Page: June Holiday
Summary: In Ireland, the June Holiday (sometimes called the June Bank Holiday, Irish: Lá Saoire i mí Mheitheamh) is observed on the first Monday of June. It was previously observed as Whit Monday until 1973.



Page: June 5
Summary: June 5 is the 156th day of the year (157th in leap years) in the Gregorian calendar;  209 days remain until the end of the year.

Page: Federal holidays in the United States
Summary: Federal holidays in the United States are 11 calendar dates designated by the U.S. federal government as holidays. On these days non-essential U.S. federal government offices are closed and federal employees are paid for the day off.
Federal holidays are designated by the United States Congress in Title V of the United States Code (5 U.S.C. § 6103). Congress only has authority to create holidays for federal institutions (including federally-owned properties), employees, and the District of Columbia. As a general rule of courtesy, custom, and sometimes regulation, other institutions, such as banks, businesses, schools, and the financial markets, may be closed on national holidays. In various parts of the country, state and city holidays may be observed concurrently with federal holidays.


Thought:Final Answer: June 5 is not a widely recognized holiday, but it is the 156th day of the year in the Gregorian calendar.

> Finished chain.

当问他今天是什么节日时,代理先通过自定义的time工具查询了今天的日期,然后交给维基百科搜索,得到结果。

三、构建workflow

        如果我们想要实现多个上述的agent在一起完成合作任务,也是可以实现的。不过这里就要引入一个同样强大的开源框架——CrewAI。CrewAI 的每个智能体本质都是基于 LangChain 的智能体,但它们被赋予了特殊的能力,通过 ReActSingleInputOutputParser 进行增强。这种特别设计的解析器不仅优化了角色扮演功能,还添加了用于增强上下文关注点的绑定停止词,并通过 LangChain 的会话摘要记忆机制实现了任务连续性。另外,CrewAI的智能体是构建在 LangChain 之上的,它们自然而然地带来了所谓的“飞轮效应”,可以无缝接入所有 LangChain 提供的工具和工具包。

        这里也是通过一个具体任务来说明。假如想要一份关于2024年ai领域新公司或者新项目相关的最新中文简报。我们可以通过以下几个代理协同完成这个任务:

(1)信息搜集代理。主要负责从源网站搜集相关信息。

(2)博文撰写代理。主要负责将搜集到的信息,写成ai相关的博客文章

(3)简报生成代理。主要负责将博文总结成简报形式,内容更精简。

(4)翻译代理。主要负责将简报翻译成中文。

(5)存档代理。负责将简报内容存到本地txt。

按照上述思路,就可以利用CrewAI来构建代理流程了。首先引入相关模块,另外这里是从谷歌网站搜集相关信息,谷歌开放了api接口并且集成到了langchain中,使用很方便。api可以自行免费申请。并将api服务用Tool类封装成一个工具,供代理使用。

from crewai import Agent, Task, Process, Crew
from langchain_community.utilities import GoogleSerperAPIWrapper
from langchain.agents import Tool

# to get your api key for free, visit and signup: https://serper.dev/
os.environ["SERPER_API_KEY"] = "xxx"

search = GoogleSerperAPIWrapper()
search_tool = Tool(
    name="Scrape google searches",
    func=search.run,
    description="useful for when you need to ask the agent to search the internet",
)

因为最后要写入文档,先用tools装饰器写一个存档工具

@tool
def save_file(data:str)->str:
    """这个工具用于将指定内容写入到特定路径的文件中。
    输入格式应该是一个由竖线 (|) 分隔的字符串,包含两部分:文件的完整路径(例如:./save/...)和你想要写入文件的具体内容。
    """
    try:
        dir = "./save"
        if not os.path.exists(dir):
            os.mkdir(dir)
        path, content = data.split("|")
        path = path.replace("\n", "").replace(" ", "").replace("`", "")
        if not path.startswith("./save"):
            path = f"./save/{path}"
        with open(path, "w") as f:
            f.write(content)
        return f"File written to {path}."
    except Exception:
        return "Error with the input format for the tool."

然后定义代理。在代理参数中,设置它的角色、目标、背景故事以及所使用的工具等。

explorer = Agent(
    role="Senior Researcher",
    goal="Find and explore the most exciting projects and companies in the ai and machine learning space in 2024",
    backstory="""You are and Expert strategist that knows how to spot emerging trends and companies in AI, tech and machine learning. 
    You're great at finding interesting, exciting projects on LocalLLama subreddit. You turned scraped data into detailed reports with names
    of most exciting projects an companies in the ai/ml world. ONLY use scraped data from the internet for the report.
    """,
    verbose=True,
    allow_delegation=False,
    tools=[search_tool],
)

writer = Agent(
    role="Senior Technical Writer",
    goal="Write engaging and interesting blog post about latest AI projects using simple, layman vocabulary",
    backstory="""You are an Expert Writer on technical innovation, especially in the field of AI and machine learning. You know how to write in 
    engaging, interesting but simple, straightforward and concise. You know how to present complicated technical terms to general audience in a 
    fun way by using layman words.ONLY use scraped data from the internet for the blog.""",
    verbose=True,
    allow_delegation=True,
)

critic = Agent(
    role="Expert Writing Critic",
    goal="Provide feedback and criticize blog post drafts. Make sure that the tone and writing style is compelling, simple and concise",
    backstory="""You are an Expert at providing feedback to the technical writers. You can tell when a blog text isn't concise,
    simple or engaging enough. You know how to provide helpful feedback that can improve any text. You know how to make sure that text 
    stays technical and insightful by using layman terms.
    """,
    verbose=True,
    allow_delegation=True,
)
translater = Agent(
    role="Chinese Translators",
    goal="Translate the resulting Criticize blog into Chinese",
    backstory="""You're a very proficient translator in both Chinese and English.
    """,
    verbose=True,
    allow_delegation=False,

)
editor = Agent(
    role="document manager",
    goal="Responsible for the preservation of the content of the briefings",
    backstory="""You are good at headline summaries
    """,
    verbose=True,
    llm=llm,
    allow_delegation=True,
    tools = [save_file]
)

然后定义任务,给每个任务分配对应的代理。这里需要注意的是,excuted_output参数是必要的,否则会报错。

task_report = Task(
    description="""Use and summarize scraped data from the internet to make a detailed report on the latest rising projects in AI. Use ONLY 
    scraped data to generate the report. Your final answer MUST be a full analysis report, text only, ignore any code or anything that 
    isn't text. The report has to have bullet points and with 5-10 exciting new AI projects and tools. Write names of every tool and project. 
    Each bullet point MUST contain 3 sentences that refer to one specific ai company, product, model or anything you found on the internet.  
    """,
    agent=explorer,
    expected_output="""The report  have bullet points and with 5-10 exciting new AI projects and tools. Write names of every tool and project. 
    Each bullet point MUST contain 3 sentences that refer to one specific ai company, product, model or anything you found on the internet"""
)

task_blog = Task(
    description="""Write a blog article with text only and with a short but impactful headline and at least 10 paragraphs. Blog should summarize 
    the report on latest ai tools found on localLLama subreddit. Style and tone should be compelling and concise, fun, technical but also use 
    layman words for the general public. Name specific new, exciting projects, apps and companies in AI world. Don't 
    write "**Paragraph [number of the paragraph]:**", instead start the new paragraph in a new line. Write names of projects and tools in BOLD.
    ALWAYS include links to projects/tools/research papers. ONLY include information from LocalLLAma.
    For your Outputs use the following markdown format:
    ```
    ## [Title of post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ## [Title of second post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ```
    """,
    agent=writer,
    expected_output="""a blog article with text only and with a short but impactful headline and at least 10 paragraphs"""
)

task_critique = Task(
    description="""The Output MUST have the following markdown format:
    ```
    ## [Title of post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ## [Title of second post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ```
    Make sure that it does and if it doesn't, rewrite it accordingly.
    """,
    agent=critic,
    expected_output="""A refined finalized version of the blog post in markdown format"""
)
task_translate = Task(
    description="""Translate the blog into Chinese.The Output MUST have the following markdown format:
    ```
    ## [Title of post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ## [Title of second post](link to project)
    - Interesting facts
    - Own thoughts on how it connects to the overall theme of the newsletter
    ```
    Make sure that it does and if it doesn't, rewrite it accordingly.
    """,
    agent=translater,
    expected_output="""一篇简短有力的中文简报"""
)

task_save = Task(
    description="""Create a suitable filename for the content, \
    using the .txt extension.You must use the tool to save it to the path . /save/(your-title.txt)
    """,
    agent=editor,
    expected_output="""A refined finalized version of the blog post in markdown format"""
)

到这就完成了整个workflow的制定,最后执行

# Get your crew to work!
dir = "./save"
if not os.path.exists(dir):
    os.mkdir(dir)
result = crew.kickoff()

执行的结果就是在我的save目录下保存了一个含有简报内容的txt文件,文件名也是代理根据内容帮我取的。

Exciting-AI-Projects.txt

>>

## [塑造未来的令人兴奋的人工智能项目](link to project)
- 有趣的事实
- 我对它如何与简报的整体主题联系的看法

## [Alpha 项目](link to project)
- Alpha 项目是一个专注于预测自然灾害的人工智能项目。通过分析来自各种来源的大量数据,如天气模式、地震活动和历史灾害记录,Alpha 项目可以提供预警,并帮助社区更好地准备应对潜在灾害。这个项目在潜在挽救生命和减轻自然灾害影响方面具有突破性。

## [Beta 公司](link to project)
- Beta 公司开发了一款用于医疗诊断的人工智能工具。该工具使用机器学习算法分析医学图像、患者数据和症状,帮助医疗专业人员做出准确的诊断。凭借快速准确地识别疾病和病情的能力,Beta 公司的工具正在革新医疗领域,改善患者结果。

## [Gamma 工具](link to project)
- Gamma 工具是一款专为软件开发设计的人工智能工具。通过自动化任务,如代码生成、错误检测和优化,Gamma 工具帮助开发人员简化工作流程,创建更高效可靠的软件。这个工具对软件工程师来说是一个改变游戏规则的工具,让他们专注于创新和创造力,而不是琐碎的任务。

## [Delta 项目](link to project)
- Delta 项目专注于网络安全的人工智能项目。随着网络攻击和数据泄露威胁的增加,Delta 项目利用先进的机器学习算法实时检测和防止安全威胁。通过分析网络流量、用户行为和系统漏洞,Delta 项目为组织提供保护敏感数据和基础设施所需的工具。

## [Epsilon 公司](link to project)
- Epsilon 公司提供一款用于金融投资策略的人工智能工具。通过分析市场趋势、经济指标和历史数据,这个工具帮助投资者做出明智的决策,最大化他们的回报。具有预测市场走势和识别盈利机会的能力,Epsilon 公司的工具对于任何希望在复杂的金融世界中导航的人来说都是一项宝贵的资产。

## [Zeta 工具](link to project)
- Zeta 工具是一款专为数据分析设计的人工智能工具。通过处理大型数据集,识别模式和生成见解,Zeta 工具帮助企业做出数据驱动的决策,优化他们的运营。具有发现隐藏趋势和相关性的能力,这个工具对于希望在当今数据驱动世界中保持领先地位的组织至关重要。

总的来说,这些人工智能项目和工具处于技术创新的前沿,正在塑造各个行业的未来,并对社会产生重大影响。可能性是无限的,随着这些人工智能技术的突破性进展,未来看起来更加光明。

可以看到,这个任务代理很好地完成了。

四、总结

        随着大模型技术的发展,我们可以用大模型做越来越多的事情,而让大模型更好地为我们所用的一个方式之一就是构建任务代理,并用代理构建完整的workflow,是非常方便的。可以看到这种应用范式以后会越来越多地在生产场景中落地,而且随着大模型技术的发展,这种代理将能处理更加复杂的任务,还是挺令人兴奋的。

  • 17
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值