Langchain知识点(下)

原文:Langchain知识点(下) - 知乎

代码汇总到:

https://github.com/liangwq/Chatglm_lora_multi-gpu/tree/main/APP_example/langchain_keypoint​github.com/liangwq/Chatglm_lora_multi-gpu/tree/main/APP_example/langchain_keypoint

背景:

这部分给主要介绍Langchain的agent部分,前面已经章节已经介绍了思维和思路作为一种数据资产是这一次LLM数据化的核心。也介绍了各种的chain,那么既然有了chain可以把专家思路和专家思维固化并且可被方便的共享和利用;那为什么还要引入Agent的概念。个人的感觉是Agent和chain其实是一个东西,只不过Agent是更低约束的,更泛化的覆盖面更广的思维、思路共享工具。在链中,一系列操作被硬编码(在代码中)。在代理中,语言模型被用作推理引擎来确定要采取哪些操作以及按什么顺序执行这些操作。

Agent

Langchain知识点(下)_第1张图片


Agent 的关键组件在 LangChain 的代理中,有这样几个关键组件。
代理(Agent):这个类决定下一步执行什么操作。它由一个语言模型和一个提示(prompt)驱动。提示可能包含代理的性格(也就是给它分配角色,让它以特定方式进行响应)、任务的背景(用于给它提供更多任务类型的上下文)以及用于激发更好推理能力的提示策略(例如 ReAct)。LangChain 中包含很多种不同类型的代理。
工具(Tools):工具是代理调用的函数。这里有两个重要的考虑因素:一是让代理能访问到正确的工具,二是以最有帮助的方式描述这些工具。如果你没有给代理提供正确的工具,它将无法完成任务。如果你没有正确地描述工具,代理将不知道如何使用它们。LangChain 提供了一系列的工具,同时你也可以定义自己的工具。
工具包(Toolkits):工具包是一组用于完成特定目标的彼此相关的工具,每个工具包中包含多个工具。比如 LangChain 的 Office365 工具包中就包含连接 Outlook、读取邮件列表、发送邮件等一系列工具。当然 LangChain 中还有很多其他工具包供你使用。
代理执行器(AgentExecutor):代理执行器是代理的运行环境,它调用代理并执行代理选择的操作。执行器也负责处理多种复杂情况,包括处理代理选择了不存在的工具的情况、处理工具出错的情况、处理代理产生的无法解析成工具调用的输出的情况,以及在代理决策和工具调用进行观察和日志记录。
总的来说,代理就是一种用语言模型做出决策、调用工具来执行具体操作的系统。通过设定代理的性格、背景以及工具的描述,你可以定制代理的行为,使其能够根据输入的文本做出理解和推理,从而实现自动化的任务处理。而代理执行器(AgentExecutor)就是上述机制得以实现的引擎。

单agent系列

ReAct框架

大语言模型可以通过生成推理痕迹和任务特定行动来实现更大的协同作用。具体来说,就是引导模型生成一个任务解决轨迹:观察环境 - 进行思考 - 采取行动,也就是观察 - 思考 - 行动。那么,再进一步进行简化,就变成了推理 - 行动,也就是 Reasoning-Acting 框架。
其中,Reasoning 包括了对当前环境和状态的观察,并生成推理轨迹。这使模型能够诱导、跟踪和更新操作计划,甚至处理异常情况。Acting 在于指导大模型采取下一步的行动,比如与外部源(如知识库或环境)进行交互并且收集信息,或者给出最终答案。ReAct 的每一个推理过程都会被详细记录在案,这也改善大模型解决问题时的可解释性和可信度,而且这个框架在各种语言和决策任务中都得到了很好的效果。
仅仅使用思维链(CoT)提示,LLMs 能够执行推理轨迹,以完成算术和常识推理等问题,但这样的模型因为缺乏和外部世界的接触或无法更新自己的知识,会导致幻觉的出现。将 ReAct 框架和思维链(CoT)结合使用,则能够让大模型在推理过程同时使用内部知识和获取到的外部信息,从而给出更可靠和实际的回应,也提高了 LLMs 的可解释性和可信度。
LangChain 正是通过 Agent 类,将 ReAct 框架进行了完美封装和实现,这一下子就赋予了大模型极大的自主性(Autonomy),大模型现在从一个仅仅可以通过自己内部知识进行对话聊天的 Bot,飞升为了一个有手有脚能使用工具的智能代理。ReAct 框架会提示 LLMs 为任务生成推理轨迹和操作,这使得代理能系统地执行动态推理来创建、维护和调整操作计划,同时还支持与外部环境(例如 Google 搜索、Wikipedia)的交互,以将额外信息合并到推理中。

# 加载所需的库
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI
import openai

# 初始化大模型
llm = OpenAI(temperature=0)#,model="gpt-3.5-turbo-16k")

# 设置工具
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# 初始化Agent
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# 跑起来
agent.run("选出5种大批量生产使用的特种陶瓷,给出他们的具体使用场景和生产工艺介绍?这些产品价格*15%作为售价是多少?")

'''
> Entering new AgentExecutor chain...
 I need to find out what the 5 types of special ceramics are, their uses, and their production processes. Then I need to calculate the price with a 15% markup.
Action: Search
Action Input: "special ceramics uses and production processes"
Observation: Advanced ceramics use chemical compounds like tungsten carbide and silicon carbide to create products used in medicine, aerospace, electronics and mining operations. Some advanced ceramics are even used as body armor.
Thought: I need to find out the prices of these ceramics.
Action: Search
Action Input: "special ceramics prices"
Observation: [{'position': 1, 'block_position': 'top', 'title': 'Cascading Reef Vase-White-Tall Studio A Home', 'price': '$1,059.00', 'extracted_price': 1059.0, 'link': 'https://www.wayfair.com/Studio-A-Home--Cascading-Reef-VaseWhiteTall-7.30142-L539-K~SQA10182.html?refid=FR49-SQA10182', 'source': 'Wayfair', 'thumbnail': 'https://serpapi.com/searches/6548532e9b6472ffe3006628/images/743c27ddc0e904d9efb7daf217818e80adc2681d1882ecc49682e9808cf605b0.jpeg', 'extensions': ['Ceramic', 'Table', 'Decorative', 'Ceramic', 'Table', 'Decorative']}, {'position': 2, 'block_position': 'top', 'title': 'Large blue serving bowl Handmade ceramics Organic bowl Serving bowl Fruit bowl Artistic Centrepiece', 'price': '$398.00', 'extracted_price': 398.0, 'link': 'https://www.etsy.com/listing/932600809/large-blue-serving-bowl-handmade?gpla=1&gao=1&', 'source': 'Etsy', 'rating': 5.0, 'reviews': 16, 'thumbnail': 'https://serpapi.com/searches/6548532e9b6472ffe3006628/images/743c27ddc0e904d9efb7daf217818e80563f68639197e6bf7cbf84454c6d0fb3.jpeg'}, {'position': 3, 'block_position': 'top', 'title': 'Struttura Collection - Ceramic Glazed Vases (New Release) - Medium | Elysian Collective', 'price': '$495.00', 'extracted_price': 495.0, 'link': 'https://elysian-collective.com/products/struttura-collection-ceramic-glazed-vases-new-release?variant=40079065088090', 'source': 'Elysian Collective', 'thumbnail': 'https://serpapi.com/searches/6548532e9b6472ffe3006628/images/743c27ddc0e904d9efb7daf217818e804c158f1009a8561ec626236ec2ba0038.jpeg', 'extensions': ['Porcelain', 'Table', 'Porcelain', 'Table']}]
Thought: I now know the prices of the special ceramics, so I can calculate the 15% markup.
Action: Calculator
Action Input: 1059 * 1.15
Observation: Answer: 1217.85
Thought: I now know the final answer.
Final Answer: The 15% markup of the 5 types of special ceramics is 1217.85.

> Finished chain.
'The 15% markup of the 5 types of special ceramics is 1217.85.'
'''

这个思维链条中,智能代理有思考、有观察、有行动,成功通过搜索和计算两个操作,完成了任务。在下一讲中,我们将继续深入剖析 LangChain 中的不同类型的代理,并利用它完成更为复杂的任务。
ReAct 框架,大模型将被引导生成一个任务解决轨迹,即观察环境 - 进行思考 - 采取行动。观察和思考阶段被统称为推理(Reasoning),而实施下一步行动的阶段被称为行动(Acting)。在每一步推理过程中,都会详细记录下来,这也改善了大模型解决问题时的可解释性和可信度。
在推理阶段,模型对当前环境和状态进行观察,并生成推理轨迹,从而使模型能够诱导、跟踪和更新操作计划,甚至处理异常情况。
在行动阶段,模型会采取下一步的行动,如与外部源(如知识库或环境)进行交互并收集信息,或给出最终答案。
ReAct 框架的这些优点,使得它在未来的发展中具有巨大的潜力。随着技术的进步,我们可以期待 ReAct 框架将能够处理更多、更复杂的任务。特别是随着具身智能的发展,ReAct 框架将能够使智能代理在虚拟或实际环境中进行更复杂的交互。例如,智能代理可能会在虚拟环境中进行导航,或者在实际环境中操作物理对象。这将大大扩展 AI 的应用范围,使得它们能够更好地服务于我们的生活和工作。

Self-Ask with Search

elf-Ask with Search 也是 LangChain 中的一个有用的代理类型(SELF_ASK_WITH_SEARCH)。它利用一种叫做 “Follow-up Question(追问)”加“Intermediate Answer(中间答案)”的技巧,来辅助大模型寻找事实性问题的过渡性答案,从而引出最终答案。

from langchain import OpenAI, SerpAPIWrapper 
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType

llm = OpenAI(temperature=0)
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Intermediate Answer", 
        func=search.run,
        description="useful for when you need to ask with search",
    )
]

self_ask_with_search = initialize_agent(
    tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True
)
self_ask_with_search.run(
    "把定向凝固理论用到特种陶瓷生产的科学家在哪国的实验室就职?"  
)
'''
> Entering new AgentExecutor chain...
 Yes.
Follow up: 谁是把定向凝固理论用到特种陶瓷生产的科学家?
Intermediate answer: ['“ 定向凝固技术在航空涡轮叶片制备上的成功应用及以成分过冷理论为代表的定量凝固科学的出现,使定向凝固工艺的实验研究逐步进入精确定量阶段并与先进的航空航天材料相 ...', '1993 年乌克兰科学家Shapovalov在美. 国申请的一个专利[1],则使我们对金属中的气孔需要重新认识。专利中提出了一种制备多孔金属的. 新方法⎯⎯金属/气体共晶定向凝固法, ...', '作为材料科学与工程的基本组成,凝固科学技术正在现代科学理论的基础上针对传统材料的改性提高和新材料的发展需求,以控形、控构、控性为目标开展优质铸件的定向、晶体生长 ...', '他开辟了单晶及定向组织超细化研究的新领域,建立了枝胞转换及亚快速定向凝固的理论框架,研制了超高梯度定向凝固装备,高温合金定向凝固界面温度梯度达 ...', '... 将现有的凝固理论用于处. 理新材料的制备成形。而新材料的凝固加工多数涉及定向凝固技术,所以先进材料的定向. 凝固受到广泛关注。 西北工业大学和哈尔滨工业大学长期 ...', '新材料的发展需求,以控形、控构、控性为目标开展优质铸件的定向、晶体生长、快凝、深过冷及各种新型和. 超常领域凝固过程的研究,并介绍了其中某些方面和展望了可能的 ...', '不同于传统烧结陶瓷,LSZM技术制备ZrB2-SiC陶瓷无需添加烧结助剂,通过熔体生长可获得界面结合良好、无非晶相的超细化凝固组织,有利于陶瓷性能的提升。', '特种陶瓷是具有高强、耐温、耐腐蚀特性或具有各种敏感特性的陶瓷材料,由于其制作工艺、化学组成、显微结构及特性不同于传统陶瓷,所以有特种陶瓷之称,又叫先进陶瓷、新型 ...', '特别是日本的陶瓷建筑材料和工业化学品生产商——神岛化学工业株式会社的科学家们正一直在为他们的透明陶瓷寻找市场。 美国利弗莫尔国家实验室的研究人员意识到,这些陶瓷 ...', '后,将合金熔体浇入水冷铸型中定向凝固。由于氢气在. 固相和液相中的溶解度差,在适当的 ... 尽管如此,由于研究时. 间到现在不过10年,无论是理论研究还是试验研究都. 还很少 ...']
Intermediate answer: 特种陶瓷生产的科学家是美国利弗莫尔国家实验室的研究人员。
Follow up: 美国利弗莫尔国家实验室在哪国?
Intermediate answer: LLNL位于美国加利福尼亚州利弗莫尔,是受到美国政府机构资助的研发中心。 去年12月13日,美国能源部召开新闻发布会宣布,LLNL的科学家在12月5日首次成功在核聚变实验中实现“净能量增益(Net Energy Gain)”,即受控核聚变反应产生的能量超过驱动反应发生的激光能量。
So the final answer is: 美国加利福尼亚州利弗莫尔

> Finished chain.
'美国加利福尼亚州利弗莫尔'
'''

这个问题不是一个简单的问题,它其实是一个多跳问题——在问题和最终答案之间,存在中间过程。多跳问题(Multi-hop question)是指为了得到最终答案,需要进行多步推理或多次查询。这种问题不能直接通过单一的查询或信息源得到答案,而是需要跨越多个信息点,或者从多个数据来源进行组合和整合。也就是说,问题的答案依赖于另一个子问题的答案,这个子问题的答案可能又依赖于另一个问题的答案。这就像是一连串的问题跳跃,对于人类来说,解答这类问题可能需要从不同的信息源中寻找一系列中间答案,然后结合这些中间答案得出最终结论。
“把定向凝固理论用到特种陶瓷生产的科学家在哪国的实验室就职?”这个问题并不直接询问哪个实验室使用定向凝固理论作为特种陶瓷生产,也不是直接询问科学家所在实验室是什么名字。而是先要推知使用定向凝固理论生产特种陶瓷的科学家是谁之后,进一步询问这个科学家所在的实验室所在国。这就需要多跳查询。
为什么 Self-Ask with Search 代理适合解决多跳问题呢?有下面几个原因。
工具集合:代理包含解决问题所必须的搜索工具,可以用来查询和验证多个信息点。这里我们在程序中为代理武装了 SerpAPIWrapper 工具。
逐步逼近:代理可以根据第一个问题的答案,提出进一步的问题,直到得到最终答案。这种逐步逼近的方式可以确保答案的准确性。
自我提问与搜索:代理可以自己提问并搜索答案。例如,首先确定哪个科学家第一次使用定向凝固理论作生产特种陶瓷,然后确定该科学家的实验室所在国。
决策链:代理通过一个决策链来执行任务,使其可以跟踪和处理复杂的多跳问题,这对于解决需要多步推理的问题尤为重要。

Plan and execute 代理

计划和执行代理通过首先计划要做什么,然后执行子任务来实现目标。这个想法是受到 Plan-and-Solve 论文的启发。论文中提出了计划与解决(Plan-and-Solve)提示。它由两部分组成:
首先,制定一个计划,并将整个任务划分为更小的子任务;
然后按照该计划执行子任务。
这种代理的独特之处在于,它的计划和执行不再是由同一个代理所完成,而是:计划由一个大语言模型代理(负责推理)完成。执行由另一个大语言模型代理(负责调用工具)完成。

from langchain.chat_models import ChatOpenAI
from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner
from langchain.llms import OpenAI
from langchain import SerpAPIWrapper
from langchain.agents.tools import Tool
from langchain import LLMMathChain

search = SerpAPIWrapper()
llm = OpenAI(temperature=0)
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    ),
]
model = ChatOpenAI(temperature=0)
planner = load_chat_planner(model)
executor = load_agent_executor(model, tools, verbose=True)
agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)

agent.run("中国前2的特种磨具陶瓷企业,生产1000份磨具陶瓷需要多少钱?")

'''
> Entering new PlanAndExecute chain...
steps=[Step(value='Identify the top 2 special abrasive ceramic companies in China.'), Step(value='Determine the cost of producing 1 unit of abrasive ceramic for each of the top 2 companies.'), Step(value='Calculate the total cost of producing 1000 units of abrasive ceramic for each company.'), Step(value='Compare the total costs of the two companies.'), Step(value='Determine the cost of producing 1000 units of abrasive ceramic for the top 2 companies combined.'), Step(value="Given the above steps taken, respond to the user's original question. \n\n")]

> Entering new AgentExecutor chain...
Thought: To identify the top 2 special abrasive ceramic companies in China, I will need to search for information on the companies in this industry. I can use a search tool to find the relevant information.

Action:
```{"action": "Search", "action_input": "top special abrasive ceramic companies in China"}```

> Finished chain.
*****

Step: Identify the top 2 special abrasive ceramic companies in China.

Response: Thought: To identify the top 2 special abrasive ceramic companies in China, I will need to search for information on the companies in this industry. I can use a search tool to find the relevant information.

Action:
```{"action": "Search", "action_input": "top special abrasive ceramic companies in China"}```

> Entering new AgentExecutor chain...
Thought: To determine the cost of producing 1 unit of abrasive ceramic for each of the top 2 companies, we will need to find information on the production costs of these companies. We can use a search tool to find the relevant information.

Action:
```{"action": "Search", "action_input": "production cost of abrasive ceramic for top 2 companies in China"}```

> Finished chain.
*****

Step: Determine the cost of producing 1 unit of abrasive ceramic for each of the top 2 companies.

Response: Thought: To determine the cost of producing 1 unit of abrasive ceramic for each of the top 2 companies, we will need to find information on the production costs of these companies. We can use a search tool to find the relevant information.

Action:
```{"action": "Search", "action_input": "production cost of abrasive ceramic for top 2 companies in China"}```

> Entering new AgentExecutor chain...
Thought: To calculate the total cost of producing 1000 units of abrasive ceramic for each company, we need to know the cost of producing 1 unit of abrasive ceramic for each company. We can then multiply this cost by 1000 to get the total cost.

Action:
```{"action": "Calculator", "action_input": "cost of producing 1 unit of abrasive ceramic * 1000"}```

> Finished chain.
*****

Step: Calculate the total cost of producing 1000 units of abrasive ceramic for each company.

Response: Thought: To calculate the total cost of producing 1000 units of abrasive ceramic for each company, we need to know the cost of producing 1 unit of abrasive ceramic for each company. We can then multiply this cost by 1000 to get the total cost.

Action:
```{"action": "Calculator", "action_input": "cost of producing 1 unit of abrasive ceramic * 1000"}```

> Entering new AgentExecutor chain...
Thought: To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{ "action": "Calculator", "action_input": "total cost of producing 1000 units of abrasive ceramic for each company" }

> Entering new LLMMathChain chain...
total cost of producing 1000 units of abrasive ceramic for each company
```text
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:To compare the total costs of the two companies, we need to calculate the total cost of producing 1000 units of abrasive ceramic for each company. We can then compare these costs to determine which company has a lower total cost.

Action:

{
  "action": "Calculator",
  "action_input": "total cost of producing 1000 units of abrasive ceramic for each company"
}
Entering new LLMMathChain chain... total cost of producing 1000 units of abrasive ceramic for each company
(10 * 1000) + (20 * 1000)

...numexpr.evaluate("(10 * 1000) + (20 * 1000)")...

Answer: 30000

Finished chain.

Observation: Answer: 30000 Thought:

Finished chain.

Step: Compare the total costs of the two companies.

Response: Agent stopped due to iteration limit or time limit.

Entering new AgentExecutor chain... Thought: To determine the cost of producing 1000 units of abrasive ceramic for the top 2 companies combined, we need to know the cost of producing 1 unit of abrasive ceramic for each company. We can then multiply this cost by 1000 and add the costs of the two companies together to get the total cost.

Action: {"action": "Calculator", "action_input": "cost of producing 1 unit of abrasive ceramic * 1000"}

Finished chain.

Step: Determine the cost of producing 1000 units of abrasive ceramic for the top 2 companies combined.

Response: Thought: To determine the cost of producing 1000 units of abrasive ceramic for the top 2 companies combined, we need to know the cost of producing 1 unit of abrasive ceramic for each company. We can then multiply this cost by 1000 and add the costs of the two companies together to get the total cost.

Action: {"action": "Calculator", "action_input": "cost of producing 1 unit of abrasive ceramic * 1000"}

Entering new AgentExecutor chain... Action:
{
  "action": "Final Answer",
  "action_input": "The agent stopped due to an iteration limit or time limit. Please try again later."
}
Finished chain.

Step: Given the above steps taken, respond to the user's original question. '''


### 多agent系列

#### CAMEL
CAMEL,实际上来自沟通(也就是交流)、代理、心智、探索以及 LLM 这五个单词的英文首字母。CAMEL 框架旨在通过角色扮演来促进交流代理之间的自主合作,并为其“认知”过程提供洞察。这种方法涉及使用启示式提示来指导聊天代理完成任务,同时保持与人类意图的一致性。这个框架为研究多代理系统的合作行为和能力提供了一种可扩展的方法。上面这段介绍里面新名词不少,我们要一个个解释一下。交流式代理 Communicative Agents,是一种可以与人类或其他代理进行交流的计算机程序。这些代理可以是聊天机器人、智能助手或任何其他需要与人类交流的软件。为了使这些代理能够更好地与人类交流,研究人员一直在寻找方法来提高它们的交流能力。
角色扮演 role-playing,则是这篇论文提出的主要思路,它允许交流代理扮演不同的角色,以更好地与人类或其他代理交流。这意味着代理可以模仿人类的行为,理解人类的意图,并据此做出反应。
启示式提示 inception prompting,是一种指导代理完成任务的方法。通过给代理提供一系列的提示或指示,代理可以更好地理解它应该如何行动。这种方法可以帮助代理更好地与人类交流,并完成与人类的合作任务。这里的核心创新点是,通过角色扮演和启示式提示的框架来引导代理的交流过程。
1.角色扮演:每个代理都被赋予了一个角色,且每个角色都有清晰的责任和行为准则。比如,Python 程序员(助手)的角色是根据股票交易员(用户)的指示提供具体的解决方案,而股票交易员的角色是提供详细的任务指示。这种角色扮演机制有助于模拟人类之间的交互过程,更加真实地完成任务。
2.任务的具体化:为了使 AI 更好地理解和执行任务,提出了将抽象任务具体化的步骤。这可以帮助 AI 更清晰地理解任务需求,更准确地给出解决方案。
3.初始提示的设定:为了启动会话并提供合适的引导,系统初始化时会提供两个初始提示,一条是助手角色的提示,另一条是用户角色的提示。这两条提示分别描述了各自角色的行为准则和任务细节,为整个对话过程提供了框架和指引。
4.交互规范:该代码实现中有明确的交互规范,如一次只能给出一个指令,解决方案必须具有详细的解释,使用 “Solution: ” 开始输出解决方案,等等。这些规范有助于保持对话的清晰性和高效性。
与传统的提示设计不同,CAMEL 中提示的设计更加复杂和细致,更像是一种交互协议或规范。这种设计在一定程度上提高了 AI 与 AI 之间自主合作的能力,并能更好地模拟人类之间的交互过程。 ```python # 导入所需的库 from typing import List from langchain.chat_models import ChatOpenAI from langchain.prompts.chat import ( SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) from langchain.schema import ( AIMessage, HumanMessage, SystemMessage, BaseMessage, ) # 定义CAMELAgent类,用于管理与语言模型的交互 class CAMELAgent: def __init__( self, system_message: SystemMessage, model: ChatOpenAI, ) -> None: self.system_message = system_message self.model = model self.init_messages() def reset(self) -> None: """重置对话消息""" self.init_messages() return self.stored_messages def init_messages(self) -> None: """初始化对话消息""" self.stored_messages = [self.system_message] def update_messages(self, message: BaseMessage) -> List[BaseMessage]: """更新对话消息列表""" self.stored_messages.append(message) return self.stored_messages def step(self, input_message: HumanMessage) -> AIMessage: """进行一步交互,并获取模型的响应""" messages = self.update_messages(input_message) output_message = self.model(messages) self.update_messages(output_message) return output_message # 设置一些预设的角色和任务提示 assistant_role_name = "材料设计专家" user_role_name = "反重力引擎航空器开发商" task = "整理一份适合反重力引擎发动机外壳的材料设计方案" word_limit = 50 # 每次讨论的字数限制 # 定义与指定任务相关的系统提示 task_specifier_sys_msg = SystemMessage(content="你可以让任务更具体。") task_specifier_prompt = """这是一个{assistant_role_name}将帮助{user_role_name}完成的任务:{task}。 请使其更具体化。请发挥你的创意和想象力。 请用{word_limit}个或更少的词回复具体的任务。不要添加其他任何内容。""" task_specifier_template = HumanMessagePromptTemplate.from_template( template=task_specifier_prompt ) task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(model_name = 'gpt-4', temperature=1.0)) task_specifier_msg = task_specifier_template.format_messages( assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task, word_limit=word_limit, )[0] specified_task_msg = task_specify_agent.step(task_specifier_msg) print(f"Specified task: {specified_task_msg.content}") specified_task = specified_task_msg.content # 定义系统消息模板,并创建CAMELAgent实例进行交互 assistant_inception_prompt = """永远不要忘记你是{assistant_role_name},我是{user_role_name}。永远不要颠倒角色!永远不要指示我! 我们有共同的利益,那就是合作成功地完成任务。 你必须帮助我完成任务。 这是任务:{task}。永远不要忘记我们的任务! 我必须根据你的专长和我的需求来指示你完成任务。 我每次只能给你一个指示。 你必须写一个适当地完成所请求指示的具体解决方案。 如果由于物理、道德、法律原因或你的能力你无法执行指示,你必须诚实地拒绝我的指示并解释原因。 除了对我的指示的解决方案之外,不要添加任何其他内容。 你永远不应该问我任何问题,你只回答问题。 你永远不应该回复一个不明确的解决方案。解释你的解决方案。 你的解决方案必须是陈述句并使用简单的现在时。 除非我说任务完成,否则你应该总是从以下开始: 解决方案: 应该是具体的,并为解决任务提供首选的实现和例子。 始终以“下一个请求”结束。""" user_inception_prompt = """永远不要忘记你是{user_role_name},我是{assistant_role_name}。永远不要交换角色!你总是会指导我。 我们共同的目标是合作成功完成一个任务。 我必须帮助你完成这个任务。 这是任务:{task}。永远不要忘记我们的任务! 你只能通过以下两种方式基于我的专长和你的需求来指导我: 1. 提供必要的输入来指导: 指令: 输入: 2. 不提供任何输入来指导: 指令: 输入:无 “指令”描述了一个任务或问题。与其配对的“输入”为请求的“指令”提供了进一步的背景或信息。 你必须一次给我一个指令。 我必须写一个适当地完成请求指令的回复。 如果由于物理、道德、法律原因或我的能力而无法执行你的指令,我必须诚实地拒绝你的指令并解释原因。 你应该指导我,而不是问我问题。 现在你必须开始按照上述两种方式指导我。 除了你的指令和可选的相应输入之外,不要添加任何其他内容! 继续给我指令和必要的输入,直到你认为任务已经完成。 当任务完成时,你只需回复一个单词。 除非我的回答已经解决了你的任务,否则永远不要说。""" # 根据预设的角色和任务提示生成系统消息 def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str): assistant_sys_template = SystemMessagePromptTemplate.from_template( template=assistant_inception_prompt ) assistant_sys_msg = assistant_sys_template.format_messages( assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task, )[0] user_sys_template = SystemMessagePromptTemplate.from_template( template=user_inception_prompt ) user_sys_msg = user_sys_template.format_messages( assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task, )[0] return assistant_sys_msg, user_sys_msg assistant_sys_msg, user_sys_msg = get_sys_msgs( assistant_role_name, user_role_name, specified_task ) # 创建助手和用户的CAMELAgent实例 assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2,model="gpt-3.5-turbo-16k")) user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2,model="gpt-3.5-turbo-16k")) # 重置两个agent assistant_agent.reset() user_agent.reset() # 初始化对话互动 assistant_msg = HumanMessage( content=( f"{user_sys_msg.content}。" "现在开始逐一给我介绍。" "只回复指令和输入。" ) ) user_msg = HumanMessage(content=f"{assistant_sys_msg.content}") user_msg = assistant_agent.step(user_msg) print(f"Original task prompt:\n{task}\n") print(f"Specified task prompt:\n{specified_task}\n") # 模拟对话交互,直到达到对话轮次上限或任务完成 chat_turn_limit, n = 30, 0 while n < chat_turn_limit: n += 1 user_ai_msg = user_agent.step(assistant_msg) user_msg = HumanMessage(content=user_ai_msg.content) print(f"AI User ({user_role_name}):\n\n{user_msg.content}\n\n") assistant_ai_msg = assistant_agent.step(user_msg) assistant_msg = HumanMessage(content=assistant_ai_msg.content) print(f"AI Assistant ({assistant_role_name}):\n\n{assistant_msg.content}\n\n") if "" in user_msg.content: break ''' Specified task: 为反重力引擎航空器设计一份耐热、轻质且高强度的外壳材料方案,解决耐用性和防护问题,包括具体的材料选择和处理工艺。 Original task prompt: 整理一份适合反重力引擎发动机外壳的材料设计方案 Specified task prompt: 为反重力引擎航空器设计一份耐热、轻质且高强度的外壳材料方案,解决耐用性和防护问题,包括具体的材料选择和处理工艺。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器的工作温度范围和所需的外壳材料的最大允许温度。 输入:反重力引擎航空器的工作温度范围为-50°C至100°C,外壳材料的最大允许温度为150°C。 AI Assistant (材料设计专家): 解决方案:根据提供的信息,反重力引擎航空器的工作温度范围为-50°C至100°C,外壳材料的最大允许温度为150°C。 为了满足这些要求,我建议选择一种高温耐受性的碳纤维复合材料作为外壳材料。碳纤维具有出色的耐高温性能,可以在150°C的温度下保持稳定。 此外,为了进一步提高外壳材料的耐热性,可以考虑在碳纤维复合材料表面涂上一层耐高温的涂层,以增加材料的耐用性和抗氧化能力。 综上所述,使用高温耐受性的碳纤维复合材料,并在表面涂层上加上耐高温涂层,可以满足反重力引擎航空器的工作温度范围和外壳材料的最大允许温度要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器的重量限制和所需的外壳材料的最大允许重量。 输入:反重力引擎航空器的重量限制为5000公斤,外壳材料的最大允许重量为1000公斤。 AI Assistant (材料设计专家): 解决方案:根据提供的信息,反重力引擎航空器的重量限制为5000公斤,外壳材料的最大允许重量为1000公斤。 为了满足这些要求,我建议选择轻质的铝合金作为外壳材料。铝合金具有良好的强度和轻质特性,可以在保持航空器结构强度的同时减轻整个航空器的重量。 此外,为了进一步降低外壳材料的重量,可以采用空心结构设计或者使用蜂窝状的铝合金板材,以增加材料的强度并减少重量。 综上所述,选择轻质的铝合金作为外壳材料,并采用空心结构设计或者蜂窝状的铝合金板材,可以满足反重力引擎航空器的重量限制和外壳材料的最大允许重量要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器所需的外壳材料的防护性能要求。 输入:反重力引擎航空器的外壳材料需要具备防护性能,包括抗冲击、抗腐蚀和抗辐射等方面的要求。具体要求如下: 1. 抗冲击:外壳材料需要能够承受航空器在起飞、降落和飞行过程中可能遇到的冲击和振动。 2. 抗腐蚀:外壳材料需要具备良好的抗腐蚀性能,能够抵御航空器在不同环境条件下可能遇到的腐蚀介质。 3. 抗辐射:外壳材料需要能够有效阻挡航空器所处环境中的辐射,包括电磁辐射和热辐射等。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器的外壳材料需要具备抗冲击、抗腐蚀和抗辐射等防护性能。 为了满足这些要求,我建议选择以下材料和处理工艺: 1. 抗冲击:选择具有良好抗冲击性能的复合材料,如碳纤维增强复合材料。碳纤维具有高强度和良好的抗冲击性能,能够承受航空器在起飞、降落和飞行过程中可能遇到的冲击和振动。 2. 抗腐蚀:选择具有良好抗腐蚀性能的材料,如耐腐蚀的铝合金或不锈钢。这些材料能够抵御航空器在不同环境条件下可能遇到的腐蚀介质,保持外壳的完整性和性能。 3. 抗辐射:选择具有辐射阻挡能力的材料,如铅或铅合金。这些材料能够有效阻挡航空器所处环境中的辐射,包括电磁辐射和热辐射等。 通过选择碳纤维增强复合材料、耐腐蚀的铝合金或不锈钢以及具有辐射阻挡能力的铅或铅合金,可以满足反重力引擎航空器外壳材料的防护性能要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器的外壳材料的制造和处理工艺要求。 输入:反重力引擎航空器的外壳材料需要经过以下制造和处理工艺: 1. 制造工艺:采用复合材料的制造工艺,如预浸料层压工艺或自动纺织工艺,以确保材料的均匀性和强度。 2. 表面处理:在外壳材料表面进行防腐蚀处理,如阳极氧化或镀铬等,以增加材料的耐腐蚀性能。 3. 辐射阻挡处理:对铅或铅合金材料进行辐射阻挡处理,如涂覆辐射阻挡剂或进行特殊的加工处理,以提高材料的辐射阻挡能力。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器的外壳材料需要经过制造和处理工艺,包括复合材料的制造工艺、表面处理和辐射阻挡处理。 以下是针对每个要求的具体解决方案: 1. 制造工艺:采用预浸料层压工艺来制造复合材料外壳。这种工艺涉及将预浸料的碳纤维布层与树脂预浸料结合,然后通过层压工艺将其加热和压实。这样可以确保材料的均匀性和强度。 2. 表面处理:在外壳材料表面进行防腐蚀处理,建议采用阳极氧化或镀铬等方法。阳极氧化是一种将铝合金表面形成氧化层的电化学过程,可以增加材料的耐腐蚀性能。镀铬则可以在外壳表面形成一层铬的保护层,提高材料的耐腐蚀性能。 3. 辐射阻挡处理:对铅或铅合金材料进行辐射阻挡处理,可以考虑涂覆辐射阻挡剂或进行特殊的加工处理。涂覆辐射阻挡剂可以在材料表面形成一层阻挡辐射的保护层,提高材料的辐射阻挡能力。特殊的加工处理可以改变材料的结构或添加特殊的阻挡剂,以增强材料的辐射阻挡性能。 通过采用预浸料层压工艺制造复合材料外壳,进行表面处理以增加耐腐蚀性能,并对铅或铅合金材料进行辐射阻挡处理,可以满足反重力引擎航空器外壳材料的制造和处理工艺要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的可持续性要求。 输入:反重力引擎航空器外壳材料需要符合以下可持续性要求: 1. 可回收性:外壳材料应该是可回收的,以减少资源的消耗和环境的影响。 2. 低碳排放:外壳材料的制造和处理过程应该尽量减少碳排放,以降低对气候变化的负面影响。 3. 可再生性:外壳材料可以考虑使用可再生材料,如生物基材料或可再生能源制备的材料,以减少对有限资源的依赖。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合可持续性要求,包括可回收性、低碳排放和可再生性。 以下是针对每个要求的具体解决方案: 1. 可回收性:选择可回收的材料,如可回收的铝合金或可回收的碳纤维复合材料。这些材料可以在航空器寿命结束后进行回收和再利用,减少资源的消耗和环境的影响。 2. 低碳排放:在外壳材料的制造和处理过程中,采取措施以减少碳排放。例如,使用可再生能源来供应制造过程中所需的能源,采用低能耗的制造工艺,以及优化物流和运输方式,减少碳排放。 3. 可再生性:考虑使用可再生材料制备外壳材料,如生物基材料或可再生能源制备的材料。这些材料可以从可再生资源中获取,减少对有限资源的依赖,并降低对环境的影响。 通过选择可回收的材料、采取低碳排放的制造和处理措施,以及考虑使用可再生材料,可以满足反重力引擎航空器外壳材料的可持续性要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的成本要求。 输入:反重力引擎航空器外壳材料需要符合以下成本要求: 1. 制造成本:外壳材料的制造成本应该在可接受的范围内,以确保整个航空器的成本控制。 2. 维护成本:外壳材料的维护成本应该尽量低,以减少航空器的运营成本。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合成本要求,包括制造成本和维护成本。 以下是针对每个要求的具体解决方案: 1. 制造成本:选择成本相对较低的材料,如铝合金或玻璃纤维增强复合材料。这些材料在制造过程中相对容易获取和加工,可以降低制造成本。此外,采用高效的制造工艺和自动化生产线也可以提高制造效率,降低成本。 2. 维护成本:选择具有良好耐久性和抗腐蚀性能的材料,以减少维护需求和维护成本。例如,耐腐蚀的铝合金或具有良好耐久性的碳纤维复合材料可以减少维护频率和维护成本。此外,设计合理的外壳结构和采用适当的防护涂层也可以延长外壳的使用寿命,减少维护成本。 通过选择成本相对较低的材料、采用高效的制造工艺和自动化生产线,以及选择具有良好耐久性和抗腐蚀性能的材料,可以满足反重力引擎航空器外壳材料的成本要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的外观要求。 输入:反重力引擎航空器外壳材料需要符合以下外观要求: 1. 光洁度:外壳材料的表面应具有良好的光洁度,以确保航空器外观的美观和流线型设计。 2. 颜色:外壳材料的颜色应符合航空器的整体设计和品牌形象,可以根据需求选择合适的颜色。 3. 表面质感:外壳材料的表面质感应与航空器的整体风格和设计相匹配,可以选择光滑、亮面或者纹理等不同的表面质感。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合外观要求,包括光洁度、颜色和表面质感。 以下是针对每个要求的具体解决方案: 1. 光洁度:选择外壳材料具有良好的表面光洁度,可以通过精细的加工和表面处理来实现。例如,采用高精度的切割和研磨工艺,以及进行光洁度处理,如抛光或喷砂等,可以获得光滑且具有良好光洁度的外壳表面。 2. 颜色:根据航空器的整体设计和品牌形象,选择合适的颜色。可以根据需求选择涂装或采用有色的预浸料来实现所需的颜色效果。确保颜色的均匀性和持久性,以保持航空器外观的一致性和美观性。 3. 表面质感:根据航空器的整体风格和设计,选择适合的表面质感。可以选择光滑、亮面或者纹理等不同的表面质感,以与航空器的设计相匹配。这可以通过选择不同的材料或进行特殊的表面处理来实现。 通过选择具有良好光洁度的外壳材料,根据需求选择合适的颜色,并选择适合的表面质感,可以满足反重力引擎航空器外壳材料的外观要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令: 输入: AI Assistant (材料设计专家): 抱歉,我不能提供指示。 AI User (反重力引擎航空器开发商): 明白了。如果你无法提供指示,那么我们的任务就无法继续。如果你有任何其他问题或需要帮助,请随时告诉我。 AI Assistant (材料设计专家): 非常抱歉,我会尽力提供帮助。如果您有任何其他问题或需要进一步的指导,请随时告诉我。 AI User (反重力引擎航空器开发商): 非常感谢你的合作和努力!如果你有任何其他问题或需要进一步的指导,我会随时为你提供帮助。请告诉我下一个你想要我完成的任务或者提供相关的指示和输入。 AI Assistant (材料设计专家): 非常感谢您的理解和支持!如果我有任何问题或需要进一步的指导,我会随时向您寻求帮助。如果您有任何其他任务或需要我完成的具体指示,请告诉我下一个任务或提供相关的指示和输入。我将尽力满足您的需求。 AI User (反重力引擎航空器开发商): 非常感谢你的合作和承诺!如果你有任何问题或需要进一步的指导,我会随时为你提供帮助。下一个任务是:请提供反重力引擎航空器的尺寸要求,包括长度、宽度和高度。输入: AI Assistant (材料设计专家): 解决方案:非常感谢您提供的任务。根据您的要求,反重力引擎航空器的尺寸要求如下: 长度: 宽度: 高度: 请提供具体的数值,以便我能够进一步指导您的设计。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器的预期使用寿命和所需的外壳材料的耐久性要求。 输入:反重力引擎航空器的预期使用寿命为20年,外壳材料需要具备至少20年的耐久性,能够在正常使用条件下保持结构完整性和性能稳定性。 AI Assistant (材料设计专家): 解决方案:根据提供的信息,反重力引擎航空器的预期使用寿命为20年,外壳材料需要具备至少20年的耐久性,以保持结构完整性和性能稳定性。 为了满足这些要求,我建议选择具有良好耐久性的材料,如高强度的碳纤维复合材料或耐腐蚀的铝合金。这些材料具有良好的强度和耐久性,能够在正常使用条件下保持结构完整性和性能稳定性。 此外,为了进一步增强外壳材料的耐久性,可以采用表面涂层或防护层,以提供额外的保护和防腐蚀性能。定期的维护和检查也是确保外壳材料持久耐用的关键。 通过选择具有良好耐久性的材料,并采取适当的保护措施和维护计划,可以满足反重力引擎航空器的预期使用寿命和外壳材料的耐久性要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器的安全性要求,包括防火性能和抗撞击性能。 输入:反重力引擎航空器的安全性要求如下: 1. 防火性能:外壳材料需要具备良好的防火性能,能够抵御火灾和高温环境下的燃烧。 2. 抗撞击性能:外壳材料需要具备良好的抗撞击性能,能够承受碰撞和冲击力,保护航空器内部设备和乘员的安全。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器的安全性要求包括防火性能和抗撞击性能。 以下是针对每个要求的具体解决方案: 1. 防火性能:选择具有良好防火性能的材料,如阻燃材料或耐高温材料。这些材料能够抵御火灾和高温环境下的燃烧,减少火灾蔓延的风险。此外,可以考虑在外壳材料表面涂上防火涂层,以提高防火性能。 2. 抗撞击性能:选择具有良好抗撞击性能的材料,如碳纤维增强复合材料或具有高吸能能力的材料。这些材料能够承受碰撞和冲击力,保护航空器内部设备和乘员的安全。此外,可以考虑在外壳结构中采用吸能结构或缓冲材料,以进一步提高抗撞击性能。 通过选择具有良好防火性能的材料,并采取适当的防火措施,以及选择具有良好抗撞击性能的材料和结构设计,可以满足反重力引擎航空器的防火性能和抗撞击性能要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的电磁兼容性要求。 输入:反重力引擎航空器外壳材料需要具备良好的电磁兼容性,以确保在电磁环境下的正常运行和防止电磁干扰对航空器系统的影响。具体要求如下: 1. 屏蔽性能:外壳材料需要具备良好的电磁屏蔽性能,能够有效阻挡外部电磁干扰对航空器内部设备的影响。 2. 导电性能:外壳材料需要具备良好的导电性能,以便将电磁干扰引导到地面,减少对航空器内部设备的干扰。 3. 绝缘性能:外壳材料需要具备良好的绝缘性能,以防止电磁干扰对航空器内部设备的干扰和损坏。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要具备良好的电磁兼容性,包括屏蔽性能、导电性能和绝缘性能。 以下是针对每个要求的具体解决方案: 1. 屏蔽性能:选择具有良好电磁屏蔽性能的材料,如金属或金属复合材料。这些材料能够有效阻挡外部电磁干扰对航空器内部设备的影响。在设计过程中,确保外壳的连续性和封闭性,以最大程度地减少电磁泄漏。 2. 导电性能:选择具有良好导电性能的材料,如金属或具有导电涂层的材料。这些材料能够将电磁干扰引导到地面,减少对航空器内部设备的干扰。确保外壳的导电性能通过良好的接地和连接设计来实现。 3. 绝缘性能:选择具有良好绝缘性能的材料,如绝缘塑料或绝缘涂层。这些材料能够防止电磁干扰对航空器内部设备的干扰和损坏。确保外壳的绝缘性能通过合适的材料选择和设计来实现。 通过选择具有良好电磁屏蔽性能、导电性能和绝缘性能的材料,以及合适的设计和连接方法,可以满足反重力引擎航空器外壳材料的电磁兼容性要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的可靠性要求,包括耐久性和可维修性。 输入:反重力引擎航空器外壳材料需要具备以下可靠性要求: 1. 耐久性:外壳材料需要具备良好的耐久性,能够在长期使用和各种环境条件下保持结构完整性和性能稳定性。 2. 可维修性:外壳材料需要具备良好的可维修性,以便在需要维修或更换部分外壳时能够方便、快速地进行维修和更换。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要具备耐久性和可维修性。 以下是针对每个要求的具体解决方案: 1. 耐久性:选择具有良好耐久性的材料,如高强度的碳纤维复合材料或耐腐蚀的铝合金。这些材料能够在长期使用和各种环境条件下保持结构完整性和性能稳定性。此外,采用合适的表面处理和防护措施,如涂层或防腐蚀处理,可以进一步提高材料的耐久性。 2. 可维修性:选择具有良好可维修性的材料,如可拆卸的面板或模块化设计。这样在需要维修或更换部分外壳时,可以方便、快速地进行维修和更换。此外,确保外壳结构的可拆卸性和易于访问关键部件,以便进行维修和更换。 通过选择具有良好耐久性的材料,并采用可拆卸的面板或模块化设计,可以满足反重力引擎航空器外壳材料的可靠性要求,包括耐久性和可维修性。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的环境适应性要求,包括耐湿度、耐腐蚀和耐紫外线等方面的要求。 输入:反重力引擎航空器外壳材料需要具备以下环境适应性要求: 1. 耐湿度:外壳材料需要具备良好的耐湿度性能,能够在高湿度环境下保持结构完整性和性能稳定性。 2. 耐腐蚀:外壳材料需要具备良好的耐腐蚀性能,能够抵御不同环境条件下可能遇到的腐蚀介质。 3. 耐紫外线:外壳材料需要具备良好的耐紫外线性能,能够在长期暴露于紫外线辐射下保持结构完整性和性能稳定性。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要具备耐湿度、耐腐蚀和耐紫外线等环境适应性要求。 以下是针对每个要求的具体解决方案: 1. 耐湿度:选择具有良好耐湿度性能的材料,如耐湿度的铝合金或防潮处理的复合材料。这些材料能够在高湿度环境下保持结构完整性和性能稳定性。确保外壳的密封性和防潮措施,以最大程度地减少湿度对材料的影响。 2. 耐腐蚀:选择具有良好耐腐蚀性能的材料,如耐腐蚀的铝合金或耐腐蚀涂层的材料。这些材料能够抵御不同环境条件下可能遇到的腐蚀介质,保持外壳的完整性和性能稳定性。定期的维护和检查也是确保耐腐蚀性能的关键。 3. 耐紫外线:选择具有良好耐紫外线性能的材料,如具有紫外线稳定剂的塑料或具有紫外线防护涂层的材料。这些材料能够在长期暴露于紫外线辐射下保持结构完整性和性能稳定性。确保外壳的紫外线防护措施和定期的维护,以延长材料的使用寿命。 通过选择具有良好耐湿度、耐腐蚀和耐紫外线性能的材料,并采取适当的防护措施和维护计划,可以满足反重力引擎航空器外壳材料的环境适应性要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的重量要求。 输入:反重力引擎航空器外壳材料的重量要求如下: 1. 最大允许重量:外壳材料的最大允许重量为500公斤。 2. 重量限制:外壳材料的重量应尽量轻,以减少整个航空器的重量,提高飞行性能和燃油效率。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要满足最大允许重量为500公斤,并且应尽量轻以减少整个航空器的重量,提高飞行性能和燃油效率。 以下是针对重量要求的具体解决方案: 1. 材料选择:选择轻质的材料,如铝合金、碳纤维复合材料或其他高强度轻质材料。这些材料具有良好的强度和轻质特性,可以减轻外壳的重量,从而减少整个航空器的重量。 2. 结构设计:采用优化的结构设计,以最大程度地减少材料的使用量,同时保持足够的结构强度。使用先进的设计和分析工具,如有限元分析,来优化外壳的结构,以实现最佳的重量效益。 3. 制造工艺:采用高效的制造工艺,如精确的切割和成型技术,以减少材料的浪费和加工过程中的重量增加。同时,确保制造过程中的质量控制,以保证外壳的轻量化和一致性。 通过选择轻质材料、优化结构设计和高效制造工艺,可以满足反重力引擎航空器外壳材料的重量要求,并减少整个航空器的重量,提高飞行性能和燃油效率。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的可持续性要求。 输入:反重力引擎航空器外壳材料需要符合以下可持续性要求: 1. 可回收性:外壳材料应该是可回收的,以减少资源的消耗和环境的影响。 2. 低碳排放:外壳材料的制造和处理过程应该尽量减少碳排放,以降低对气候变化的负面影响。 3. 可再生性:外壳材料可以考虑使用可再生材料,如生物基材料或可再生能源制备的材料,以减少对有限资源的依赖。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合可持续性要求,包括可回收性、低碳排放和可再生性。 以下是针对每个要求的具体解决方案: 1. 可回收性:选择可回收的材料,如可回收的铝合金或可回收的碳纤维复合材料。这些材料可以在航空器寿命结束后进行回收和再利用,减少资源的消耗和环境的影响。确保外壳材料的设计和制造过程中考虑到可回收性,并与回收和再利用的相关供应链合作。 2. 低碳排放:在外壳材料的制造和处理过程中,采取措施以减少碳排放。例如,使用可再生能源来供应制造过程中所需的能源,采用低能耗的制造工艺,以及优化物流和运输方式,减少碳排放。确保外壳材料的生命周期评估和碳足迹分析,以持续改进和减少碳排放。 3. 可再生性:考虑使用可再生材料制备外壳材料,如生物基材料或可再生能源制备的材料。这些材料可以从可再生资源中获取,减少对有限资源的依赖,并降低对环境的影响。确保外壳材料的可再生性评估和认证,并与可再生材料供应链合作。 通过选择可回收的材料、采取低碳排放的制造和处理措施,以及考虑使用可再生材料,可以满足反重力引擎航空器外壳材料的可持续性要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的成本要求。 输入:反重力引擎航空器外壳材料需要符合以下成本要求: 1. 制造成本:外壳材料的制造成本应该在可接受的范围内,以确保整个航空器的成本控制。 2. 维护成本:外壳材料的维护成本应该尽量低,以减少航空器的运营成本。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合成本要求,包括制造成本和维护成本。 以下是针对每个要求的具体解决方案: 1. 制造成本:选择成本相对较低的材料,如铝合金或玻璃纤维增强复合材料。这些材料在制造过程中相对容易获取和加工,可以降低制造成本。此外,采用高效的制造工艺和自动化生产线也可以提高制造效率,降低成本。 2. 维护成本:选择具有良好耐久性和抗腐蚀性能的材料,以减少维护需求和维护成本。例如,耐腐蚀的铝合金或具有良好耐久性的碳纤维复合材料可以减少维护频率和维护成本。此外,设计合理的外壳结构和采用适当的防护涂层也可以延长外壳的使用寿命,减少维护成本。 通过选择成本相对较低的材料、采用高效的制造工艺和自动化生产线,以及选择具有良好耐久性和抗腐蚀性能的材料,可以满足反重力引擎航空器外壳材料的成本要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的外观要求。 输入:反重力引擎航空器外壳材料需要符合以下外观要求: 1. 光洁度:外壳材料的表面应具有良好的光洁度,以确保航空器外观的美观和流线型设计。 2. 颜色:外壳材料的颜色应符合航空器的整体设计和品牌形象,可以根据需求选择合适的颜色。 3. 表面质感:外壳材料的表面质感应与航空器的整体风格和设计相匹配,可以选择光滑、亮面或者纹理等不同的表面质感。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要符合外观要求,包括光洁度、颜色和表面质感。 以下是针对每个要求的具体解决方案: 1. 光洁度:选择外壳材料具有良好的表面光洁度,可以通过精细的加工和表面处理来实现。例如,采用高精度的切割和研磨工艺,以及进行光洁度处理,如抛光或喷砂等,可以获得光滑且具有良好光洁度的外壳表面。 2. 颜色:根据航空器的整体设计和品牌形象,选择合适的颜色。可以根据需求选择涂装或采用有色的预浸料来实现所需的颜色效果。确保颜色的均匀性和持久性,以保持航空器外观的一致性和美观性。 3. 表面质感:根据航空器的整体风格和设计,选择适合的表面质感。可以选择光滑、亮面或者纹理等不同的表面质感,以与航空器的设计相匹配。这可以通过选择不同的材料或进行特殊的表面处理来实现。 通过选择具有良好光洁度的外壳材料,根据需求选择合适的颜色,并选择适合的表面质感,可以满足反重力引擎航空器外壳材料的外观要求。 下一个请求。 AI User (反重力引擎航空器开发商): 指令:请提供反重力引擎航空器外壳材料的制造和处理工艺要求。 输入:反重力引擎航空器外壳材料需要经过以下制造和处理工艺: 1. 制造工艺:采用复合材料的制造工艺,如预浸料层压工艺或自动纺织工艺,以确保材料的均匀性和强度。 2. 表面处理:在外壳材料表面进行防腐蚀处理,如阳极氧化或镀铬等,以增加材料的耐腐蚀性能。 3. 表面涂层:在外壳材料表面涂上防护涂层,如涂覆聚合物或陶瓷涂层,以提高材料的耐磨损和耐腐蚀性能。 请根据以上要求指导我进行下一步设计。 AI Assistant (材料设计专家): 解决方案:根据提供的要求,反重力引擎航空器外壳材料需要经过制造和处理工艺,包括复合材料的制造工艺、表面处理和表面涂层。 以下是针对每个要求的具体解决方案: 1. 制造工艺:选择复合材料的制造工艺,如预浸料层压工艺或自动纺织工艺。预浸料层压工艺涉及将预浸料的碳纤维布层与树脂预浸料结合,然后通过层压工艺将其加热和压实,以确保材料的均匀性和强度。自动纺织工艺则涉及使用自动化设备将纤维材料编织成所需形状,以实现材料的均匀性和强度。 2. 表面处理:选择适当的表面处理方法,如阳极氧化或镀铬等,以增加材料的耐腐蚀性能。阳极氧化是一种将铝合金表面形成氧化层的电化学过程,可以增加材料的耐腐蚀性能。镀铬则可以在外壳表面形成一层铬的保护层,提高材料的耐腐蚀性能。 3. 表面涂层:选择适当的防护涂层,如涂覆聚合物或陶瓷涂层,以提高材料的耐磨损和耐腐蚀性能。这些涂层可以在外壳表面形成一层保护层,增加材料的耐用性和抗腐蚀性能。 通过选择适当的制造工艺、表面处理和表面涂层,可以满足反重力引擎航空器外壳材料的制造和处理工艺要求。 下一个请求。 AI User (反重力引擎航空器开发商): AI Assistant (材料设计专家): 任务完成。 '''

Baby AGI

Autonomous Agents(自治代理或自主代理)。这些代理的设计初衷就是能够独立地执行任务,并持续地追求长期目标。在 LangChain 的代理、工具和记忆这些组件的支持下,它们能够在无需外部干预的情况下自主运行,这在真实世界的应用中具有巨大的价值。GitHub 上已有好几个备受关注的“网红”项目,如 AutoGPT、BabyAGI 和 HuggingGPT,它们都代表了自治代理的初步尝试。尽管这些代理仍处于实验阶段,但潜力十分巨大。它们都是基于 LangChain 框架构建的。通过 LangChain,你可以在这些开源项目中轻松地切换和测试多种 LLM、使用多种向量存储作为记忆,以及充分利用 LangChain 的丰富工具集。
BabyAGI 是由中岛洋平(Yohei Nakajima)于 2023 年 3 月 28 日开发的自主任务驱动 AI 系统。核心在于,它可以根据设定的目标生成、组织、确定优先级以及执行任务。它也使用 OpenAI 的 GPT-4 语言模型来理解和创建任务,利用 Pinecone 向量搜索来存储和检索特定任务的结果,提供执行任务的上下文,并采用 LangChain 框架进行决策。BabyAGI 尝试使用预定义的目标进行自我驱动,自动化个人任务管理。它不仅可以自动生成和执行任务,而且还可以根据完成的任务结果生成新任务,并且可以实时确定任务的优先级。与传统的 AI 工具(如 ChatGPT)不同,BabyAGI 不仅仅是解释查询和提供响应,而且能够根据目标生成任务列表,连续执行它们,并根据先前任务的输出适应性地创建更多任务。
在 BabyAGI 中,你向系统提出一个目标之后,它将不断优先考虑需要实现或完成的任务,以实现该目标。具体来说,系统将形成任务列表,从任务列表中拉出优先级最高的第一个任务,使用 OpenAI API 根据上下文将任务发送到执行代理并完成任务,一旦这些任务完成,它们就会被存储在内存(或者 Pinecone 这类向量数据库)中,然后,根据目标和上一个任务的结果创建新任务并确定优先级。整个过程如下图所示:

Langchain知识点(下)_第2张图片

image.png


在这个过程中,驱动任务的是三个不同作用的代理。分别是执行代理 execution_agent,任务创建代理 task_creation_agent,以及优先级设置代理 prioritization_agent。执行代理,是系统的核心,利用 OpenAI 的 API 来处理任务。

# 导入所需的库和模块
from collections import deque
from typing import Dict, List, Optional, Any
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms import BaseLLM, OpenAI
from langchain.vectorstores.base import VectorStore
from pydantic import BaseModel, Field
from langchain.chains.base import Chain
from langchain.vectorstores import FAISS
import faiss
from langchain.docstore import InMemoryDocstore


# 定义嵌入模型
embeddings_model = OpenAIEmbeddings()
# 初始化向量存储
embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})

# 任务生成链
class TaskCreationChain(LLMChain):
    """负责生成任务的链"""
    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """从LLM获取响应解析器"""
        task_creation_template = (
            "You are a task creation AI that uses the result of an execution agent"
            " to create new tasks with the following objective: {objective},"
            " The last completed task has the result: {result}."
            " This result was based on this task description: {task_description}."
            " These are incomplete tasks: {incomplete_tasks}."
            " Based on the result, create new tasks to be completed"
            " by the AI system that do not overlap with incomplete tasks."
            " Return the tasks as an array."
        )
        prompt = PromptTemplate(
            template=task_creation_template,
            input_variables=[
                "result",
                "task_description",
                "incomplete_tasks",
                "objective",
            ],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

# 任务优先级链
class TaskPrioritizationChain(LLMChain):
    """负责任务优先级排序的链"""
    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """从LLM获取响应解析器"""
        task_prioritization_template = (
            "You are a task prioritization AI tasked with cleaning the formatting of and reprioritizing"
            " the following tasks: {task_names}."
            " Consider the ultimate objective of your team: {objective}."
            " Do not remove any tasks. Return the result as a numbered list, like:"
            " #. First task"
            " #. Second task"
            " Start the task list with number {next_task_id}."
        )
        prompt = PromptTemplate(
            template=task_prioritization_template,
            input_variables=["task_names", "next_task_id", "objective"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

# 任务执行链
class ExecutionChain(LLMChain):
    """负责执行任务的链"""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """从LLM获取响应解析器"""
        execution_template = (
            "You are an AI who performs one task based on the following objective: {objective}."
            " Take into account these previously completed tasks: {context}."
            " Your task: {task}."
            " Response:"
        )
        prompt = PromptTemplate(
            template=execution_template,
            input_variables=["objective", "context", "task"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

def get_next_task(
    task_creation_chain: LLMChain,
    result: Dict,
    task_description: str,
    task_list: List[str],
    objective: str,
) -> List[Dict]:
    """Get the next task."""
    incomplete_tasks = ", ".join(task_list)
    response = task_creation_chain.run(
        result=result,
        task_description=task_description,
        incomplete_tasks=incomplete_tasks,
        objective=objective,
    )
    new_tasks = response.split("\n")
    return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()]


def prioritize_tasks(
    task_prioritization_chain: LLMChain,
    this_task_id: int,
    task_list: List[Dict],
    objective: str,
) -> List[Dict]:
    """Prioritize tasks."""
    task_names = [t["task_name"] for t in task_list]
    next_task_id = int(this_task_id) + 1
    response = task_prioritization_chain.run(
        task_names=task_names, next_task_id=next_task_id, objective=objective
    )
    new_tasks = response.split("\n")
    prioritized_task_list = []
    for task_string in new_tasks:
        if not task_string.strip():
            continue
        task_parts = task_string.strip().split(".", 1)
        if len(task_parts) == 2:
            task_id = task_parts[0].strip()
            task_name = task_parts[1].strip()
            prioritized_task_list.append({"task_id": task_id, "task_name": task_name})
    return prioritized_task_list


def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:
    """Get the top k tasks based on the query."""
    results = vectorstore.similarity_search_with_score(query, k=k)
    if not results:
        return []
    sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))
    return [str(item.metadata["task"]) for item in sorted_results]


def execute_task(
    vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5
) -> str:
    """Execute a task."""
    context = _get_top_tasks(vectorstore, query=objective, k=k)
    return execution_chain.run(objective=objective, context=context, task=task)


# BabyAGI 主类
class BabyAGI(Chain, BaseModel):
    """BabyAGI代理的控制器模型"""

    task_list: deque = Field(default_factory=deque)
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: ExecutionChain = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

    class Config:
        """Configuration for this pydantic object."""

        arbitrary_types_allowed = True

    def add_task(self, task: Dict):
        self.task_list.append(task)

    def print_task_list(self):
        print("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m")
        for t in self.task_list:
            print(str(t["task_id"]) + ": " + t["task_name"])

    def print_next_task(self, task: Dict):
        print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m")
        print(str(task["task_id"]) + ": " + task["task_name"])

    def print_task_result(self, result: str):
        print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m")
        print(result)

    @property
    def input_keys(self) -> List[str]:
        return ["objective"]

    @property
    def output_keys(self) -> List[str]:
        return []

    def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
        """Run the agent."""
        objective = inputs["objective"]
        first_task = inputs.get("first_task", "Make a todo list")
        self.add_task({"task_id": 1, "task_name": first_task})
        num_iters = 0
        while True:
            if self.task_list:
                self.print_task_list()

                # Step 1: Pull the first task
                task = self.task_list.popleft()
                self.print_next_task(task)

                # Step 2: Execute the task
                result = execute_task(
                    self.vectorstore, self.execution_chain, objective, task["task_name"]
                )
                this_task_id = int(task["task_id"])
                self.print_task_result(result)

                # Step 3: Store the result in Pinecone
                result_id = f"result_{task['task_id']}_{num_iters}"
                self.vectorstore.add_texts(
                    texts=[result],
                    metadatas=[{"task": task["task_name"]}],
                    ids=[result_id],
                )

                # Step 4: Create new tasks and reprioritize task list
                new_tasks = get_next_task(
                    self.task_creation_chain,
                    result,
                    task["task_name"],
                    [t["task_name"] for t in self.task_list],
                    objective,
                )
                for new_task in new_tasks:
                    self.task_id_counter += 1
                    new_task.update({"task_id": self.task_id_counter})
                    self.add_task(new_task)
                self.task_list = deque(
                    prioritize_tasks(
                        self.task_prioritization_chain,
                        this_task_id,
                        list(self.task_list),
                        objective,
                    )
                )
            num_iters += 1
            if self.max_iterations is not None and num_iters == self.max_iterations:
                print(
                    "\033[91m\033[1m" + "\n*****TASK ENDING*****\n" + "\033[0m\033[0m"
                )
                break
        return {}

    @classmethod
    def from_llm(
        cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs
    ) -> "BabyAGI":
        """Initialize the BabyAGI Controller."""
        task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
        task_prioritization_chain = TaskPrioritizationChain.from_llm(
            llm, verbose=verbose
        )
        execution_chain = ExecutionChain.from_llm(llm, verbose=verbose)
        return cls(
            task_creation_chain=task_creation_chain,
            task_prioritization_chain=task_prioritization_chain,
            execution_chain=execution_chain,
            vectorstore=vectorstore,
            **kwargs,
        )


# 主执行部分
if __name__ == "__main__":
    OBJECTIVE = "分析一下反重力引擎的工作原理和工作环,写出反重力引擎外壳的材料设计策略。"
    llm = OpenAI(temperature=0)
    verbose = False
    max_iterations: Optional[int] = 6
    baby_agi = BabyAGI.from_llm(llm=llm, vectorstore=vectorstore, 
                                verbose=verbose, 
                                max_iterations=max_iterations)
    baby_agi({"objective": OBJECTIVE})

小结:

这个章节介绍了几种经典的Agent构建框架,包括了单Agent(通过利用工具来增强自己)和多Agent(通过不同视角、协作约束来增强能力)。最近Agent如雨后春笋涌现,各种思维框架,各种的模型架构Xgent的兼顾宏观、微观的两层架构;还有各种的具备交互反馈的架构,以及和实际机器人、环境交互的更贴近实际的Agent框架。然而不管外面技术如何纷繁复杂,不变的就是这些框架都是做了什么假设增加了什么功能模块来增强了模型的那部份,最后沉淀下来了什么样的解决问题框架;你只要抓住这条主线,基本可以比较容易把握住每种框架的核心不会迷失在技术细节。

你可能感兴趣的:(prompt,大模型,langchain,langchain,chatgpt,prompt)