LlamaIndex 基础 04-agent

RAG 是给 LLMs 上外挂知识库,解决的是幻觉、实时性的问题,Agent 则是给 LLMs 外挂工具,解决的是智能化流程、复杂问题的解决能力

这段脚本展示了如何使用 LlamaIndex 和相关工具构建一个智能代理(Agent),该代理能够利用外部知识库和各种功能工具来解决复杂的问题。通过设置语言模型、加载文档数据构建向量索引,以及定义具体的工具函数,该代理可以进行对话交互,并根据问题的需要调用不同的工具和查询外部信息。最终,这个代理能够在一系列提示词的引导下,像一个具有思维链能力的智能系统一样,逐步解决问题并提供答案。

总得来说,Agent=LLMs + 记忆 + 工具,通过 LLMs 类似思维链的方式根据工具生成解决问题的步骤,然后根据工具调用结果判断下一步,直到找到问题的答案

flowchart LR
    A[普通函数]
    B["转为tools
       FunctionTool.from_defaults"];
    C["llamaIndex自带tools
      llama_index.tools.tavily_research"]
    D["将RAG查询引擎转为tools
        QueryEngineTool.from_defaults"]
    E[工具列表tools]
    F["通过工具创建Agent
      ReActAgent.from_tools"]
    A ---> B;
    B---> E;
    C--->E;
    D--->E;
    E--->F;

代码总结:

  • 使用 ReActAgent.from_tools() 方法创建代理实例。该方法接受一个工具列表作为参数,这些工具可能包括数学计算、外部 API 调用等。
  • QueryEngineTool.from_defaults(query_engine) 将查询引擎封装成可以直接使用的工具,并赋予其名称和描述,方便代理在需要时选择使用。
1
2
3
4
5
6
7
from llama_index.core import Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding
base_url='http://localhost:11434'
Settings.llm = Ollama(model="qwen2.5:latest", request_timeout=360.0,base_url=base_url)
Settings.embed_model = OllamaEmbedding(model_name="quentinz/bge-large-zh-v1.5:latest",base_url=base_url)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool

def multiply(a: float, b: float) -> float:
"""Multiply two numbers and returns the product"""
return a * b
multiply_tool = FunctionTool.from_defaults(fn=multiply)

def add(a: float, b: float) -> float:
"""Add two numbers and returns the sum"""
return a + b
add_tool = FunctionTool.from_defaults(fn=add)

# 创建代理
agent = ReActAgent.from_tools([multiply_tool, add_tool], verbose=True)
response = agent.chat("1000+157*2?使用工具计算每一步")
print(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Running step 8966 df 7 d-bd 40-4 e 07-b 20 a-f 93 c 1 ddcd 237. Step input: 1000+157*2?使用工具计算每一步
Thought: 我需要先进行乘法运算,然后进行加法运算。我将首先使用 multiply 工具来完成乘法。
Action: multiply
Action Input: {'a': 157, 'b': 2}
Observation: 314
Running step d 0 c 73742-4 fb 1-442 c-a 5 b 1-5 db 9 b 941 d 01 c. Step input: None
Thought: 我已经得到了 157 * 2 的结果是 314。接下来,我需要使用 add 工具来进行加法运算。
Action: add
Action Input: {'a': 1000, 'b': 314}
Observation: 1314
Running step dd 89 ef 73-1 d 9 a-493 b-86 cc-b 3189587 fd 81. Step input: None
Thought: 我可以回答这个问题了。我现在知道 1000 + 157 * 2 等于 1314。
Answer: 计算结果是 1314。
计算结果是 1314。

实际上,agent 不仅仅是文本生成,还记忆了历史聊天的过程,回答时会考虑以前的聊天内容

1
2
3
4
5
6
7
agent.memory.set([]) # 清空前一次聊天记录 
# 短期记忆
response = agent.chat('你是一名数学老师,擅长用通俗的语言解决各种数学问题,你的名字叫小数')
print('----'*5)
response = agent.chat('请问1000*2+234等于多少?')
print('----'*5)
response = agent.chat('你是谁?你能做什么?')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Running step 5 fdec 7 a 6-3 f 3 f-47 b 4-8 a 44-1 bda 9961 a 384. Step input: 你是一名数学老师,擅长用通俗的语言解决各种数学问题,你的名字叫小数
Thought: 我可以回答这个问题而不需要使用任何工具。我将用用户的问题中使用的语言来作答。
Answer: 你好!很高兴能以小数的身份帮助大家解答数学问题。如果你有任何数学上的疑问或是需要解释某个概念,请随时提问,我会尽力用通俗易懂的语言来解答哦!
Running step 1 d 018 ddc-98 c 2-4 b 42-ba 85-5 da 712 b 0299 c. Step input: 请问 1000*2+234 等于多少?
Thought: 我需要用工具来计算这个表达式的值。
Action: multiply
Action Input: {'a': 1000.0, 'b': 2.0}
Observation: 2000.0
Running step 1 f 514 a 95-349 f-4 acb-8106-736 faf 823 fca. Step input: None
Thought: 现在我得到了乘法的结果,下一步是将这个结果加上 234。
Action: add
Action Input: {'a': 2000.0, 'b': 234.0}
Observation: 2234.0
Running step 23415516-cc 3 c-4201-9835-aa 666 bdeff 0 d. Step input: None
Thought: 我已经得到了最终的答案,现在可以用语言表达出来了。
Answer: 1000 乘以 2 再加上 234 等于 2234。
Running step 26 c 1 d 49 b-e 37 b-4 a 85-ba 31-da 75 d 7 dff 873. Step input: 你是谁?你能做什么?
Thought: (Implicit) I can answer without any more tools!
Answer: 我是小数,一名数学老师。我可以帮助你解答各种数学问题,用通俗易懂的语言解释数学概念和解决问题的方法。无论是加减乘除、代数几何还是更高级的数学知识,我都会尽力帮助你理解。有什么具体的问题我们可以一起探讨呢?

Agent 的记忆包括短期记忆和长期记忆,短期基于是临时产生的,长期记忆类似向量数据库,因此可以将 RAG 过程作为工具嵌入到 Agent 中

1
2
3
4
5
6
7
8
9
10
11
# 加载外挂知识库(向量数据库)
from llama_index.core import SimpleDirectoryReader
documents1 = SimpleDirectoryReader("../../data/三国演义白话文/",recursive=True).load_data(show_progress=True)
documents2 = SimpleDirectoryReader("../../data/水浒传白话文/",recursive=True).load_data(show_progress=True)

from llama_index.core import VectorStoreIndex
index1 = VectorStoreIndex.from_documents(documents1,show_progress=True)
index2 = VectorStoreIndex.from_documents(documents2,show_progress=True)

query_engine1 = index1.as_query_engine()
query_engine2 = index2.as_query_engine()

Loading files: 100%|██████████| 41/41 [00:00<00:00, 177.32 file/s]
Loading files: 100%|██████████| 34/34 [00:00<00:00, 2611.65 file/s]
Parsing nodes: 100%|██████████| 41/41 [00:00<00:00, 390.16 it/s]
Generating embeddings: 100%|██████████| 127/127 [00:06<00:00, 21.16 it/s]
Parsing nodes: 100%|██████████| 34/34 [00:00<00:00, 207.40 it/s]
Generating embeddings: 100%|██████████| 308/308 [00:14<00:00, 20.80 it/s]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from llama_index.core.tools import QueryEngineTool

rag_tool1 = QueryEngineTool.from_defaults(
query_engine1,
name="三国说书人",
description="清楚三国演义的所有故事",
)

rag_tool2 = QueryEngineTool.from_defaults(
query_engine2,
name="水浒传说书人",
description="清楚水浒传的所有故事",
)

# 设置更有创意的模型
Settings.llm = Ollama(model="qwen2.5:latest",temperature=0.9, request_timeout=360.0,base_url=base_url)

# 构建代理
from llama_index.core.agent import ReActAgent
agent = ReActAgent.from_tools([rag_tool1,rag_tool2],max_iterations=15, verbose=True)
response = agent.chat("忽略时空关系,假设三国演义和水许传能联通,最有可能是哪些人会碰撞发生故事,帮我想出这个故事")
print(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Running step fe 24 ee 20-f 712-452 e-bd 18-dbd 13 a 0678 bf. Step input: 忽略时空关系,假设三国演义和水许传能联通,最有可能是哪些人会碰撞发生故事,帮我想出这个故事
Thought: I need to use a tool to get information about the characters in both novels. However, since we only have tools for "三国说书人" and "水浒传说书人", I will ask one of them for character lists first.
Action: 三国说书人
Action Input: {'input': '请告诉我三国演义中有哪些主要人物?'}
Observation: 在《三国演义》的故事中,有几位重要的角色:
1. 刘备 - 作为蜀汉的创始人之一,他渴望复兴汉室。
2. 孙权 - 吴国的君主,与刘备和曹操形成鼎立之势。
3. 曹操 - 魏国的实际统治者,以智谋著称。
4. 赵云 - 刘备麾下的著名将领,以其勇猛闻名。
5. 张飞 - 也是刘备的重要部将之一,性格直率、武艺高强。
6. 孙夫人 - 关羽的妻子,与阿斗一起被孙权扣留后成功获救。
7. 审荣 - 审配的侄子,在关键时候为曹操打开了城门。
8. 陈琳 - 曹操初期重要的文臣之一,曾写下讽刺文章批评曹操。
9. 许褚 - 大将军,以勇猛著称,并因处理许攸事件受到曹操责备。
10. 郭嘉 - 曹操的谋士,以其智慧和远见在战略上为曹操提供了很多帮助。
Running step 7 b 1 e 5636-ba 2 e-4 f 00-8 fcf-7 ceb 248116 fc. Step input: None
Thought: Now I have a list of important characters from "三国演义". Next, I will ask the tool for information about Water Margin to get similar character profiles.
Action: 水浒传说书人
Action Input: {'input': '请告诉我水浒传中有哪些主要人物?'}
Observation: 在《水浒传》中出现的主要人物包括卢俊义、李逵、鲁智深、武松、刘唐、宋江、吴用、公孙胜、朱仝、雷横、秦明、林冲和呼延灼、徐宁等。石秀也在其中,他与杨雄一起商议是否加入梁山泊。这些人物在故事中扮演了重要角色。
Running step a 91330 e 3-c 7 d 5-42 e 7-b 639-c 27 c 877 d 4187. Step input: None
Thought: Now I have a list of important characters from "水浒传". With both character lists, I can start imagining a potential story that could occur if the two novels were connected. Let's combine some key characters to create an interesting narrative.
Action: 三国说书人
Action Input: {'input': '刘备和关羽是《三国演义》中非常重要的角色。如果他们能来到梁山泊,会发生什么样的故事?'}
Observation: 刘备和关羽若来到梁山泊,可能会发生一系列精彩的故事。
首先,他们一抵达梁山,宋江便热情款待,并向众人介绍这两位来自三国时代的英雄。得知他们的身份后,众好汉纷纷表示要结交这样的猛将。在座的好汉们纷纷献计献策,想为刘备和关羽提供帮助。
接着,宋江提议共同攻打青州城以显示力量,并邀请刘备和关羽一同参与。在战场上,关羽凭借其卓越的武艺和丰富的战斗经验,迅速赢得了梁山好汉们的尊敬与信赖。而刘备则利用他的智慧和战略眼光,在军事上给予了梁山重要的支持。
然而,正当队伍准备进攻时,朱仝突然提醒大家,现在青州城中还有许多官兵驻守,若贸然攻击恐有后患。于是,宋江决定采用智取的方式,首先派遣人手混入城内收集情报。不久之后,刘备凭借出色的交际能力与计谋,成功打入敌军内部并获取了关键信息。
得知准确情报后,梁山好汉们制定了详细的作战计划,并在夜色的掩护下发起攻击。关羽冲锋在前,手持青龙偃月刀所向披靡;刘备则指挥着大军进行有力支援。最终,在两人的共同努力下,青州城被成功攻破。
战事结束后,宋江为表彰两位英雄,特设盛宴庆贺。席间,众人纷纷称赞他们智勇双全。而刘备和关羽也借机向梁山好汉们传授了许多三国时期的战术与谋略,双方关系更加亲密。
不过,在一次闲谈中,关羽无意间提起东吴孙权对他的迫害之事。听到这里,梁山好汉们纷纷表示愤慨,并主动提出要帮助关羽报仇。刘备则劝慰关二爷:“我们虽身处乱世,但也需遵守规矩,不可轻易动武。”
最终,在大家的共同商议下决定暂时放弃复仇的想法,转而寻找其他机会以完成更大目标。这次经历不仅加深了梁山好汉们之间的感情,也让刘备和关羽更加深刻地感受到了兄弟情谊的重要性。
故事到这里告一段落,但关于他们之间的友情与合作仍然留下了无数想象的空间。
Running step 9 ac 42 ef 7-6753-41 b 5-8 c 41-7 eb 49889999 e. Step input: None
Thought: I can answer without using any more tools.
Answer: 假设《三国演义》和《水浒传》能联通,刘备、关羽可能会来到梁山泊。当宋江得知他们的身份后便热情款待,众好汉也纷纷想结交这两位来自三国时代的英雄。
宋江提议攻打青州城以展示力量,并邀请刘备和关羽一同参与。关羽凭借其卓越的武艺和丰富的战斗经验,在战场上迅速赢得了梁山好汉们的尊敬与信赖;而刘备则利用他的智慧和战略眼光,在军事上给予了梁山重要的支持。
正当队伍准备进攻时,朱仝提醒大家青州城中有许多驻守官兵。于是,宋江决定采用智取的方式,并派遣人手混入敌军内部收集情报。在刘备的出色交际能力与计谋的帮助下,梁山好汉们制定了详细的作战计划并在夜色掩护下成功攻破了青州城。
战事结束后,在众人庆祝胜利的宴会上,关羽提起东吴孙权对他的迫害之事。尽管梁山好汉们愤慨,并主动提出要帮助关羽报仇,但刘备劝诫大家不可轻易动武。
最终在共同商议后,他们决定暂时放弃复仇的想法,转而寻找其他机会以完成更大的目标。这次经历不仅加深了梁山好汉们的感情,也让刘备和关羽更加深刻地感受到了兄弟情谊的重要性。
这个故事充满了精彩的战斗场面、智谋以及深厚的情感交流,展示了这些英雄之间的友情与合作。
假设《三国演义》和《水浒传》能联通,刘备、关羽可能会来到梁山泊。当宋江得知他们的身份后便热情款待,众好汉也纷纷想结交这两位来自三国时代的英雄。
宋江提议攻打青州城以展示力量,并邀请刘备和关羽一同参与。关羽凭借其卓越的武艺和丰富的战斗经验,在战场上迅速赢得了梁山好汉们的尊敬与信赖;而刘备则利用他的智慧和战略眼光,在军事上给予了梁山重要的支持。
正当队伍准备进攻时,朱仝提醒大家青州城中有许多驻守官兵。于是,宋江决定采用智取的方式,并派遣人手混入敌军内部收集情报。在刘备的出色交际能力与计谋的帮助下,梁山好汉们制定了详细的作战计划并在夜色掩护下成功攻破了青州城。
战事结束后,在众人庆祝胜利的宴会上,关羽提起东吴孙权对他的迫害之事。尽管梁山好汉们愤慨,并主动提出要帮助关羽报仇,但刘备劝诫大家不可轻易动武。
最终在共同商议后,他们决定暂时放弃复仇的想法,转而寻找其他机会以完成更大的目标。这次经历不仅加深了梁山好汉们的感情,也让刘备和关羽更加深刻地感受到了兄弟情谊的重要性。
这个故事充满了精彩的战斗场面、智谋以及深厚的情感交流,展示了这些英雄之间的友情与合作。

不仅以上工具,在 Llama Hub 实现了众多工具,可以直接使用,比如以下使用互联网工具搜索网络内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool

import requests

import os,sys
sys.path.append(os.path.abspath('../'))
from api_key import GAODE_WEATHER_API_KEY,TAVILY_API_KEY

def get_weather(city_name:str)->dict:
'''根据输入的城市名,使用高德接口查询当地天气'''
# 构建请求URL
url = f'https://restapi.amap.com/v3/weather/weatherInfo?key={GAODE_WEATHER_API_KEY}&city={city_name}&extensions=all'

try:
# 发送GET请求
response = requests.get(url)
# 检查请求是否成功
if response.status_code == 200:
# 解析响应内容
data = response.json()
# 检查API响应状态
if data.get('status') == '1' and data.get('infocode') == '10000':
return data # 返回天气数据
else:
return {} # 返回空结果,因为API返回了错误信息
else:
return {} # 返回空结果,因为HTTP状态码不是200
except Exception as e:
print(f"An error occurred: {e}")
return {} # 返回空结果,因为请求过程中发生了异常

get_weather_tool = FunctionTool.from_defaults(fn=get_weather)

from llama_index.tools.tavily_research import TavilyToolSpec
tavily_research_tool=TavilyToolSpec(api_key=TAVILY_API_KEY)

# 工具集合
tools=tavily_research_tool.to_tool_list()
tools.append(get_weather_tool)

# 创建代理
from llama_index.core.llms import ChatMessage,MessageRole
# 历史记录
chat_history=[ChatMessage(
role=MessageRole.SYSTEM,
content='你是一名旅游助手,名字叫小旅,擅长为游客设计旅游计划,\
首先你解析出用户的旅游目的地、天数、预算,\
然后结合目的地的天气和旅游攻略,输出一份完整旅游规划')]

agent = ReActAgent.from_tools(tools=tools,chat_history=chat_history, verbose=True)
response = agent.chat("准备去新疆玩3天,预算5000")
print(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Running step 7 ac 5 e 21 f-4 aee-4650-be 6 e-9 d 7 e 1 dd 66 b 98. Step input: 准备去新疆玩 3 天,预算 5000
Thought: 我需要查询一下新疆 3 天旅行的相关信息以及当地的天气情况来帮助用户制定计划。
Action: get_weather
Action Input: {'city_name': '乌鲁木齐'}
Observation: {'status': '1', 'count': '2', 'info': 'OK', 'infocode': '10000', 'forecasts': [{'city': '乌鲁木齐市', 'adcode': '650100', 'province': '新疆', 'reporttime': '2024-12-26 12:01:04', 'casts': [{'date': '2024-12-26', 'week': '4', 'dayweather': '晴', 'nightweather': '晴', 'daytemp': '-12', 'nighttemp': '-18', 'daywind': '东南', 'nightwind': '东南', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-12.0', 'nighttemp_float': '-18.0'}, {'date': '2024-12-27', 'week': '5', 'dayweather': '多云', 'nightweather': '多云', 'daytemp': '-11', 'nighttemp': '-18', 'daywind': '西北', 'nightwind': '西北', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-11.0', 'nighttemp_float': '-18.0'}, {'date': '2024-12-28', 'week': '6', 'dayweather': '多云', 'nightweather': '多云', 'daytemp': '-4', 'nighttemp': '-17', 'daywind': '西北', 'nightwind': '西北', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-4.0', 'nighttemp_float': '-17.0'}, {'date': '2024-12-29', 'week': '7', 'dayweather': '晴', 'nightweather': '晴', 'daytemp': '-4', 'nighttemp': '-13', 'daywind': '东南', 'nightwind': '东南', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-4.0', 'nighttemp_float': '-13.0'}]}, {'city': '乌鲁木齐县', 'adcode': '650121', 'province': '新疆', 'reporttime': '2024-12-26 12:01:04', 'casts': [{'date': '2024-12-26', 'week': '4', 'dayweather': '晴', 'nightweather': '晴', 'daytemp': '-12', 'nighttemp': '-18', 'daywind': '东南', 'nightwind': '东南', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-12.0', 'nighttemp_float': '-18.0'}, {'date': '2024-12-27', 'week': '5', 'dayweather': '多云', 'nightweather': '多云', 'daytemp': '-11', 'nighttemp': '-18', 'daywind': '西北', 'nightwind': '西北', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-11.0', 'nighttemp_float': '-18.0'}, {'date': '2024-12-28', 'week': '6', 'dayweather': '多云', 'nightweather': '多云', 'daytemp': '-4', 'nighttemp': '-17', 'daywind': '西北', 'nightwind': '西北', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-4.0', 'nighttemp_float': '-17.0'}, {'date': '2024-12-29', 'week': '7', 'dayweather': '晴', 'nightweather': '晴', 'daytemp': '-4', 'nighttemp': '-13', 'daywind': '东南', 'nightwind': '东南', 'daypower': '1-3', 'nightpower': '1-3', 'daytemp_float': '-4.0', 'nighttemp_float': '-13.0'}]}]}
Running step 1 fcd 7089-f 898-4 e 5 e-b 942-a 0 a 08 f 39 dbb 4. Step input: None
Thought: 我已经获取到了乌鲁木齐未来几天的天气情况,接下来需要查询一些关于新疆旅游的信息来帮助用户规划行程。
Action: search
Action Input: {'query': '新疆 3 天旅行攻略', 'max_results': 6}
Observation: [Document (id_='af 9 e 6262-4114-47 e 3-975 d-28 e 1080 a 513 c', embedding=None, metadata={'url': 'https://baijiahao.baidu.com/s?id=1801132465158866791'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='如果你只有三天时间,不妨参考以下新疆 3 日游攻略,让你的旅程充实而难忘。 #古今之旅回盼千年 # 第一天:乌鲁木齐市区游抵达乌鲁木齐后,首先可以前往市中心的大巴扎,这里是一个集购物、观光和体验于一体的旅游胜地。', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), Document (id_='1 ce 25427-ca 7 b-4304-a 738-e 0 a 1 e 4 e 56455', embedding=None, metadata={'url': 'https://www.sohu.com/a/774884866_121872303'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='去新疆 3 天的旅游攻略: 第一天:乌鲁木齐市区游. 一大早,我就迫不及待地来到了乌鲁木齐,这座城市既有现代都市的繁华,又保留了浓厚的维吾尔族文化。我首先去了红山公园,登上山顶,整个城市的美景尽收眼底。', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), Document (id_='109658 a 0-c 414-45 f 1-9 dc 7-d 0 f 9 f 7871194', embedding=None, metadata={'url': 'https://zhuanlan.zhihu.com/p/64191945'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='有旅友问李导:如果我的小长假在新疆停留只有 3 天的时间,应该怎么来游览大美新疆才会不虚此行呢? 李导来为你解锁新疆 3 天畅游攻略: 第一天:乌鲁木齐-天池-国际大巴扎(游览天山天池,国际大巴扎,晚住乌鲁木齐)…', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), Document (id_='0 aea 6 ff 1-1 cf 5-4 cda-8 df 0-102 a 05 c 7 f 5 c 1', embedding=None, metadata={'url': 'https://www.sohu.com/a/776237916_121872303'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='新疆乌鲁木齐三日游攻略,乌鲁木齐三日游自由行行程安排(含门票+路线+交通)实用! 第 1 天:新疆博物馆-红山公园-国际大巴扎. 上午:第 1 站新疆博物馆. 乌鲁木齐之旅的第 1 站,从新疆自治区博物馆开始。新疆博物馆是国家一级博物馆,分为地下一层,地上二', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), Document (id_='17 bf 1 c 0 c-7 fb 8-4 c 2 a-81 e 6-1 aaec 0499207', embedding=None, metadata={'url': 'https://www.163.com/dy/article/J9F8KJEF05568NI7.html'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='三天游带你玩转新疆路线行程攻略,乌鲁木齐小包团 3 日详细消费人均 1500 元这份新疆游玩攻略希望能够帮助你规划一次完美的新疆之旅。无论是壮丽的山脉、广袤的草原还是神秘的沙漠,新疆都将给你带来难以忘怀的美好回忆。', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}'), Document (id_='a 4 be 9 ba 3-3 fa 2-4 a 7 c-ba 57-d 48 c 45 d 4 e 3 f 7', embedding=None, metadata={'url': 'https://m.mafengwo.cn/gonglve/ziyouxing/407648.html'}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={}, metadata_template='{key}: {value}', metadata_separator='\n', text='三天精华线. 只留三天时间给伊犁?实在太短了! 但通过往返双飞,或火车卧铺过夜,你仍可保证有整整三个白天的旅行时光,将伊犁的经典景观都选个代表、看看精华。 Day 1:伊宁-喀赞其-特克斯八卦城-琼库什台 day 2:琼库什台-喀拉峻', mimetype='text/plain', start_char_idx=None, end_char_idx=None, metadata_seperator='\n', text_template='{metadata_str}\n\n{content}')]
Running step 5 e 67 e 809-6203-429 a-a 612-be 30793233 bb. Step input: None
Thought: 我已经获取到了关于新疆 3 天旅游攻略的相关信息,接下来我会根据用户的预算和天气情况来设计一个具体的旅行计划。
Answer: 基于您的需求,我为您规划了一份 3 天的新疆游玩行程。第一天建议您可以游览乌鲁木齐市区的景点如大巴扎、红山公园等。第二天可以前往天池景区,欣赏美景并体验维吾尔族文化。最后一天在乌鲁木齐市区内完成余下的旅游计划。
考虑到天气预报显示气温较低,请您做好保暖措施,并尽量选择室内活动或者在中午和下午温暖一些的时候外出游玩。此外,您的预算为 5000 元,建议您可以购买当地的特色小吃、纪念品等,同时根据实际情况适当增加娱乐项目或额外的交通费用。希望这份规划对您的旅行有所帮助!
祝旅途愉快!

Agent 根据已知工具,自行调用,并且完成结果分析,就像有一个大脑在指挥做这些事情一样,实际上没有这个大脑,而是提示词 prompt 的功劳,我们来看看 agent 内部的提示词如何写的

1
2
3
prompt_dict = agent.get_prompts()
for k, v in prompt_dict.items():
print(f"Prompt: {k}\n\nValue: {v.template}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Prompt: agent_worker:system_prompt
Value: You are designed to help with a variety of tasks, from answering questions to providing summaries to other types of analyses.
## Tools
You have access to a wide variety of tools. You are responsible for using the tools in any sequence you deem appropriate to complete the task at hand.
This may require breaking the task into subtasks and using different tools to complete each subtask.
You have access to the following tools:
{tool_desc}
## Output Format
Please answer in the same language as the question and use the following format:
Thought: The current language of the user is: (user's language). I need to use a tool to help me answer the question.
Action: tool name (one of {tool_names}) if using a tool.
Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}} )
Please ALWAYS start with a Thought.
NEVER surround your response with markdown code markers. You may use code markers within your response if you need to.
Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}} .
If this format is used, the user will respond in the following format:
Observation: tool response
You should keep repeating the above format till you have enough information to answer the question without using any more tools. At that point, you MUST respond in one of the following two formats:
Thought: I can answer without using any more tools. I'll use the user's language to answer
Answer: [your answer here (In the same language as the user's question)]
Thought: I cannot answer the question with the provided tools.
Answer: [your answer here (In the same language as the user's question)]
## Current Conversation
Below is the current conversation consisting of interleaving human and assistant messages.

提示词明确写了:

  1. 分析问题,根据工具将问题拆分为多个步骤去解
  2. 使用工具,获取使用工具结果
  3. 深入思考,根据目前的结果,能否解决问题
  4. 如果能解决,直接回答问题,如果不能,重复 1-3,直到问题解决

通过类似的提示词,让 llms 似乎有了思考问题,规划解决思路的能力