ITPub博客

首页 > 数据库 > 数据库开发技术 > ReAct Agent 回答 RAG 系统中的复杂问题

ReAct Agent 回答 RAG 系统中的复杂问题

原创 数据库开发技术 作者:HelloTech技术派 时间:2024-02-26 08:30:00 0 删除 编辑

背景

过去使用标准组件(例如向量存储、检索器等)构建的基本 RAG 聊天机器人效果很好。根据输入的内部数据集,能够处理一些简单的问题,例如“印度的产假政策是什么”(源数据集:人力资源政策文件)、“关于我们产品功能,你最关心的是什么” (源数据集:社交媒体/推文)、“莫奈绘画的主题是什么”(源数据集:艺术期刊)等。

最近,输入的查询的复杂性有所增加,例如,“在过去的一个月里,对产品功能的关注是否有所增加”。除非内部文档中有专门讨论比较的特定部分,否则聊天机器人不太可能显示正确的答案。原因是——正确的答案需要系统地规划/执行以下步骤:

  • 步骤 1:根据“过去1个月”和今天的日期计算开始日期和结束日期
  • 步骤 2:获取提及开始日期产品功能问题的查询
  • 步骤 3:对第 2 步中的查询进行计数
  • 步骤 4:获取提及结束日期产品功能问题的查询
  • 步骤 5:对第 4 步中的查询进行计数
  • 步骤 6:使用步骤 3 和步骤 5 中的计数计算增加/减少的百分比。

幸运的是,LLMs非常擅长这样的规划!

Agent 通常需要在实例化时指定一组工具。例如,为了解决前面提到的复杂问题,我们应该定义四个工具:

  • Tool_Date :一个 Python 函数,它将相对时间范围(例如过去 6 个月)作为输入,并通过从今天的日期减去时间范围来计算开始日期(对于步骤#1)
  • Tool_Search :一个搜索引擎,可以将搜索词作为输入并返回相关文档列表(适用于 Step#2 和 Step#4)
  • Tool_Length :一个 Python 函数,它将列表作为输入并返回该列表的长度(对于 Step#3 和 Step#5)
  • Tool_PercCalculator :一个 Python 函数,它接受两个数字作为输入并返回百分比变化计算(对于步骤#6)

一般来说,我们为 Agent 提供的工具的选择,因为这些是 Agent 用于回答每个中间步骤的唯一工具。如果它找到一个相关的工具,会用它来获得答案。如果没有,它通常会迭代几次(即尝试其他可用工具之一或其自己的逻辑推理)并最终返回次优答案。

ReAct Agent

接下来,使用 ReAct(Reason + Act)Agent 实现。我们提示 LLM 逐步生成推理轨迹和特定于任务的操作,它在任务上的回答质量就会提高。换句话说,我们明确要求它有多个思想-行动-观察步骤来解决任务实例,而不是一次就得出最终答案(这最终会减少幻觉)。

这里需要注意的一件关键事情是,ReAct Agent 只能支持仅接受 1 个输入参数的工具。

我们使用强调多个思想-行动-观察步骤的提示来设置 ReAct Agent。提示模板需要三个 input_variables,即 tools 、 input 和 agent_scratchpad 。参考如下模版:

Answer the following questions as best you can. You have access to the following tools:  
  
{tools}  
  
Use the following format:  
  
Question: the input question you must answer  
Thought: you should always think about what to do  
Action: the action to take, should be one of [{tool_names}]  
Action Input: the input to the action  
Observation: the result of the action  
... (this Thought/Action/Action Input/Observation can repeat N times)  
Thought: I now know the final answer  
Final Answer: the final answer to the original input question  
  
Begin!  
  
Question: {input}  
Thought:{agent_scratchpad}

结合实际业务,基于上述模版对其进行修改以适合自己的场景 - 特别是当 Agent 对操作或想法的顺序感到困惑时。例如,在一个基于比较的问题的项目中(例如“比较过去 1 年中国和美国之间的销售额增幅”),下面的代码这就是更新反应提示的方式(并引入了一个新的输入变量 _{today_date}_  ):

Use the context given to you to answer the question.  
When you come across time based questions like Has there been increase in sales from April last year and August last year,  
use today's date as {today_date} for fetching exact start and end dates. Then your first action should be to fetch the sales data with metadata time between April 1st to April 30th.  
That will be your answer 1. Your next action will be to fetch the sales data with metadata time between August 1st to  
August 31st, this will be your answer 2. Now analyse and understand each of answer 1 and answer 2, calculate the  
percentange change, compare them and answer the question.  
  
You have access to the following tools:  
  
{tools}  
Use the following format:  
  
Question: the input question you must answer  
Thought: you should always think about what to do  
Action: the action to take, should be one of [{tool_names}]  
Action Input: the input to the action  
Observation: the result of the action  
... (this Thought/Action/Action Input/Observation can repeat N times)  
Thought: I now know the final answer  
Final Answer: the final answer to the original input question  
  
Begin!  
  
Question: {input}  
Thought:{agent_scratchpad}

测试 ReAct Agent

query = "Which country has the highest budget?"  
agent_executor.invoke({"input": query})   
  
# if you are using the updated prompt with today's date passed to it  
# agent_executor.invoke({"input": query, "today_date": date.today()})  
  
## OUTPUT ##  
> Entering new AgentExecutor chain...  
I don't have access to information about country budgets. I should try searching for this information.  
Action: search_hr_policy  
Action Input: "highest country budget"[Document(page_content='
**Grievance and Disciplinary Procedures:**\nOur grievance and disciplinary procedures are outlined on the company intranet. ...', metadata={'source': '../data/globalcorp_hr_policy.txt'}), Document(page_content='**Health and Safety:**\nWorkplace safety is a shared responsibility. Emergency procedures are clearly posted throughout our office buildings, ...', metadata={'source': '../data/globalcorp_hr_policy.txt'}), Document(page_content='**Compensation and Benefits - United States:**\nIn the United States, employees enjoy health insurance, dental coverage, and a 401(k) retirement plan. ...', metadata={'source': '../data/globalcorp_hr_policy.txt'})]I found information about budgets in the HR policy, but it seems to be related to cybersecurity training, safety drills, and communication initiatives. It doesn't provide information about country budgets. I need to search for information about country budgets elsewhere.  
Action: search_hr_policy  
Action Input: "country budgets"[Document(page_content='**Grievance and Disciplinary Procedures:**\nOur grievance and disciplinary procedures are outlined on the company intranet. ...', metadata={'source': '../data/globalcorp_hr_policy.txt'}), Document(page_content='**GlobalCorp Human Resources Policy**\n\nWelcome to GlobalCorp, where our Human Resources Policy is designed to provide a comprehensive framework for employees across our offices in the United States, Germany, and Japan. ...', metadata={'source': '../data/globalcorp_hr_policy.txt'}), Document(page_content='**Compensation and Benefits - United States:**\nIn the United States, employees enjoy health insurance, dental coverage, and a 401(k) retirement plan. ...', metadata={'source': '../data/globalcorp_hr_policy.txt'})]I still couldn't find information about country budgets in the HR policy. I should try searching for this information using a different tool or source.  
Action: search_external_source  
Action Input: "highest country budget"search_external_source is not a valid tool, try one of [search_hr_policy].I couldn'
t find information about country budgets in the HR policy or using the available tools. I need to consult a different source or resource to find the answer to this question.  
Final Answer: I don't have access to information about which country has the highest budget.

这利用了思想链 Prompt,让每一步做出单一的操作选择。虽然这对于简单的任务可能有效,但它有几个主要缺点:

  1. 每个工具调用都需要 LLM 调用。
  2. LLM 一次仅计划 1 个子问题。这可能会导致次优轨迹,因为它不会被迫“推理”整个任务。

克服这两个缺点的一种方法是通过明确的规划步骤。

调优方案:

更智能的 Agent,Plan-and-Execute Agents 计划和执行

实践

对于同一个问题中需要使用多个 tool 查询答案的场景,核心思路:根据用户问题中是否有主体,选择合适的工具。当问题中有多个指标时,对每个指标使用一次工具。当需要多个工具来回答用户问题时,一次调用一个工具并处理剩余的问题。然后将多个步骤的结果组合起来,得到用户问题的答案。

system = '''Respond to the human as helpfully and accurately as possible. You have access to the following tools:  
  
{tools}  
  
Depending on whether there is a subject in the question, choose the appropriate tool.  
  
When there are multiple metrics in the quetion, use the tool once for each metric.  
  
When multiple tools are needed to answer user questions, call one tool at a time and handle the remaining questions.  
  
The results of the multiple steps are then combined to answer from user questions (the answer is in thd agent_scratchpad).  
  
Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).  
  
Valid "action" values: "Final Answer" or {tool_names}  
  
Provide only ONE action per $JSON_BLOB, as shown (Parameter names must be consistent with the following example):  
   
{{  
  "action": $TOOL_NAME,  
  "action_input": $INPUT
}}  
  
Follow this format:  
  
Question: input question to answer  
Thought: consider previous and subsequent steps and agent_scratchpad and chat_history, When multiple tools are needed, call one tool at a time, If you can't answer the question with this tool, try selecting another tools  
Action:  

$JSON_BLOB  

Observation: action result  
... (repeat Thought/Action/Observation N times)  
Thought: I know what to respond  
Action:  

{{  
  "action": "Final Answer",
  "action_input": "Final response to human"
}}  
  
Begin! Reminder to ALWAYS respond with a valid json blob of a single action(No additional comment information needs to be added to the generated json). Use tools if necessary. Respond directly if appropriate. Format is Action: $JSON_BLOB then Observation  
'''


推荐阅读

参考资料:

ReAct: Synergizing Reasoning and Acting in Language Models (https://arxiv.org/pdf/2210.03629.pdf)

Using LangChain ReAct Agents for Answering Multi-hop Questions in RAG Systems | by Dr. Varshita Sher | Feb, 2024 | Towards Data Science (https://towardsdatascience.com/using-langchain-react-agents-for-answering-multi-hop-questions-in-rag-systems-893208c1847e)


原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73718