Type something to search...
从文本到功能代码:使用自适应提示工程为 Rag 增效--权威指南!

从文本到功能代码:使用自适应提示工程为 Rag 增效--权威指南!

从结构化表中提取相关数据

从结构化表中提取相关数据需要的不仅仅是标准的 RAG 方法。我们通过索引术语建议、上下文行检索和动态 few-shot 示例增强了提示工程,以生成可靠的 Pandas 查询,使我们的系统既准确又高效。

共同作者:Michael Leshchinsky

Clalit 是以色列最大的健康维护组织——它既是超过 450 万名成员的保险公司,也是医疗服务提供者。正如您所料,这样一个庞大的组织拥有大量有用的信息,应该对所有客户和员工可用——医疗提供者名单、患者的资格、医疗测试和程序的信息等等。不幸的是,这些信息分散在多个来源和系统中,使最终用户很难获取他们所寻找的确切信息。

为了解决这个问题,我们决定构建一个多代理 RAG 系统,能够理解需要查询的知识领域,从一个或多个来源获取相关上下文,并根据这些上下文为用户提供正确和完整的答案。

每个代理专注于特定领域,并且本身就是一个小型 RAG,因此它可以检索上下文并回答其领域的问题。协调代理理解用户的问题,并决定应该向哪个代理发送请求。然后,它聚合所有相关代理的答案,并为用户编制一个答案。

解决方案的一般架构。作者提供的图像。

至少,这就是最初的想法——我们很快发现并非所有数据源都是相同的,有些代理应该与人们所称的经典 RAG 完全不同。

在本文中,我们将重点关注一个这样的用例——医疗提供者名单,也称为 服务手册。服务手册是一个大约有 23K 行的表格,每一行代表一个医疗提供者。每个提供者的信息包括其地址和联系信息、提供的职业和服务(包括员工姓名)、营业时间以及关于诊所可达性和评论的一些额外自由文本评论。

以下是表中的一些伪示例(由于列数较多,垂直显示)。

Image 8

我们最初的方法是将每一行转换为文本文档,进行索引,然后使用简单的 RAG 进行提取。然而,我们很快发现这种方法有几个局限性:

  • 用户可能期望得到包含多行的答案。例如,考虑这个问题:“特拉维夫有哪些药店?” 我们的 RAG 应该检索多少个文档?如果用户明确规定期望多少行呢?

  • 对于检索器来说,区分不同字段可能极其困难——某个城市的诊所可能以另一个城市的名字命名(例如,耶路撒冷诊所位于特拉维夫的耶路撒冷路上)。

  • 作为人类,我们可能不会“文本扫描”一个表格来提取信息。相反,我们更愿意根据规则过滤表格。我们的应用程序没有理由表现得不同。

相反,我们决定朝另一个方向发展——要求 LLM 将用户的问题转换为提取相关行的计算机代码。

这种方法受到 llama-index 的 Pandas 查询引擎 的启发。简而言之,LLM 的提示由用户的查询、_df.head()(用于教导 LLM 表格的结构)和一些一般指令构成。

query = """
## Your job is to convert user's questions to a single line of Pandas code that will filter `df` and answer the user's query.
Here are the top five rows from df:
## {df}
- Your output will be a single code line with no additional text.
- The output must include: the clinic/center name, type, address, phone number(s), additional remarks, website, and all columns including the answer or that were filtered.
## - Think carefully about each search term!
USER'S QUESTION: {user_query}
PANDAS CODE:
"""
response = llm.complete(query.format(df=df.head(), 
                                     user_query=user_query)
                       )
try:
    result_df = eval(response.text)
except:
    result_df = pd.DataFrame()

听起来很简单,对吧?实际上,我们遇到了残酷的现实,在我们生成的大多数代码中,Pandas 出现了一个或另一个原因的错误,因此主要工作才刚刚开始。

我们能够识别生成代码失败的三个主要原因,并使用几种动态提示工程技术来解决它们:

  1. 通过**添加“thesaurus”**来修复与 不精确术语 相关的问题,这些术语可以用来过滤每一列。

  2. 向 LLM 提供来自 df 的相关行,而不是由 _df.head() 提取的任意行。

  3. 使用定制的代码示例进行动态 few-shotting,以帮助 LLM 生成正确的 Pandas 代码。

将同义词添加到提示中

在许多情况下,用户的问题可能与表格“期望”的内容不完全一致。例如,用户可能会询问在 特拉维夫 的药店,但表格中的术语是 特拉维夫-雅法。在另一个情况下,用户可能在寻找 眼科医生,而不是 眼科,或者在寻找 心脏病专家 而不是 心脏病学。对于 LLM 来说,编写能够涵盖所有这些情况的代码将是困难的。相反,检索正确的术语并将其作为建议包含在提示中可能更有益。

正如您所想,服务手册中每一列的术语数量是有限的——诊所类型可能是医院诊所、私人诊所、初级保健诊所,等等。城市名称、医疗职业和服务以及医疗人员的数量也是有限的。我们使用的解决方案是创建所有术语的列表(在每个字段下),将每个术语作为一个文档,然后将其作为向量进行索引。

然后,使用仅检索的引擎,我们为每个搜索术语提取大约 3 个项目,并将这些项目包含在提示中。例如,如果用户的问题是“特拉维夫有哪些药店可用?”,则可能检索到以下术语:

  • 诊所类型:药店;初级保健诊所;医院诊所
  • 城市:特拉维夫-雅法,特尔谢瓦,法拉迪斯
  • 职业和服务:药店,肛肠学,儿科

检索到的术语包括我们正在寻找的真实术语(药店,特拉维夫-雅法),以及一些可能听起来相似的无关术语(特尔谢瓦,肛肠学)。所有这些术语将作为建议包含在提示中,我们期望 LLM 能够筛选出可能有用的术语。

from llama_index.core import VectorStoreIndex, Document

unique_cities = df['city'].unique()
cities_documents = [Document(text=city) for city in unique_cities]
cities_index = VectorStoreIndex.from_documents(documents=cities_documents)
cities_retriever = cities_index.as_retriever()

suggest_cities = ", ".join([doc.text for doc in cities_retriever.retrieve(user_query)])

query = """您的任务是将用户的问题转换为一行 Pandas 代码,该代码将筛选 df 并回答用户的查询。

以下是 df 的前五行:

{df}

这是您可能正在寻找的城市: {suggest_cities}

  • 您的输出将是一行代码,没有额外的文本。
  • 输出必须包括:诊所/中心名称、类型、地址、电话号码、附加备注、网站,以及所有包含答案或被筛选的列。

- 仔细考虑每个搜索词!

用户的问题: {user_query}
PANDAS 代码:
"""

response = llm.complete(query.format(df=df.head(),
suggest_cities=suggest_cities,
user_query=user_query)
)
try:
result_df = eval(response.text)
except:
result_df = pd.DataFrame()

选择相关行示例以包含在提示中

默认情况下,PandasQueryEngine通过将_df.head()_嵌入到提示中来包含_df_的前几行,以便让LLM学习表的结构。然而,这五行很可能与用户的问题无关。想象一下,我们可以明智地选择哪些行包含在提示中,以便LLM不仅能学习表的结构,还能看到与当前任务相关的示例。

为了实现这个想法,我们使用了上述描述的初始方法:

  • 我们将每一行转换为文本,并将其作为单独的Document进行索引。
  • 然后,我们使用检索器根据用户的query提取五个最相关的行,并将它们包含在提示中的_df_示例中。
  • 我们在这个过程中学到的一个重要教训是包含一些随机的、不相关的示例,以便LLM也能看到负面示例,并知道必须区分它们。

这里有一些代码示例:

rows = df.fillna('').apply(lambda x: ", ".join(x), axis=1).to_dict()
rows_documents = [Document(text=v, metadata={'index_number': k}) for k, v in rows.items()]

rows_index = VectorStoreIndex.from_documents(documents=rows_documents)
rows_retriever = rows_index.as_retriever(top_k_similarity=5)

retrieved_indices = rows_retriever.retrieve(user_query)
relevant_indices = [i.metadata['index_number'] for i in retrieved_indices]

query = """您的任务是将用户的问题转换为一行 Pandas 代码,该代码将过滤 df 并回答用户的查询。

以下是 df 中的前五行:

{df}

这些是您最可能寻找的城市:{suggest_cities}

  • 您的输出将是一个没有额外文本的单行代码。
  • 输出必须包括:诊所/中心名称、类型、地址、电话号码、附加备注、网站,以及所有包含答案或已过滤的列。

- 仔细考虑每个搜索词!

示例:

{relevant_example}

用户的问题:{user_query} PANDAS 代码: """

response = llm.complete(query.format(df=pd.concat([df.head(), df.loc[relevant_indices]]), suggest_cities=suggest_cities, user_query=user_query) ) try: result_df = eval(response.text) except: result_df = pd.DataFrame()

添加量身定制的代码示例到提示中(动态少量示例)

考虑以下用户的问题:H&C 诊所允许服务动物吗?

生成的代码是:

df[
    (df['clinic_name'].str.contains('H&C')) &
    (df['accessibility'].str.contains('service animals'))
][['clinic_name', 'address', 'phone number', 'accessibility']]

乍一看,这段代码看起来是正确的。但是……用户并不想在 accessibility 列上进行 过滤 — 而是想检查其内容!

在这个过程中,我们很早就意识到,采用少量示例的方法,将示例问题和代码答案包含在提示中,可能会解决这个问题。然而,我们意识到我们可以想到的不同示例实在是太多了,每个示例都强调不同的概念。

我们的解决方案是创建一个不同示例的列表,并使用检索器来包含与当前用户问题最相似的示例。每个示例都是一个字典,其中的键是:

  • QUESTION:潜在用户的问题
  • CODE:请求的输出代码,正如我们所写的那样
  • EXPLANATION:文本解释,强调我们希望 LLM 在生成代码时考虑的概念。

例如:

{
    'QUESTION': 'H&C 诊所允许服务动物吗?',
    'CODE': "df[df['clinic_name'].str.contains('H&C')][['clinic_name', 'address', 'phone number', 'accessibility']]",
    'EXPLANATION': "当询问某个诊所是否存在服务时 - 你不应在相关列上进行过滤。相反,你应该返回给用户以供检查!"
}

现在,每当我们遇到一个新的概念时,我们可以扩展这个 示例库,让我们的系统知道如何处理:

examples_documents = [
    Document(text=ex['QUESTION'], 
             metadata={k: v for k, v in ex.items()})
    for ex in examples_book
]
examples_index = VectorStoreIndex.from_documents(documents=examples_documents)
examples_retriever = examples_index.as_retriever(top_k_similarity=1)

relevant_example = examples_retriever.retrieve(user_query)
relevant_example = f"""问题: {relevant_example.text}
代码: {relevant_example.metadata['CODE']}
解释: {relevant_example.metadata['EXPLANATION']}
"""

query = """您的任务是将用户的问题转换为一行 Pandas 代码,该代码将过滤 df 并回答用户的查询。

以下是 df 的前五行:

{df}

这些是您可能正在寻找的城市:{suggest_cities}

  • 您的输出将是没有额外文本的单行代码。
  • 输出必须包括:诊所/中心名称、类型、地址、电话号码、附加备注、网站,以及所有包括答案或被过滤的列。

- 仔细考虑每个搜索词!

示例:

{relevant_example}

用户的问题:{user_query} PANDAS 代码: """

response = llm.complete(query.format(df=pd.concat([df.head(), df.loc[relevant_indices]]), suggest_cities=suggest_cities, relevant_example=relevant_example, user_query=user_query) ) try: result_df = eval(response.text) except: result_df = pd.DataFrame()

摘要

在本文中,我们尝试描述我们用来创建更具体、动态提示以从我们的表中提取数据的几种启发式方法。通过使用预先索引的数据和检索器,我们可以丰富我们的提示,并使其根据用户当前的问题进行定制。值得一提的是,尽管这使得代理变得更加复杂,但运行时间仍然相对较低,因为检索器通常很快(至少与文本生成器相比)。这是完整流程的示例:

Image 9

查询引擎的完整图形描述。作者提供的图片。

Related Posts

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

结合chatgpt-o3-mini与perplexity Deep Research的3步提示:提升论文写作质量的终极指南

AI 研究报告和论文写作 合并两个系统指令以获得两个模型的最佳效果 Perplexity AI 的 Deep Research 工具提供专家级的研究报告,而 OpenAI 的 ChatGPT-o3-mini-high 擅长推理。我发现你可以将它们结合起来生成令人难以置信的论文,这些论文比任何一个模型单独撰写的都要好。你只需要将这个一次性提示复制到 **

阅读更多
让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

让 Excel 过时的 10 种 Ai 工具:实现数据分析自动化,节省手工作业时间

Non members click here作为一名软件开发人员,多年来的一个发现总是让我感到惊讶,那就是人们还在 Excel

阅读更多
使用 ChatGPT 搜索网络功能的 10 种创意方法

使用 ChatGPT 搜索网络功能的 10 种创意方法

例如,提示和输出 你知道可以使用 ChatGPT 的“搜索网络”功能来完成许多任务,而不仅仅是基本的网络搜索吗? 对于那些不知道的人,ChatGPT 新的“搜索网络”功能提供实时信息。 截至撰写此帖时,该功能仅对使用 ChatGPT 4o 和 4o-mini 的付费会员开放。 ![](https://images.weserv.nl/?url=https://cdn-im

阅读更多
掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

掌握Ai代理:解密Google革命性白皮书的10个关键问题解答

10 个常见问题解答 本文是我推出的一个名为“10 个常见问题解答”的新系列的一部分。在本系列中,我旨在通过回答关于该主题的十个最常见问题来分解复杂的概念。我的目标是使用简单的语言和相关的类比,使这些想法易于理解。 图片来自 [Solen Feyissa](https://unsplash.com/@solenfeyissa?utm_source=medium&utm_medi

阅读更多
在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和技术领域保持领先地位的 10 项必学技能 📚

在人工智能和科技这样一个动态的行业中,保持领先意味着不断提升你的技能。无论你是希望深入了解人工智能模型性能、掌握数据分析,还是希望通过人工智能转变传统领域如法律,这些课程都是你成功的捷径。以下是一个精心策划的高价值课程列表,可以助力你的职业发展,并让你始终处于创新的前沿。 1. 生成性人工智能简介课程: [生成性人工智能简介](https://genai.works

阅读更多
揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

揭开真相!深度探悉DeepSeek AI的十大误区,您被误导了吗?

在AI军备竞赛中分辨事实与虚构 DeepSeek AI真的是它所宣传的游戏规则改变者,还是仅仅聪明的营销和战略炒作?👀 虽然一些人将其视为AI效率的革命性飞跃,但另一些人则认为它的成功建立在借用(甚至窃取的)创新和可疑的做法之上。传言称,DeepSeek的首席执行官在疫情期间像囤积卫生纸一样囤积Nvidia芯片——这只是冰山一角。 从其声称的550万美元培训预算到使用Open

阅读更多
Type something to search...