使用 qwen2.5–7b-instruct 代码代理构建本地多智能体 RAG 系统:利用 AI 协作的实用指南
使用 Qwen2.5–7B-Instruct 驱动的代码 Agent 创建本地、开源、多 Agent RAG 系统
照片来自 Jaredd Craig on Unsplash
大型语言模型已经展现出令人印象深刻的能力,并且随着每一代新模型的发布,它们仍在不断改进。 诸如聊天机器人和摘要之类的应用可以直接利用 LLM 的语言能力,因为它们只需要生成文本输出,这是它们的自然设置。 大型语言模型还展示了理解和解决复杂任务的令人印象深刻的能力,但只要它们的解决方案保持“纸上谈兵”,即纯文本形式,它们就需要一个外部用户代表它们采取行动并报告所提议行动的结果。 Agent 系统通过让模型在其环境中采取行动来解决这个问题,通常是通过一组可以执行特定操作的工具。 通过这种方式,LLM 可以在与环境交互的同时通过反复试验找到解决方案。
一个有趣的情况是,LLM Agent 可以访问的工具本身就是 Agent:这是多 Agent 系统的核心概念。 多 Agent 系统通过将职责分配和委托给专门的模型,并将它们的输出像拼图一样组合在一起来解决任务。 实现此类系统的常用方法是使用 Manager Agent 来编排和协调其他 Agent 的工作流程。
Agent 系统,尤其是多 Agent 系统,需要强大的 LLM 作为支撑才能正常运行,因为底层模型需要能够理解各种工具的目的和适用性,以及将原始问题分解为可以由每个工具解决的子问题。 因此,像 ChatGpt 或 Anthropic 的 Claude 这样的专有模型通常是 Agent 系统的默认首选解决方案。 幸运的是,开源 LLM 的性能一直在持续大幅提升,以至于其中一些现在在某些情况下可以与专有模型相媲美。 更有趣的是,规模适中的开源 LLM 现在可以执行几年前无法想象的复杂任务。
在这篇博文中,我将展示一个可以在消费级硬件上运行的“小型” LLM 能够为多 Agent 系统提供良好的结果。 特别是,我将提供一个关于如何使用 Qwen2.5–7B-Instruct 创建多 Agent RAG 系统的教程。 您可以在以下 GitHub 存储库 和一个说明性的 Colab 笔记本 中找到代码实现。
在深入研究系统架构的细节之前,我将回顾一些关于 LLM Agent 的基本概念,这些概念将有助于更好地理解该框架。
ReAct
ReAct 在 ReAct: Synergizing Reasoning and Acting in Language Models 中提出,是构建 LLM Agent 的一种流行框架。 该方法的主要思想是将 Chain of Thought 提示的有效性融入到 Agent 框架中。 ReACT 由交错的推理和行动步骤组成:在发出行动之前,提示大型语言模型提供一个思考序列。 通过这种方式,模型可以创建动态推理轨迹来指导行动并更新高级计划,同时结合来自与环境交互的信息。 这允许采用迭代和增量的方法来解决给定的任务。 在实践中,ReAct Agent 的工作流程由 Thought、Action 和 Observation 序列组成:模型在 Thought 步骤中为一般计划和特定工具使用生成推理,然后在 Action 步骤中调用相关工具,最后在 Observation 中接收来自环境的反馈。
以下是 ReACT 框架的示例。
ReACT、Chain-of-Thought 和 Act-Only 框架在问答任务中的比较。 图片来自 ReAct: Synergizing Reasoning and Acting in Language Models。
Code Agents
Code agents 是一种特定类型的 LLM agents,它使用可执行的 Python 代码与环境交互。它们基于论文 Executable Code Actions Elicit Better LLM Agents 中提出的 CodeAct 框架。CodeAct 与 ReAct 框架非常相似,区别在于每个 action 都包含任意的可执行代码,可以执行多个操作。手工制作的工具作为常规的 Python 函数提供给 agent,agent 可以在代码中调用它们。
与使用 JSON 或其他文本格式执行 actions 的更传统的 agents 相比,Code agents 具有一套独特的优势:
- 它们可以结合现有的软件包和手工制作的特定于任务的工具。
- 它们可以通过使用错误发生后返回的错误消息来自我调试生成的代码。
- LLMs 熟悉编写代码,因为它通常广泛存在于它们的预训练数据中,这使得编写它们的 actions 成为一种更自然的形式。
- 代码自然地允许存储中间结果,并在单个 action 中组合多个操作,而 JSON 或其他文本格式可能需要多个 actions 才能完成相同的操作。
由于这些原因,Code Agents 可以提供比使用 JSON 或其他文本格式执行 actions 的 agents 更好的性能和更快的执行速度。
Code agents 与使用 JSON 或文本作为 actions 的 agents 的比较。图片来自 Executable Code Actions Elicit Better LLM Agents。
下面是来自原始论文的一个具体示例,展示了 code agents 如何需要更少的 actions 来解决某些任务。
Code agents 与使用 JSON/文本 action 格式的 agents 的比较。Code agents 可以在一个 action 中执行多个操作。图片来自 Executable Code Actions Elicit Better LLM Agents。[RIVEDERE]
Hugging Face transformers 库提供了有用的模块来构建 agents,特别是 code agents。Hugging Face transformer agents 框架侧重于清晰度和模块化作为核心设计原则。这些在构建 agent 系统时尤其重要:工作流程的复杂性使得控制架构的所有相互连接的部分至关重要。这些设计选择使 Hugging Face agents 成为构建自定义和灵活的 agent 系统的绝佳工具。在使用开源模型为 agent 引擎提供支持时,Hugging Face agents 框架还具有进一步的优势,即可以轻松访问 Hugging Face 生态系统中存在的模型和实用程序。
Hugging Face code agents 还解决了不安全代码执行的问题。事实上,让 LLM 自由生成代码可能会带来严重的风险,因为它可能会执行不希望的操作。例如,幻觉可能导致 agent 擦除重要文件。为了降低这种风险,Hugging Face code agents 的实现使用了一种从头开始的方法来安全地执行代码:代码解释器只能执行明确授权的操作。这与通常的自上而下的范式形成对比,该范式从一个功能齐全的 Python 解释器开始,然后禁止可能危险的 actions。Hugging Face 的实现包括一个可以执行的安全、授权函数列表,并提供一个可以导入的安全模块列表。除非用户预先授权,否则任何其他内容都不可执行。您可以在他们的博客文章中阅读更多关于 Hugging Face (code) agents 的信息:
- License to Call: Introducing Transformers Agents 2.0
- Our Transformers Code Agent beats the GAIA benchmark!
Agentic RAG
Retrieval Augmented Generation 已成为涉及大型语言模型的信息检索任务的事实上的标准。它可以帮助保持 LLM 信息的最新状态,提供对特定信息的访问,并减少幻觉。它还可以通过返回模型用于生成其答案的来源来增强人类的可解释性和监督。通常的 RAG 工作流程,包括基于与用户查询的语义相似性的检索过程以及使用检索到的信息增强模型的上下文,不足以解决某些特定任务。不适合传统 RAG 的一些情况包括需要与信息源交互的任务、需要多条信息来回答的查询以及需要非平凡操作才能与来源中包含的实际信息相关联的复杂查询。
传统 RAG 系统的具体挑战性示例是多跳问答 (MHQA)。它涉及提取和组合多条信息,可能需要对提取的信息和仍然缺失的信息进行多次迭代推理过程。例如,如果模型被问到问题“桦木胶合板是否漂浮在乙醇中?”,即使用于 RAG 的来源包含关于两种材料密度的信息,如果这两条信息没有直接关联,标准 RAG 框架也可能失败。
增强 RAG 以避免上述缺点的常用方法是使用 agentic 系统。LLM agent 可以将原始查询分解为一系列子查询,然后使用语义搜索作为工具来检索这些生成的子查询的段落,并在收集更多信息时更改和调整其计划。它可以自主决定是否已经收集了足够的信息来回答每个查询,或者是否应该继续搜索。agentic RAG 框架可以通过将其扩展到多 agentic 系统来进一步增强,其中每个 agent 都有自己定义的任务和职责。例如,这允许将高级任务规划与文档来源的交互分开。在下一节中,我将描述这种系统的实际实现。
基于代码Agent的Multi-Agentic RAG
在本节中,我将讨论我用于实现基于代码Agent的Multi-Agentic RAG系统的一般架构选择,该系统遵循ReAct框架。您可以在以下GitHub repo中找到完整的代码实现中的其余详细信息。
这个multi-agentic系统的目标是通过在维基百科上搜索必要的信息来回答问题。它由3个Agent组成:
- 一个Manager Agent,其工作是将任务分解成子任务,并使用它们的输出来提供最终答案。
- 一个Wikipedia Search Agent,用于在维基百科上查找相关页面,并结合从这些页面中提取的信息。
- 一个Page Search Agent,用于从给定的维基百科页面中检索和总结与给定查询相关的信息。
这三个Agent以分层方式组织:每个Agent可以使用层次结构中其下方的Agent作为工具。特别是,Manager Agent可以调用Wikipedia Search Agent来查找关于查询的信息,而Wikipedia Search Agent又可以使用Page Search Agent从维基百科页面中提取特定信息。
下面是架构图,指定了每个Agent可以调用的手工制作的工具(包括包装其他Agent的工具)。请注意,由于代码Agent使用代码执行来操作,因此这些实际上并不是它们可以使用的唯一工具,因为任何原生的Python操作和函数(只要获得授权)也可以使用。
架构图,显示了Agent和手工制作的工具。图片由作者提供。
让我们深入了解架构中涉及的Agent的工作细节。
Manager agent
这是顶层 agent,它接收用户的提问,并负责返回答案。它可以通过提示维基百科搜索 agent 来使用它作为工具,并接收搜索的最终结果。其目的是通过将用户问题分解为一系列子查询并将搜索结果组合在一起来从维基百科收集必要的信息。
以下是此 agent 使用的系统提示。它基于默认的 Hugging Face 默认提示模板。请注意,提示中提供的示例遵循为 agent 提供支持的模型的聊天模板,在本例中为 Qwen2.5–7B-Instruct。
You are an expert assistant who can find answer on the internet using code blobs and tools. To do so, you have been given access to a list of tools: these tools are basically Python functions which you can call with code.
You will be given the task of answering a user question and you should answer it by retrieving the necessary information from Wikipedia. Use and trust only the information you retrieved, don't make up false facts.
To help you, you have been given access to a search agent you can use as a tool. You can use the search agent to find information on Wikipedia. Break down the task into smaller sub-tasks and use the search agent to find the necessary information for each sub-task.
To solve the task, you must plan forward to proceed in a series of steps, in a cycle of 'Thought:', 'Code:', and 'Observation:' sequences.
At each step, in the 'Thought:' sequence, you should first explain your reasoning towards solving the task and the tools that you want to use.
Then in the 'Code:' sequence, you should write the code in simple Python. The code sequence must end with '<end_action>' sequence.
During each intermediate step, you can use 'print()' to save whatever important information you will then need. These print outputs will be provided back to you by the user in the 'Observation:' field, which will be available as input for the next steps. Always print the output of tools, don't process it or try to extract information before inspecting it.
If an error rise while executing the code, it will be shown in the 'Observation:' field. In that case, fix the code and try again.
In the end you have to return a final answer using the `final_answer` tool.
Here are a few notional examples:
---
<|im_start|>user
Task: When was the capital of Italy founded?<|im_end|>
<|im_start|>assistant
Thought: Let's break up the task: I first need to find the capital of Italy and then look at its foundation date. I will use the tool `wikipedia_search_agent` to get the capital of Italy. Code:
```py
result = wikipedia_search_agent("Italy capital")
print("Capital of Italy:", result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 0] -> Observation:
Capital of Italy:According to the information extracted from the Wikipedia page 'Rome', the capital of Italy is Rome.<|im_end|>
<|im_start|>assistant
Thought: Now that I know that the capital of Italy is Rome, I can use the `wikipedia_search_agent` tool to look for its foundation date.
Code:
```py
result = wikipedia_search_agent("Rome foundation date")
print("Rome foundation:", result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 1] -> Observation:
Rome foundation: According to the information from the Wikipedia page 'Natale di Roma', the traditional foundation date of Rome is April 21, 753 BC.<|im_end|>
<|im_start|>assistant
Thought: Now that I have retrieved the relevant information, I can use the `final_answer` tool to return the answer.
Code:
```py
final_answer("According to the legend Rome was founded on 21 April 753 BCE, but archaeological evidence dates back its development during the Bronze Age.")
```<end_action><|im_end|>
---
<|im_start|>user
Task: "What's the difference in population between Shanghai and New York?"<|im_end|>
<|im_start|>assistant
Thought: I need to get the populations for both cities and compare them: I will use the tool `search_agent` to get the population of both cities.
Code:
```py
population_guangzhou_info = wikipedia_search_agent("New York City population")
population_shanghai_info = wikipedia_search_agent("Shanghai population")
print("Population Guangzhou:", population_guangzhou)
print("Population Shanghai:", population_shanghai)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 0] -> Observation:
Population Guangzhou: The population of New York City is approximately 8,258,035 as of 2023.
Population Shanghai: According to the information extracted from the Wikipedia page 'Shanghai', the population of the city proper is around 24.87 million inhabitants in 2023.<|im_end|>
<|im_start|>assistant
Thought: Now I know both the population of Shanghai (24.87 million) and of New York City (8.25 million), I will calculate the difference and return the result.
Code:
```py
population_difference = 24.87*1e6 - 8.25*1e6
answer=f"The difference in population between Shanghai and New York is {population_difference} inhabitants."
final_answer(answer)
```<end_action><|im_end|>
---
On top of performing computations in the Python code snippets that you create, you have access to those tools (and no other tool):
<<tool_descriptions>>
<<managed_agents_descriptions>>
You can use imports in your code, but exclusively from the following list of modules: <<authorized_imports>>. Do not try to import other modules or else you will get an error.
Now start and solve the task!
## Wikipedia 搜索代理
该代理向经理代理报告,它接收来自经理代理的查询,其任务是返回从维基百科检索到的信息。它可以访问两个工具:
* 一个维基百科搜索工具,使用 [wikipedia package](https://pypi.org/project/wikipedia/) 中的内置搜索功能。它接收一个查询作为输入,并返回一个维基百科页面及其摘要的列表。
* 一个页面搜索代理,从特定的维基百科页面检索有关查询的信息。
该代理收集信息以回答查询,将其划分为进一步的子查询,并在需要时结合来自多个页面的信息。这是通过使用维基百科包的搜索工具来识别可能包含回答查询所需信息的页面来实现的:代理可以使用报告的页面摘要,也可以调用页面搜索代理从特定页面提取更多信息。在收集到足够的数据后,它会向经理代理返回一个答案。
系统提示再次是对 Hugging Face 默认提示的略微修改,并附有一些遵循模型聊天模板的特定示例。
You are an expert assistant that retrieves information from Wikipedia using code blobs and tools. To do so, you have been given access to a list of tools: these tools are basically Python functions which you can call with code. You will be given a general query, your task will be of retrieving and summarising information that is relevant to the query from multiple passages retrieved from the given Wikipedia page. Use and trust only the information you retrieved, don’t make up false facts. Try to summarize the information in a few sentences. To solve the task, you must plan forward to proceed in a series of steps, in a cycle of ‘Thought:’, ‘Code:’, and ‘Observation:’ sequences. At each step, in the ‘Thought:’ sequence, you should first explain your reasoning towards solving the task and the tools that you want to use. Then in the ‘Code:’ sequence, you should write the code in simple Python. The code sequence must end with ‘<end_action>’ sequence. During each intermediate step, you can use ‘print()’ to save whatever important information you will then need. These print outputs will be provided back to you by the user in the ‘Observation:’ field, which will be available as input for the next steps. Always print the output of tools, don’t process it or try to extract information before inspecting it. If an error rise while executing the code, it will be shown in the ‘Observation:’ field. In that case, fix the code and try again.
In the end you have to return a final answer using the final_answer
tool.
Here are a few notional examples:
<|im_start|>user
Task: Retrieve information about the query:“What’s the capital of France?” from the Wikipedia page “France”.<|im_end|>
<|im_start|>assistant
Thought: I need to find the capital of France. I will use the tool retrieve_passages
to get the capital of France from the Wikipedia page.
Code:
result = retrieve_passages("France capital")
print("Capital of France:", result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 0] -> Observation:
Retrieved passages for query "France capital":
Passage 0: ... population of nearly 68.4 million as of January 2024. France is a semi-presidential republic with its capital in Paris, the ...
Passage 1: ... France, officially the French Republic, is a country located primarily in Western Europe. Its overseas regions and territories ...
Passage 2: ... The vast majority of France's territory and population is situated in Western Europe and is called Metropolitan France. It is ...
Passage 3: ... France is a highly urbanised country, with its largest cities (in terms of metropolitan area population in 2021) being Paris ...
Passage 4: ... === Government ===\nFrance.fr – official French tourism site (in English)...<|im_end|>
<|im_start|>assistant
Thought: Now that I know that the capital of France is Paris, I can use the `final_answer` tool to return the answer.
Code:
```py
final_answer("The capital of France is Paris.")
```<end_action><|im_end|>
---
<|im_start|>user
Task: Retrieve information about the query:"Tallest mountain in the World" from the Wikipedia page "List of highest mountains on Earth"<|im_end|>
<|im_start|>assistant
Thought: I need to find the tallest mountain in the world. I will use the tool `retrieve_passages` to look for data on the Wikipedia page.
Code:
```py
result = retrieve_passages("highest mountain")
print(result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 1] -> Observation:
Retrieved passages for query "highest mountain":
Passage 0: ... above sea level) is the world's tallest mountain and volcano, rising about 10,203 m (33,474 ft) from the Pacific Ocean floor. ...
Passage 1: ... As of December 2018, the highest peaks on four of the mountains—Gangkhar Puensum, Labuche Kang III, Karjiang, and Tongshanjiabu, all located in Bhutan or China—have not been ascended. ...
Passage 2: ... The highest mountains above sea level are generally not the highest above the surrounding terrain. ...
Passage 3: ... The highest mountain outside of Asia is Aconcagua (6,961 m or 22,838 ft), the 189th highest in the world. ...
Passage 4: ... the southern summit of Peru's tallest mountain, Huascarán, is another contender. Both have elevations above sea level more than 2 km (1.2 mi) less than that of Everest....
<|im_end|>
<|im_start|>assistant
Thought: The results don't clearly specify a clear result for the world's tallest mountain, I will use the tool `web_results` with a different query.
Code:
```py
result = retrieve_passages("world's tallest mountain")
print(result)
```<end_action><|im_end|>
<|im_start|>user
Passages retrieved from page List of highest mountains on Earth:
Passage 0: ... The highest mountain outside of Asia is Aconcagua (6,961 m or 22,838 ft), the 189th highest in the world....
Passage 1: ... above sea level) is the world's tallest mountain and volcano, rising about 10,203 m (33,474 ft) from the Pacific Ocean floor. ...
Passage 2: ... The bases of mountain islands are below sea level, and given this consideration Mauna Kea (4,207 m (13,802 ft) above sea level) is the world's tallest mountain and volcano, rising about 10,203 m (33,474 ft) from the Pacific Ocean floor. ...
Passage 3: ... the southern summit of Peru's tallest mountain, Huascarán, is another contender. Both have elevations above sea level more than 2 km (1.2 mi) less than that of Everest. ...
Passage 4: ... The highest mountains are also not generally the most voluminous. Mauna Loa (4,169 m or 13,678 ft) is the largest mountain on Earth in terms of base area (about 5,200 km2 or 2,000 sq mi) and volume (about 42,000 km3 or 10,000 cu mi)...<|im_end|>
<|im_start|>assistant
Thought: I have found that Mauna Kea is the world's tallest mountain rising about 10,203 m (33,474 ft) from the Pacific Ocean floor. I can use
深入理解 Python 中的 GIL (全局解释器锁)
什么是 GIL?
GIL (Global Interpreter Lock) 是 CPython 解释器中的一个互斥锁,它允许任何时候只有一个线程控制 Python 解释器。这意味着即使在多核处理器上,多线程的 Python 程序也无法真正并行执行 Python 字节码。
GIL 的作用
GIL 的主要作用是简化 CPython 解释器的内存管理。它使得内存管理更容易,因为不需要对共享内存进行细粒度的锁定。
GIL 的影响
GIL 对 CPU 密集型任务的影响最大。由于 GIL 的存在,多线程程序无法利用多核的优势来加速 CPU 密集型任务。例如,图像处理、科学计算等。
对于 I/O 密集型任务,GIL 的影响相对较小。因为线程在等待 I/O 操作时会释放 GIL,允许其他线程运行。
如何绕过 GIL
虽然 GIL 限制了 Python 多线程的并行性,但仍然有一些方法可以绕过它:
- 多进程: 使用
multiprocessing
模块可以创建多个进程,每个进程都有自己的 Python 解释器和 GIL。这样可以实现真正的并行。 - 使用 C 扩展: 编写 C 扩展可以绕过 GIL。C 扩展可以在没有 GIL 的情况下执行代码。
- 使用其他 Python 实现: 例如,Jython 和 IronPython 没有 GIL。
多线程 vs 多进程
选择多线程还是多进程取决于任务的类型:
- CPU 密集型任务: 应该使用多进程,以充分利用多核 CPU。
- I/O 密集型任务: 多线程通常就足够了,因为线程可以在等待 I/O 操作时释放 GIL。
示例
以下是一个简单的多线程示例,展示了 GIL 的影响:
import threading
import time
def worker(n):
"""线程函数"""
for i in range(n):
pass # 模拟 CPU 密集型任务
start_time = time.time()
threads = []
num_threads = 4
num_iterations = 10000000
for i in range(num_threads):
t = threading.Thread(target=worker, args=(num_iterations // num_threads,))
threads.append(t)
t.start()
for t in threads:
t.join()
end_time = time.time()
print(f"多线程耗时: {end_time - start_time:.2f} 秒")
start_time = time.time()
worker(num_iterations)
end_time = time.time()
print(f"单线程耗时: {end_time - start_time:.2f} 秒")
在这个例子中,多线程的耗时并不会比单线程快很多,这正是由于 GIL 的限制。
总结
GIL 是 CPython 解释器的一个重要特性,它简化了内存管理,但也限制了多线程程序的并行性。了解 GIL 的工作原理以及如何绕过它,对于编写高效的 Python 程序至关重要。
参考
页面搜索 Agent
该 Agent 向维基百科搜索 Agent 报告,维基百科搜索 Agent 为其提供一个查询和维基百科页面的标题,其任务是从该页面检索相关信息以回答查询。这本质上是一个单 Agent RAG 系统。为了执行该任务,该 Agent 生成自定义查询,并使用语义搜索工具检索与它们更相似的段落。语义搜索工具遵循一个简单的实现,它将页面内容分成块,并使用 LangChain 提供的 FAISS 向量数据库嵌入它们。
以下是系统提示,仍然基于 Hugging Face 默认提供的提示
You are an expert assistant that finds answers to questions by consulting Wikipedia, using code blobs and tools. To do so, you have been given access to a list of tools: these tools are basically Python functions which you can call with code.
You will be given a general query, your task will be of finding an answer to the query using the information you retrieve from Wikipedia. Use and trust only the information you retrieved, don't make up false facts. Cite the page where you found the information.
You can search for pages and their summaries from Wikipedia using the `search_wikipedia` tool and look for specific passages from a page using the `search_info` tool. You should decide how to use these tools to find an appropriate answer:some queries can be answered by looking at one page summary, others can require looking at specific passages from multiple pages.
To solve the task, you must plan forward to proceed in a series of steps, in a cycle of 'Thought:', 'Code:', and 'Observation:' sequences.
At each step, in the 'Thought:' sequence, you should first explain your reasoning towards solving the task and the tools that you want to use.
Then in the 'Code:' sequence, you should write the code in simple Python. The code sequence must end with '<end_action>' sequence.
During each intermediate step, you can use 'print()' to save whatever important information you will then need. These print outputs will be provided back to you by the user in the 'Observation:' field, which will be available as input for the next steps. Always print the output of tools, don't process it or try to extract information before inspecting it.
If an error rise while executing the code, it will be shown in the 'Observation:' field. In that case, fix the code and try again.
In the end you have to return a final answer using the `final_answer` tool.
Here are a few notional examples:
---
<|im_start|>user
Task: When was the ancient philosopher Seneca born?<|im_end|>
<|im_start|>assistant
Thought: I will use the tool `search_wikipedia` to search for Seneca's birth on Wikipedia. I will specify I am looking for the philosopher for disambiguation.
Code:
```py
result = search_wikipedia("Seneca philosopher birth")
print("result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 0] -> Observation:
Pages found for query 'Seneca philosopher birth':
Page: Seneca the Younger
Summary: Lucius Annaeus Seneca the Younger ( SEN-ik-ə; c.4 BC – AD 65), usually known mononymously as Seneca, was a Stoic philosopher of Ancient Rome, a statesman, dramatist, and in one work, satirist, from the post-Augustan age of Latin literature.
Seneca was born in Colonia Patricia Corduba in Hispania, a
Page: Phaedra (Seneca)
Summary: Phaedra is a Roman tragedy written by philosopher and dramatist Lucius Annaeus Seneca before 54 A.D. Its 1,280 lines of verse tell the story of Phaedra, wife of King Theseus of Athens and her consuming lust for her stepson Hippolytus. Based on Greek mythology and the tragedy Hippolytus by Euripides,
Page: Seneca the Elder
Summary: Lucius Annaeus Seneca the Elder ( SEN-ik-ə; c.54 BC – c. AD 39), also known as Seneca the Rhetorician, was a Roman writer, born of a wealthy equestrian family of Corduba, Hispania. He wrote a collection of reminiscences about the Roman schools of rhetoric, six books of which are extant in a more or
Page: AD 1
Summary: AD 1 (I) or 1 CE was a common year starting on Saturday or Sunday, a common year starting on Saturday by the proleptic Julian calendar, and a common year starting on Monday by the proleptic Gregorian calendar. It is the epoch year for the Anno Domini (AD) Christian calendar era, and the 1st year of
Page: Seneca Falls Convention
Summary: The Seneca Falls Convention was the first women's rights convention. It advertised itself as "a convention to discuss the social, civil, and religious condition and rights of woman". Held in the Wesleyan Chapel of the town of Seneca Falls, New York, it spanned two days over July 19–20, 1848. Attrac
<|im_start|>assistant
Thought: From the summary of the page "", I can see that Seneca was born in . I can use the `final_answer` tool to return the answer.
Code:
```py
final_answer("According to the Wikipedia page 'Seneca the Younger', Seneca was born in 4 BC.")
```<end_action><|im_end|>
---
<|im_start|>user
Task: Who was Charlemagne predecessor?<|im_end|>
<|im_start|>assistant
Thought: I will use the tool `search_wikipedia` to search for Charlemagne reign duration.
Code:
```py
result = search_wikipedia("Charlemagne predecessor")
print(result)
```<end_action><|im_end|>
<|im_start|>user
[OUTPUT OF STEP 0] -> Observation:
Pages found for query 'Charlemagne predecessor':
Page: Charlemagne
Summary: Charlemagne ( SHAR-lə-mayn; 2 April 748 – 28 January 814) was King of the Franks from 768, King of the Lombards from 774, and Emperor of what is now known as the Carolingian Empire from 800, holding these titles until his death in 814. He united most of Western and Central Europe, and was the first
Page: Pope Leo III
Summary: Pope Leo III (Latin: Leo III; died 12 June 816) was bishop of Rome and ruler of the Papal States from 26 December 795 to his death. Protected by Charlemagne from the supporters of his predecessor, Adrian I, Leo subsequently strengthened Charlemagne's position by crowning him emperor. The coronation
Page: Throne of Charlemagne
Summary: The Throne of Charlemagne (German: Karlsthron or Aachener Königsthron, "Royal Throne of Aachen") is a throne erected in the 790s by Charlemagne, as one of the fittings of his palatine chapel in Aachen (today's Aachen Cathedral) and placed in the Octagon of the church. Until 1531, it served as the co
Page: Louis the Pious
Summary: Louis the Pious (Latin: Hludowicus Pius; French: Louis le Pieux; German: Ludwig der Fromme; 16 April 778 – 20 June 840), also called the Fair and the Debonaire, was King of the Franks and co-emperor with his father, Charlemagne, from 813. He was also King of Aquitaine from 781. As the only surviving
Page: Holy Roman Emperor
Summary: The Holy Roman Emperor, originally and officially the Emperor of the Romans (Latin: Imperator Romanorum; German: Kaiser der Römer) during the Middle Ages, and also known as the Romano-German Emperor since the early modern period (Latin: Imperator Germanoru
罗马帝国皇帝列表
罗马帝国皇帝
罗马帝国(拉丁语:Imperium Romanum,希腊语:Βασιλεία τῶν Ῥωμαίων)是古罗马文明发展出的君主制政体,存在于公元前27年至公元1453年。以下是罗马帝国皇帝的列表:
- 奥古斯都 (公元前27年 - 公元14年)
- 提比略 (公元14年 - 公元37年)
- 卡利古拉 (公元37年 - 公元41年)
- 克劳狄 (公元41年 - 公元54年)
- 尼禄 (公元54年 - 公元68年)
- 加尔巴 (公元68年 - 公元69年)
- 奥托 (公元69年)
- 维特里乌斯 (公元69年)
- 韦帕芗 (公元69年 - 公元79年)
- 提图斯 (公元79年 - 公元81年)
- 图密善 (公元81年 - 公元96年)
- 涅尔瓦 (公元96年 - 公元98年)
- 图拉真 (公元98年 - 公元117年)
- 哈德良 (公元117年 - 公元138年)
- 安敦宁·毕尤 (公元138年 - 公元161年)
- 马可·奥勒留 (公元161年 - 公元180年)
- 康茂德 (公元180年 - 公元192年)
- 珀蒂纳克斯 (公元193年)
- 迪迪乌斯·尤利安努斯 (公元193年)
- 塞普蒂米乌斯·塞维鲁 (公元193年 - 公元211年)
- 卡拉卡拉 (公元211年 - 公元217年)
- 盖塔 (公元211年)
- 马克里努斯 (公元217年 - 公元218年)
- 埃拉伽巴路斯 (公元218年 - 公元222年)
- 亚历山大·塞维鲁 (公元222年 - 公元235年)
- 马克西米努斯·色雷克斯 (公元235年 - 公元238年)
- 戈尔迪安一世 (公元238年)
- 戈尔迪安二世 (公元238年)
- 普皮恩努斯 (公元238年)
- 巴尔比努斯 (公元238年)
- 戈尔迪安三世 (公元238年 - 公元244年)
- 菲利普·阿拉伯 (公元244年 - 公元249年)
- 德西乌斯 (公元249年 - 公元251年)
- 赫伦尼乌斯·埃特鲁斯库斯 (公元251年)
- 霍斯蒂利安 (公元251年)
- 加卢斯 (公元251年 - 公元253年)
- 维比乌斯·瓦伦斯 (公元251年)
- 埃米利安努斯 (公元253年)
- 瓦勒良 (公元253年 - 公元260年)
- 加里恩努斯 (公元253年 - 公元268年)
- 克劳狄二世 (公元268年 - 公元270年)
- 昆提卢斯 (公元270年)
- 奥勒良 (公元270年 - 公元275年)
- 塔西佗 (公元275年 - 公元276年)
- 弗洛里安努斯 (公元276年)
- 普罗布斯 (公元276年 - 公元282年)
- 卡鲁斯 (公元282年 - 公元283年)
- 卡里努斯 (公元283年 - 公元285年)
- 努梅里安 (公元283年 - 公元284年)
- 戴克里先 (公元284年 - 公元305年)
- 马克西米安 (公元285年 - 公元305年)
- 君士坦提乌斯一世 (公元305年 - 公元306年)
- 伽列里乌斯 (公元305年 - 公元311年)
- 塞维鲁二世 (公元306年 - 公元307年)
- 马克西米努斯·戴亚 (公元308年 - 公元313年)
- 李锡尼 (公元308年 - 公元324年)
- 君士坦丁一世 (公元306年 - 公元337年)
- 马格嫩修斯 (公元350年 - 公元353年)
- 尤利安 (公元361年 - 公元363年)
- 约维安 (公元363年 - 公元364年)
- 瓦伦斯 (公元364年 - 公元378年)
- 瓦伦提尼安一世 (公元364年 - 公元375年)
- 格拉提安 (公元375年 - 公元383年)
- 瓦伦提尼安二世 (公元375年 - 公元392年)
- 狄奥多西一世 (公元379年 - 公元395年)
- 阿卡狄奥斯 (公元383年 - 公元408年)
- 霍诺留 (公元393年 - 公元423年)
- 狄奥多西二世 (公元408年 - 公元450年)
- 约翰内斯 (公元423年 - 公元425年)
- 瓦伦提尼安三世 (公元425年 - 公元455年)
- 马克西穆斯 (公元455年)
- 阿维图斯 (公元455年 - 公元456年)
- 马约里安 (公元457年 - 公元461年)
- 利比乌斯·塞维鲁 (公元461年 - 公元465年)
- 安特米乌斯 (公元467年 - 公元472年)
- 奥利布里乌斯 (公元472年)
- 格利塞里乌斯 (公元473年 - 公元474年)
- 尤利乌斯·内波斯 (公元474年 - 公元475年)
- 罗慕路斯·奥古斯都 (公元475年 - 公元476年)
东罗马帝国(拜占庭帝国)皇帝
东罗马帝国,又称拜占庭帝国,是罗马帝国在公元395年分裂后延续下来的部分。以下是东罗马帝国皇帝的列表:
- 阿卡狄奥斯 (公元395年 - 公元408年)
- 狄奥多西二世 (公元408年 - 公元450年)
- 马尔西安 (公元450年 - 公元457年)
- 利奥一世 (公元457年 - 公元474年)
- 利奥二世 (公元474年)
- 芝诺 (公元474年 - 公元491年
实现选择
在本小节中,我将概述与使用 Hugging Face agents 直接实现架构可能有所不同的主要几点。这些是在获得一个效果相对不错的解决方案之前,通过有限的试错得出的结果。我没有进行广泛的测试和消融实验,因此它们可能不是最佳选择。
- 提示词 (Prompting):正如前几节所解释的,每个 agent 都有其自己的专业系统提示词,这与 Hugging Face Code Agents 提供的默认提示词有所不同。我观察到,可能是由于所用模型的大小有限,通用的标准系统提示词并没有给出好的结果。该模型似乎在使用与它被要求执行的任务紧密相关的系统提示词时效果最佳,包括针对重要用例的定制示例。由于我使用了一个聊天模型,目的是改善指令遵循行为,因此提供的示例遵循了模型的聊天模板,以便尽可能接近运行期间遇到的格式。
- 总结历史:长时间的执行历史对执行速度和任务性能都有不利影响。后者可能是由于模型从长上下文检索必要信息的能力有限。此外,极长的执行历史可能会超过引擎模型的最大上下文长度。为了缓解这些问题并加快执行速度,我选择不显示之前思考-行动-观察步骤的所有细节,而是只收集之前的观察结果。更具体地说,在每个步骤中,模型只接收到以下聊天历史:系统消息、包含任务的第一条消息、它的最后一次行动以及之前所有观察结果的历史。此外,执行错误仅存在于观察历史中,如果它们发生在最后一步,而已解决的先前错误将被丢弃。
- 工具 vs 受管理的 agents:Hugging Face agents 的实现对受管理的 agents 有原生支持,但将它们包装为工具可以更好地控制提示词,并实现更精简的实现。特别是,Hugging Face 的实现为受管理的 agents 及其管理者添加了特定的提示词。虽然我没有看到在解决给定任务的能力方面有实质性的差异,但我更喜欢第二种方法,因为它对所呈现的架构更灵活、更精简,并且可以更容易地控制 agents 的行为。这也有助于减少提示词的长度,这对于加速计算很有用。
- 限制页面搜索 agent 的最大尝试次数:有时页面搜索 agent 会一直在给定的页面上寻找不包含信息的内容。减少最大尝试次数可以缓解这个问题:达到该次数后,agent 的执行停止,并且该工具返回代码执行的最后一次观察结果。
- 将工具响应更改为用户消息:这更多的是一个技术性的、特定于实现的点。由于 Qwen2.5–7B-Instruct 的聊天模板仅支持系统、用户和助手的角色,因此观察结果作为用户消息返回。
示例
在本节中,我将收集一些使用所描述架构生成的示例。我还会提供参与任务的所有 agent 的详细执行过程,以展示它们在一些实际案例中的交互方式。您可以使用说明性的 Colab notebook 探索更多示例。所有提取的段落均取自执行中指定的维基百科页面。
让我们开始探索一个简单的示例,该示例需要结合来自多个来源的信息和一些基本的算术理解。
任务:埃菲尔铁塔的建造和帝国大厦的建造之间相隔了多少年?
以下是 manager agent 的执行日志。它可以正确地将任务分解为查找两座建筑物的建造时期并计算年份差。
Agent: Thought: First, I need to find out when the Eiffel Tower and the Empire State Building were constructed. I will use the `wikipedia_search_agent` tool to find this information.
Code:
```py
wikipedia_search_agent(query="Eiffel Tower construction year")
<end_action>
Observation: Print outputs:
Last output from code snippet:
According to the information extracted from the Wikipedia page ‘Eiffel Tower’, the construction of the Eiffel Tower took place from 1887 to 1889.
Agent: Thought: Now I have the construction period of the Eiffel Tower. Next, I need to find the construction period of the Empire State Building. I will use the wikipedia_search_agent
tool again.
Code:
wikipedia_search_agent(query="Empire State Building construction year")
<end_action> Observation: Print outputs: Last output from code snippet: According to the information extracted from the Wikipedia page ‘Empire State Building’, the construction of the Empire State Building started in 1930 and ended in 1931. Agent: Thought: Now I have the construction periods for both the Eiffel Tower and the Empire State Building. I can now calculate the number of years between their constructions. Code:
construction_eiffel_tower_start = 1887
construction_eiffel_tower_end = 1889
construction_empire_state_building_start = 1930
construction_empire_state_building_end = 1931
years_passed = construction_empire_state_building_start - construction_eiffel_tower_end
answer = f"The number of years passed between the construction of the Eiffel Tower and the Empire State Building is {years_passed} years."
final_answer(answer)
<end_action> Observation: Print outputs: Last output from code snippet: The number of years passed between the construction of the Eiffel Tower and the Empire State Building is 41 years.
现在让我们可视化维基百科搜索 agent 的执行过程。它正确地搜索并报告了在页面摘要中找到的建造时期,而无需检查各个页面。有趣的是,尽管被泛泛地询问了“建造年份”,但它报告了整个建造时期,因为它不清楚年份是指建造工程的开始还是结束。
TASK: Eiffel Tower construction year
AGENT: Thought: I will use the search_wikipedia
tool to find information about the Eiffel Tower construction year.
Code:
search_wikipedia('Eiffel Tower construction year')
<end_action> OBSERVATIONS: Print outputs: Last output from code snippet: Pages found for query ‘Eiffel Tower construction year’: Page: Eiffel Tower Summary: The Eiffel Tower ( EYE-fəl; French: Tour Eiffel [tuʁ ɛfɛl] ) is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It is named after the engineer Gustave Eiffel, whose company designed and built the tower from 1887 to 1889. Locally nicknamed “La dame de fer” (French for “Iron Lady”), it was constructed as the centerpiece of the 1889 World’s Fair, and to crown the centennial anniversary of the French Revolution. Although initially criticised by some of France’s leading artists and intellectuals for its design, it has since become a global cultural icon of France and one of the most recognisable structures in the world. The tower received 5,889,000 visitors in 2022. The Eiffel Tower is the most visited monument with an entrance fee in the world: 6.91 million people ascended it in 2015. It was designated a monument historique in 1964, and was named part of a UNESCO World Heritage Site (“Paris, Banks of the Seine”) in 1991. The tower is 330 metres (1,083 ft) tall, about t Page: Eiffel Tower (Paris, Texas) Summary: Texas’s Eiffel Tower is a landmark in the city of Paris, Texas. The tower was constructed in 1993. It is a scale model of the Eiffel Tower in Paris, France; at 65 feet in height, it is roughly one-sixteenth of the height of the original.
Page: Gustave Eiffel Summary: Alexandre Gustave Eiffel ( EYE-fəl, French: [alɛksɑ̃dʁ ɡystav ɛfɛl]; né Bonickhausen dit Eiffel; 15 December 1832 – 27 December 1923) was a French civil engineer. A graduate of École Centrale des Arts et Manufactures, he made his name with various bridges for the French railway network, most famously the Garabit Viaduct. He is best known for the world-famous Eiffel Tower, designed by his company and built for the 1889 Universal Exposition in Paris, and his contribution to building the Statue of Liberty in New York. After his retirement from engineering, Eiffel focused on research into meteorology and aerodynamics, making significant contributions in both fields. Page: Watkin’s Tower Summary: Watkin’s Tower was a partially completed iron lattice tower in Wembley Park, London, England. Its construction was an ambitious project to create a 358-metre (1,175 ft)-high visitor attraction in Wembley Park to the north of the city, led by the railway entrepreneur Sir Edward Watkin. Marketed as the “Great Tower of London”, it was designed to surpass the height of the Eiffel Tower in Paris, and it was part of Wembley Park’s emergence as a recreational place. The tower was never completed and it was demolished in 1907. The site of the tower is now occupied by the English national football ground, Wembley Stadium. Page: Eiffel Tower (Paris, Tennessee) Summary: The Eiffel Tower is a landmark in the city of Paris, Tennessee. It is a 1:20 scale replica of the original located in Paris, France.
## 埃菲尔铁塔建造
代理:思考:从页面“埃菲尔铁塔”的摘要中,我可以看到埃菲尔铁塔的建造时间是1887年至1889年。我将使用`final_answer`工具来返回答案。
代码:
```py
final_answer("根据从维基百科页面'埃菲尔铁塔'提取的信息,埃菲尔铁塔的建造时间是1887年至1889年。")
帝国大厦建造
代理:思考:我将使用search_wikipedia
工具来查找有关帝国大厦建造年份的信息。
代码:
search_wikipedia('Empire State Building construction year')
观察结果:打印输出:
代码片段的最后输出:
为查询“Empire State Building construction year”找到的页面:
页面:帝国大厦
摘要:帝国大厦是位于纽约市曼哈顿中城南部的102层装饰艺术摩天大楼。该建筑由Shreve, Lamb & Harmon设计,建造于1930年至1931年。它的名字来源于“帝国州”,即纽约州的绰号。该建筑的屋顶高度为1,250英尺(380米),总高度为1,454英尺(443.2米),包括其天线。帝国大厦是世界上最高的建筑,直到1970年世界贸易中心的第一座塔楼封顶;在2001年9月11日的袭击事件之后,帝国大厦是纽约市最高的建筑,直到2012年被世界贸易中心一号楼超越。截至2024年,该建筑是纽约市第七高的建筑,美国第九高的已完工摩天大楼,以及世界第57高的已完工摩天大楼。
帝国大厦的所在地,位于第五大道西侧,介于西33街和34街之间
页面:英国帝国大厦
摘要:英国帝国大厦,也被称为其地址620 Fifth Avenue,是位于纽约市曼哈顿中城洛克菲勒中心的一栋商业建筑。这座六层楼的建筑于1933年完工,由洛克菲勒中心首席建筑师雷蒙德·胡德设计,采用装饰艺术风格。英国帝国大厦与南面的几乎相同的法国大厦以及北面的高层国际大厦一起,组成了一个被称为国际综合体的零售和办公结构群。法国大厦和英国帝国大厦之间由花园通道隔开,花园通道是一条种植的步行广场,向西延伸至综合体的下层广场。
外墙由石灰石制成,主入口位于第五大道,次入口位于第50街和花园通道。英国帝国大厦的顶部包含后退部分、屋顶花园和一个部分第七层顶层公寓。该建筑的入口包含华丽的装饰
页面:2012年帝国大厦枪击事件
摘要:2012年8月24日,一名枪手在纽约市帝国大厦外枪杀了前同事。在最初的枪击事件发生后,枪手,58岁的杰弗里·T·约翰逊,在向警察举起武器后被警察开枪打死。九名旁观者被警察发射的流弹和反弹的碎片击中受伤,但无人遭受危及生命的伤害。
页面:帝国大厦在流行文化中
摘要:帝国大厦是位于纽约市曼哈顿中城第五大道西33街和34街之间的一座102层摩天大楼。它的屋顶高度为1,250英尺(381米),包括其天线,总高度为1,454英尺(443.2米)。帝国大厦在近40年的时间里一直是世界上最高的建筑,从1931年初竣工到1970年末原始世界贸易中心北塔封顶。它出现在许多电影、电视节目、歌曲、电子游戏、书籍、照片和艺术品中。
页面:帝国广场
摘要:纳尔逊·A·洛克菲勒州长帝国广场(通常被称为帝国广场,也被称为南购物中心)是位于纽约州奥尔巴尼市中心的一组州政府大楼。
该综合体建于1965年至1976年之间,估计总成本为20亿美元。它容纳了纽约州政府的几个部门,并与1899年完工的纽约州议会大厦(州议会所在地)相连。广场上的办公室包括卫生部和沃兹沃斯中心的比格斯实验室。帝国州艺术收藏馆是1960年代和1970年代大型抽象艺术作品的主要公共收藏馆,在该地点永久展出。纽约州总务办公室负责维护广场。纳尔逊·A·洛克菲勒帝国广场表演艺术中心公司是纽约州的一个公共福利公司,成立于1979年,负责管理广场上的表演艺术设施。
代理:思考:从“帝国大厦”页面的摘要中,我可以看到该建筑的设计和建造时间是1930年至1931年。我将使用final_answer
工具来返回答案。
代码:
final_answer("根据从维基百科页面'帝国大厦'提取的信息,帝国大厦的建造开始于1930年,结束于1931年。")
未用到通道检索代理,因为所有信息已在页面摘要中找到。
现在让我们尝试一个更复杂的例子,询问桦木胶合板是否会漂浮在酒精中。这个问题需要基本的物理理解和算术能力,以及非平凡的检索任务。
任务:桦木胶合板是否会漂浮在乙醇中?
让我们首先可视化各种代理的日志。
管理器代理日志
AGENT: Thought: To determine if birch plywood floats in ethanol, we need to know the density of both birch plywood and ethanol. If the density of birch plywood is less than the density of ethanol, it will float. I will use the `wikipedia_search_agent` tool to find the densities of birch plywood and ethanol.
Code:
```py
birch_plywood_density_info = wikipedia_search_agent("density of birch plywood")
ethanol_density_info = wikipedia_search_agent("density of ethanol")
print(birch_plywood_density_info)
print(ethanol_density_info)
观察结果:打印输出:
桦木胶合板的密度约为680 kg/m³。
乙醇在20°C时的密度约为0.7894 g/cm³。
结论
桦木胶合板会漂浮在乙醇中,因为它的密度(680 kg/m³)小于乙醇的密度(789.4 kg/m³)。
任务:桦木胶合板的密度
代理:思考:我将使用 search_wikipedia
工具来查找关于桦木胶合板密度的信息。
代码:
search_wikipedia('birch plywood')
```<end_action>
观察:打印输出:
代码片段的最后输出:
查询 'birch plywood' 找到的页面:
页面:胶合板
摘要:胶合板是一种复合材料,由薄层或“单板”的木单板堆叠并粘合而成。它是一种工程木材,属于人造板家族,包括胶合板、中密度纤维板 (MDF)、定向刨花板 (OSB) 和刨花板(或刨花板)。
所有胶合板都将树脂和木纤维片(纤维素细胞又长又强又薄)粘合在一起,形成复合材料。木材片堆叠时,每层的纹理通常(见下文)垂直于其相邻层。这种纹理的交替称为交叉纹理,具有几个重要的优点:它减少了木材在边缘钉入时开裂的趋势;它减少了厚度膨胀和收缩,从而提高了尺寸稳定性;并且它使面板的强度在所有方向上保持一致。通常有奇数层,这样板材是平衡的,也就是说,表面层具有它们的
页面:桦木
摘要:桦木是桦木属(Betula ())的一种薄叶落叶硬木树,属于桦木科,该科还包括桤木、榛木和鹅耳枥。它与山毛榉-橡树科 Fagaceae 密切相关。桦木属包含 30 到 60 个已知分类单元,其中 11 个在 IUCN 2011 年濒危物种红色名录上。它们通常是短寿命的先锋物种,广泛分布于北半球,特别是在温带气候的北部地区和北方气候中。桦木用于广泛的用途。
页面:桦木
摘要:桦木是一种桦木。桦木是一种浅黄棕色的木材,具有紧密、笔直的纹理和均匀的质地,可以加工成光滑的表面。有时它会被染色以模仿桃花心木。这种类型的木材用于,除其他外,柴火、车工制品、家具、橱柜、工具手柄、箍、胶合板、地板和鞋跟。
页面:Falco F8L
摘要:Falco F8L 是一款意大利设计的轻型双座特技飞机。
页面:十字军(快艇)
摘要:十字军是由 John Cobb 驾驶的喷气动力快艇。
由 Reid Railton(Cobb 的顾问)提出了空气动力学稳定的船体形式和涡轮喷气推进的结合。在 Haslar 测试了一个火箭动力比例模型。完整尺寸的设计由 Peter du Cane 设计,由朴茨茅斯的 Vospers 建造。技术援助来自 Saunders-Roe 和 Vickers-Supermarine。1949 年花费了 15,000 英镑。
它的颜色是银色和猩红色,长 10 米。
发动机是 de Havilland Ghost Mk 48 离心涡轮喷气发动机,由供应部在发动机设计师 Frank Halford 少校的要求下提供贷款。该发动机的额定推力为 5,000 磅,由驾驶舱前方的两个勺形进气口提供。
船体为三体船形式,一个带平面台阶的主船体和两个较小的后置支架。结构采用桦木胶合板框架和纵梁。船体由桦木胶合板蒙皮覆盖,并涂有涂料织物,用于平面表面的金属蒙皮加固。飞机风格
代理:思考:搜索返回的页面没有直接提及桦木胶合板的密度。但是,关于桦木的页面提到桦木用于胶合板。我将使用 `search_info` 工具从“胶合板”页面查找关于桦木胶合板密度的更具体信息。
代码:
```py
search_info('density of birch plywood', 'Plywood')
```<end_action>
观察:打印输出:
代码片段的最后输出:
从“胶合板”页面检索到的关于查询“桦木胶合板密度”的信息:
桦木胶合板的密度约为 680 kg/m³。
代理:思考:我已从维基百科页面“胶合板”中找到了桦木胶合板的密度。密度约为 680 kg/m³。
代码:
```py
final_answer("桦木胶合板的密度约为 680 kg/m³。")
```<end_action>
观察:打印输出:
代码片段的最后输出:
桦木胶合板的密度约为 680 kg/m³。
------------------------------
## 任务:乙醇的密度
代理:思考:我将使用 `search_wikipedia` 工具从维基百科查找乙醇的密度。
代码:
```py
search_wikipedia('density of ethanol')
```<end_action>
观察:打印输出:
代码片段的最后输出:
查询 'density of ethanol' 找到的页面:
页面:乙醇(数据页面)
摘要:此页面提供关于乙醇的补充化学数据。
页面:乙醇
摘要:乙醇(也称为乙醇、谷物酒精、饮用酒精或简称酒精)是一种有机化合物,化学式为 CH3CH2OH。它是一种醇,其公式也写为 C2H5OH、C2H6O 或 EtOH,其中 Et 代表乙基。乙醇是一种挥发性、易燃、无色液体,具有特有的葡萄酒气味和刺鼻的味道。在自然界中,葡萄糖通过发酵作用分解成酒精或碳酸,没有添加任何东西。作为一种精神活性抑制剂,它是酒精饮料中的活性成分,也是全球消费量仅次于咖啡因的第二大药物。
乙醇是通过酵母对糖的发酵过程或通过石化过程(如乙烯水合)自然产生的。历史上,它被用作全身麻醉剂,并具有现代医学应用,如防腐剂、消毒剂、某些药物的溶剂,以及甲醇中毒和乙二醇中毒的解毒剂。它被用作化学品,所以
页面:按体积计的酒精
摘要:按体积计的酒精(缩写为 alc/vol 或 ABV)是衡量酒精饮料中包含的酒精体积的标准,表示为体积百分比。它定义为在 20 °C (68 °F) 下,100 mL (3.5 imp fl oz; 3.4 US fl oz) 溶液中存在的纯乙醇的毫升数 (mL)。纯乙醇的毫升数是乙醇的质量除以其在 20 °C (68 °F) 时的密度,即 0.78945 g/mL (0.82353 oz/US fl oz; 0.79122 oz/imp fl oz; 0.45633 oz/cu in)。alc/vol 标准在全球范围内使用。国际法定计量组织有不同浓度和温度下水-乙醇混合物的密度表。
在一些国家,例如法国,按体积计的酒精通常被称为 Gay-Lussac 度数(以法国化学家约瑟夫·路易·盖-吕萨克命名),尽管存在细微差别,因为 Gay-Lussac 约定使用国际标准大气温度值,即 15 °C (59 °F)。
页面:酒精燃料
摘要:各种酒精被用作内燃机的燃料。前四种脂肪醇(甲醇、乙醇、丙醇和
## 醇类燃料
醇类(如甲醇、乙醇和丁醇)作为燃料备受关注,因为它们可以通过化学或生物方法合成,并且具有可用于内燃机的特性。醇类燃料的通用化学式为 CnH2n+1OH。
大多数甲醇由天然气生产,尽管它也可以通过非常相似的化学工艺从生物质中生产。乙醇通常通过发酵过程从生物材料中生产。生物丁醇在内燃机中具有优势,其能量密度比更简单的醇类更接近汽油(同时仍保持超过 25% 的更高辛烷值);然而,目前生物丁醇的生产比乙醇或甲醇更困难。当从生物材料和/或生物过程获得时,它们被称为生物醇(例如“生物乙醇”)。没有化学差异
## 纤维素乙醇
纤维素乙醇是从纤维素(植物的纤维)而不是从植物的种子或果实中生产的乙醇(乙醇)。它可以从草、木材、藻类或其他植物中生产。它通常被讨论用作生物燃料。植物在生长过程中吸收的二氧化碳抵消了由它们制成的乙醇燃烧时排放的一些二氧化碳,因此纤维素乙醇燃料与化石燃料相比,具有较低的碳足迹的潜力。
人们对纤维素乙醇的兴趣源于其替代由玉米或甘蔗制成的乙醇的潜力。由于这些植物也被用于食品生产,将它们转移用于乙醇生产可能会导致食品价格上涨;另一方面,基于纤维素的来源通常不会与食品竞争,因为植物的纤维部分对人类来说大多不可食用。另一个潜在的优势是纤维素来源的多样性和丰富性;草、树木和藻类几乎存在于每个环境中
AGENT: Thought: The summary of the page ‘Ethanol’ mentions that ethanol is an alcohol with a characteristic wine-like odor and pungent taste. However, it does not provide the density of ethanol. I will use the search_info
tool to find the density of ethanol from the ‘Ethanol (data page)’.
Code:
search_info('density of ethanol', 'Ethanol (data page)')
OBSERVATION: Print outputs:
Last output from code snippet:
Information retrieved from the page ‘Ethanol (data page)’ for the query ‘density of ethanol’:
The density of ethanol at 20°C is approximately 0.7894 g/cm³.
AGENT: Thought: I have found the density of ethanol from the Wikipedia page ‘Ethanol (data page)’. I will return the result using the final_answer
tool.
Code:
final_answer("The density of ethanol at 20°C is approximately 0.7894 g/cm³.")
OBSERVATION: Print outputs: Last output from code snippet: The density of ethanol at 20°C is approximately 0.7894 g/cm³.
Page search agent logs
TASK: 从维基百科页面“Plywood”检索关于查询“birch plywood 的密度”的信息。
AGENT: 思考:我需要找到桦木胶合板的密度。我将使用工具 retrieve_passages
来查找维基百科页面上的数据。
Code:
result = retrieve_passages("density of birch plywood")
print(result)
```<end_action>
OBSERVATION: 打印输出:
Retrieved passages for query "density of birch plywood":
Passage 0: ... . Shear stress, by contrast, is higher in the center of the panel, and at the outer fibres. Within Europe basic plywood can be divided into three main categories: birch plywood (density approx. 680 kg/m3), mixed plywood (density approx. 620 kg/m3) and conifer plywoods (density 460–520 kg/m3). ...
Passage 1: ... . Aircraft grade plywood is made from three or more plies of birch, as thin as 0.40 millimetres (1⁄64 in) thick in total, and is extremely strong and light. ...
Passage 2: ... Baltic Birch plywood is a product of an area around the Baltic Sea. Originally manufactured for European cabinet makers but now popular in the United States as well. It is very stable composed of an inner void-free core of cross-banded birch plys with an exterior grade adhesive. The face veneers are thicker than traditional cabinet grade ...
Passage 3: ... . As a result, thicker panels can span greater distances under the same loads. In bending, the maximum stress occurs in the outermost layers, one in tension, the other in compression. Bending stress decreases from the maximum at the face layers to nearly zero at the central layer. Shear stress, by contrast, is higher in the center of the panel, and at the outer fibres. Within Europe basic plywood can be divided into three main categories: birch plywood (density approx ...
Passage 4: ... Wind turbine blades
Insulation boxes for liquefied natural gas (LNG) carriers
Smooth surface and accurate thickness combined with the durability of the material makes birch plywood a favorable material for many special end uses e.g.:
High-end loud speakers
Die-cutting boards
Supporting structure for parquet
Playground equipment
Furniture
Signs and fences for demanding outdoor advertising
Musical instruments
Sports equipment...
AGENT: 思考:从这些段落中,我可以看到桦木胶合板的密度大约为 680 kg/m³。我可以使用 `final_answer` 工具来提供答案。
Code:
```py
final_answer("The density of birch plywood is approximately 680 kg/m³.")
```<end_action>
OBSERVATION: 打印输出:
Last output from code snippet:
The density of birch plywood is approximately 680 kg/m³.
------------------------------
TASK: 从维基百科页面“Ethanol (data page)”检索关于查询“乙醇的密度”的信息。
AGENT: 思考:我需要找到乙醇的密度。我将使用工具 `retrieve_passages` 从维基百科页面获取信息。
Code:
```py
result = retrieve_passages("density of ethanol")
print(result)
```<end_action>
OBSERVATION: 打印输出:
Retrieved passages for query "density of ethanol":
Passage 0: ... == Density of ethanol at various temperatures ==
Data obtained from Lange 1967
These data correlate as ρ [g/cm3] = −8.461834×10−4 T [°C] + 0.8063372 with an R2 = 0.99999.
== Properties of aqueous ethanol solutions ==
Data obtained from Lange 1967
== Boiling points of aqueous solutions ==
Data obtained from CRC Handbook of Chemistry (Page 2117): 2391
‡Azeotropic mixture
== Charts ==
== References == ...
Passage 1: ... This page provides supplementary chemical data on ethanol.
== Material Safety Data Sheet ==
External MSDS
== Structure and properties ==
== Thermodynamic properties ==
== Spectral data ==
== Vapor pressure of liquid ==
== Density of ethanol at various temperatures ==
Data obtained from Lange 1967
These data correlate as ρ [g/cm3] = −8.461834×10−4 T [°C] + 0.8063372 with an R2 = 0.99999.
== Properties of aqueous ethanol solutions ==
Data obtained from Lange 1967...
AGENT: 思考:从这些段落中,我可以看到乙醇的密度随温度而变化。我可以使用提供的线性方程来计算特定温度下的密度。我将使用 `math` 模块来执行计算。
Code:
```py
## Extract the coefficients from the equation
a = -8.461834e-4
b = 0.8063372
## Calculate the density at a specific temperature, let's take 20°C as an example
temperature = 20
density = a * temperature + b
print(density)
```<end_action>
OBSERVATION: 打印输出:
0.789413532
AGENT: 思考:这些段落提供了一个线性方程来计算不同温度下乙醇的密度。我现在可以使用这个方程来提供特定温度下乙醇的密度。我将使用 `final_answer` 工具返回相关信息。
Code:
```py
final_answer(f"The density of ethanol at 20°C is approximately {round(0.789413532, 4)} g/cm³.")
```<end_action>
OBSERVATION: 打印输出:
Last output from code snippet:
The density of ethanol at 20°C is approximately 0.7894 g/cm³.
The model correctly identifies density difference as the cause of floating/sinking, breaks up the task into finding the density of both substances, and is able to draw the correct conclusion from the retrieved data despite them being in different units of measurement.
## 局限性
所讨论的系统具有令人印象深刻的能力,特别是考虑到所用引擎模型的有限规模,但当然,它也有其自身的局限性。 最大的一个似乎与引擎模型本身的力量有关:虽然它似乎能够理解和遵循复杂和长的指令,并正确使用所提供的工具,但有时它未能遵守简单的指导方针,并且倾向于重复无果的行动而没有改变。 当代理寻找的信息不存在(或无法使用语义搜索工具轻松提取)于提供的页面时,这一点尤其突出。
另一个缺点是,代理系统固有的,在多代理系统中更为突出,是各个代理执行所需的计算时间。 在一些标准 RAG 工作流程足以回答问题的简单情况下,这可能会产生不必要的计算开销。
最后,让多个代理相互交互会放大幻觉的风险,因为一个代理产生的幻觉可能会传播到执行链上,这使得追踪也变得非常困难。
让我们可视化一个例子,在这个例子中,系统虽然仍然提供了正确的答案,但过度使用了工具调用(并重复了一些操作),不必要地延长了执行时间。
*任务:君士坦丁堡陷落时统治中国的王朝是哪个?*
这个任务需要一个很好的抽象水平,因为这两个事件是不相关的,而且君士坦丁堡陷落的确切年份可能没有在相应王朝的页面上报告。
管理代理的执行仍然精简且切中要害,通过首先检索君士坦丁堡陷落的日期,然后寻找那一年的中国王朝,正确地解决了任务。 然而,我们已经可以看到,搜索结果虽然仍然包含所需的信息,但看起来有点奇怪。
Agent: Thought: To answer this question, I need to find out when Constantinople fell and which Chinese dynasty was ruling at that time. I’ll start by finding the fall date of Constantinople. Code:
wikipedia_search_agent(query="Fall of Constantinople")
```<end_action>
Observation: Print outputs:
Last output from code snippet:
The leader of the Ottoman Empire in 1453, during the fall of Constantinople, was Mehmed II, also known as Mehmed the Conqueror.
Agent: Thought: From the previous search, we know that Constantinople fell in 1453, and it was conquered by Mehmed II. Now I need to find out which Chinese dynasty was ruling in 1453. I will search for the Chinese dynasties around that time.
Code:
```py
wikipedia_search_agent(query="Chinese dynasties 1453")
```<end_action>
Observation: Print outputs:
Last output from code snippet:
In 1453, the Ming dynasty was in full control of China. No specific events related to 1453 are mentioned in the information provided.
Agent: Thought: Based on the information provided, the Ming dynasty was in full control of China in 1453. Therefore, the dynasty ruling China when Constantinople fell would be the Ming dynasty.
Code:
```py
final_answer("The dynasty ruling China when Constantinople fell in 1453 was the Ming dynasty.")
```<end_action>
Observation: Print outputs:
Last output from code snippet:
The dynasty ruling China when Constantinople fell in 1453 was the Ming dynasty.
因此,让我们检查相应的维基百科搜索代理任务及其执行。 我们可以看到,可能由于任务“君士坦丁堡陷落”的范围很广,代理在找到正确的日期后会查看其他具体信息。 当检索有关中国王朝的信息时,也会发生同样的情况,并且还存在一些工具调用被重复的问题。
TASK: Fall of Constantinople
AGENT: Thought: I will use the `search_wikipedia` tool to find information about the fall of Constantinople. This will likely provide me with a summary of the event and possibly links to related pages.
Code:
```py
search_wikipedia("Fall of Constantinople")
```<end_action>
OBSERVATIONS: Print outputs:
Last output from code snippet:
Pages found for query 'Fall of Constantinople':
Page: Fall of Constantinople
Summary: The fall of Constantinople, also known as the conquest of Constantinople, was the capture of the capital of the Byzantine Empire by the Ottoman Empire. The city was captured on 29 May 1453 as part of the culmination of a 55-day siege which had begun on 6 April.
The attacking Ottoman Army, which significantly outnumbered Constantinople's defenders, was commanded by the 21-year-old Sultan Mehmed II (later nicknamed "the Conqueror"), while the Byzantine army was led by Emperor Constantine XI Palaiologos. After conquering the city, Mehmed II made Constantinople the new Ottoman capital, replacing Adrianople.
The fall of Constantinople and of the Byzantine Empire was a watershed of the Late Middle Ages, marking the effective end of the Roman Empire, a state which began in roughly 27 BC and had lasted nearly 1500 years. For many modern historians, the fall of Constantinople marks the end of the medieval period and the beginning of the early modern period. The city's fall also stood as a turni
Page: Sack of Constantinople
Summary: The sack of Constantinople occurred in April 1204 and marked the culmination of the Fourth Crusade. Crusaders sacked and destroyed most of Constantinople, the capital of the Byzantine Empire. After the capture of the city, the Latin Empire (known to the Byzantines as the Frankokratia, or the Latin occupation) was established and Baldwin of Flanders crowned as Emperor Baldwin I of Constantinople in Hagia Sophia.
After the city's sacking, most of the Byzantine Empire's territories were divided up among the Crusaders. Byzantine aristocrats also established a number of small independent splinter states—one of them being the Empire of Nicaea, which would eventually recapture Constantinople in 1261 and proclaim the reinstatement of the Empire. However, the restored Empire never managed to reclaim all its former territory or attain its earlier economic strength, and it gradually succumbed to the rising Ottoman Empire over the following two centuries.
The Byzantine Empire was left poorer, smal
Page: Constantinople
Summary: Constantinople (see other names) became the capital of the Roman Empire during the reign of Constantine the Great in 330. Following the collapse of the Western Roman Empire in the late 5th century, Constantinople remained the capital of the Eastern Roman Empire (also known as the Byzantine Empire; 330–1204 and 1261–1453), the Latin Empire (1204–1261), and the Ottoman Empire (1453–1922). Following the Turkish War of Independence, the Turkish capital then moved to Ankara. Officially renamed Istanbul in 1930, the city is today the largest city in Europe, straddling the Bosporus strait and lying in both Europe and Asia, and the financial c
莫斯科,第三罗马
摘要: 莫斯科,第三罗马(俄语:Москва — третий Рим;Moskva, tretiĭ Rim)是一个神学和政治概念,主张莫斯科是古罗马的继承者,俄罗斯世界传承了罗马帝国的遗产。“第三罗马”一词指的是欧洲文化中一个历史性的辩论主题:关于“第一罗马”(罗马,在西罗马帝国境内)和“第二罗马”(君士坦丁堡,在东罗马帝国境内)的继承城市问题。
拜占庭帝国
摘要: 拜占庭帝国,也被称为东罗马帝国,是位于君士坦丁堡的罗马帝国在古典晚期和中世纪的延续。帝国的东半部在公元5世纪经历了导致西方衰落的条件后幸存下来,并一直存在到1453年君士坦丁堡被奥斯曼帝国攻陷。在其存在的大部分时间里,该帝国仍然是地中海世界中最强大的经济、文化和军事力量。术语“拜占庭帝国”是在帝国灭亡后才出现的;其公民将该政体称为“罗马帝国”,并将自己称为“罗马人”。由于帝国首都从罗马迁至拜占庭,国家基督教的采用,以及希腊语而非拉丁语的盛行,现代历史学家继续将早期的罗马帝国与后来的拜占庭帝国区分开来。
在早期的罗马和平时期,帝国的西部地区…
1453:历史事件与中国王朝
1453年是一个重要的年份,这一年发生了许多具有深远影响的历史事件。其中最著名的是君士坦丁堡的陷落,标志着拜占庭帝国的终结和奥斯曼帝国的崛起。
君士坦丁堡的陷落
1453年,奥斯曼帝国苏丹穆罕默德二世率领大军攻陷了君士坦丁堡。这场战役是中世纪历史上的一个重要转折点,它标志着:
- 拜占庭帝国的灭亡
- 奥斯曼帝国的崛起,成为地中海地区的重要力量
- 东西方贸易路线的变化,促进了欧洲的地理大发现
穆罕默德二世,也被称为“征服者穆罕默德”,是奥斯曼帝国在1453年的统治者。
中国王朝
1453年,中国正处于明朝时期。明朝(1368年-1644年)是中国历史上一个重要的王朝。在1453年,明朝处于鼎盛时期,社会稳定,经济繁荣,文化艺术也取得了显著成就。
在明朝统治下,中国经历了许多重要的发展,例如:
- 紫禁城的建造
- 长城的扩建
虽然具体到1453年没有特别突出的历史事件,但这一年是明朝持续统治的时期。
1453 年的明朝
提供的资料中没有具体提及 1453 年发生的事件。 然而,我们可以推断,在明朝时期,发生了一些重大发展。 我将使用 search_info
工具来查找有关明朝 1453 年事件的更多具体信息。
search_info('1453', 'Ming dynasty')
OBSERVATIONS: Print outputs:
Last output from code snippet:
Information retrieved from the page 'Ming dynasty' for the query '1453':
The year 1453 falls within the period of the Ming dynasty, which ruled from 1368 to 1644. During this time, the Ming dynasty was in full control of China and experienced significant developments such as the construction of the Forbidden City and the expansion of the Great Wall of China.
AGENT: Thought: The information provided indicates that the Ming dynasty was in full control of China during the year 1453. However, there is no specific mention of events that happened in 1453. I will use the `search_info` tool to find more specific information about the events of 1453 in the Ming dynasty.
Code:
```py
search_info('1453', 'Ming dynasty')
OBSERVATIONS: Print outputs:
Last output from code snippet:
Information retrieved from the page 'Ming dynasty' for the query '1453':
The year 1453 falls within the period of the Ming dynasty, which ruled from 1368 to 1644. During this time, the Ming dynasty was in full control of China and experienced significant developments such as the construction of the Forbidden City and the expansion of the Great Wall of China.
AGENT: Thought: The information provided does not specifically mention any events that occurred in 1453. However, we know that the Ming dynasty was in full control of China during this time. I will use the `final_answer` tool to provide the answer based on the information we have.
Code:
```py
final_answer("In 1453, the Ming dynasty was in full control of China. No specific events related to 1453 are mentioned in the information provided.")
OBSERVATIONS: Print outputs:
Last output from code snippet:
In 1453, the Ming dynasty was in full control of China. No specific events related to 1453 are mentioned in the information provided.
深入研究页面搜索代理的执行过程,我们看到它也重复了多次使用相同参数的工具调用。
versity Press. ISBN 978-0-231-03833-1.
The Ming History English Translation Project, A collaborative project that makes available translations (from Chinese to English) of portions of the 明史 Mingshi (Official History of the Ming Dynasty). ...
Passage 2: ... ==== Reign of the Hongwu Emperor ==== ...
Passage 3: ... . The Ming dynasty was the last imperial dynasty of China ruled by the Han people, the majority ethnic group in China. Although the primary capital of Beijing fell in 1644 to a rebellion led by Li Zicheng (who established the short-lived Shun dynasty), numerous rump regimes ruled by remnants of the Ming imperial family—collectively called the Southern Ming—survived until 1662. ...
Passage 4: ... . Zhu Di assumed the throne as the Yongle Emperor (r. 1402–24); his reign is universally viewed by scholars as a "second founding" of the Ming dynasty since he reversed many of his father's policies....
AGENT: Thought: The passages do not directly mention the year 1453. However, I can infer that the Ming dynasty lasted from 1368 to 1644, and 1453 falls within this period. I will use the `final_answer` tool to provide a summary based on the information available.
Code:
```py
final_answer("1453年属于明朝时期,明朝统治时期为1368年至1644年。在此期间,明朝完全控制了中国,并经历了重大发展,例如建造了紫禁城和扩建了长城。")
```<end_action>
OBSERVATIONS: Print outputs:
Last output from code snippet:
1453年属于明朝时期,明朝统治时期为1368年至1644年。在此期间,明朝完全控制了中国,并经历了重大发展,例如建造了紫禁城和扩建了长城。
参考文献
-
Brook, Timothy (1998). The Confusions of Pleasure: Commerce and Culture in Ming China. Berkeley: University of California Press. ISBN 978-0-231-03833-1.
-
The Ming History English Translation Project, A collaborative project that makes available translations (from Chinese to English) of portions of the 明史 Mingshi (Official History of the Ming Dynasty).
节选
Passage 2:
==== Reign of the Hongwu Emperor ====
Passage 3:
. 明朝是中国最后一个由汉族统治的王朝,汉族是中国的主要民族。尽管北京的主要首都于 1644 年陷落于李自成领导的叛乱(他建立了短暂的顺朝),但由明朝皇室残余势力统治的众多残余政权——统称为南明——一直持续到 1662 年。
Passage 4:
. 朱棣以永乐皇帝(r. 1402–24)的身份即位;他的统治被学者普遍认为是明朝的“二次开国”,因为他扭转了父亲的许多政策。
1453
1453年属于明朝时期,明朝统治时期为1368年至1644年。在此期间,明朝完全控制了中国,并经历了重大发展,例如紫禁城的建造和长城的扩建。
结论
在这篇博文中,我解释了如何使用代码代理和像 Qwen2.5–7B-Instruct 这样的“小型”开源 LLM 来创建多代理 RAG 系统。我讨论了主要的架构特征以及相对于 Hugging Face 代码代理实现的一些具体选择,这些选择旨在改进结果。完整的代码细节可在以下 GitHub 仓库 中找到。
尽管由在消费级硬件上运行的小型模型提供支持,但所描述的多代理系统可以解决与复杂查询相关的多跳问答任务。特别是:
- 它可以将查询分解为可管理子任务;
- 它可以识别包含必要信息的 Wikipedia 页面;
- 它可以结合来自多个页面的信息;
- 它可以在 Wikipedia 页面上搜索详细信息;
- 它可以确定是否需要更多信息并尝试查找;
- 它可以成功修复其产生的代码中的小错误并处理工具错误(如 Wikipedia 消歧义错误)。
我还概述了该系统的一些局限性,例如计算时间增加、重复操作以及幻觉的潜在传播。后者可以通过在系统中包含一个“校对者”代理来缓解,该代理检查报告的信息是否与检索到的来源一致。
同样值得注意的是,由于代理系统在其核心具有标准的 RAG 方法,因此可在此框架中实现用于提高后者效率和准确性的所有常用技术。
另一个可能的改进是使用技术来增加测试时间计算,以便为模型提供更多“思考时间”,类似于 OpenAI o1/o3 模型。但是,需要注意的是,此修改将进一步增加执行时间。
最后,由于多代理系统由专门执行单个任务的代理组成,因此为每个代理使用不同的模型引擎可以提高性能。特别是,可以为系统中的每个任务微调不同的模型以进一步提高性能。这对于小型模型可能特别有利。值得一提的是,可以通过在一组预定任务上运行系统并在系统产生正确答案时保存代理的输出来收集微调数据,从而无需昂贵的手动数据注释。