研究一个人道主义灾难情景报告聊天机器人——使用GPT-4-Turbo和全上下文引导

探索一个人道主义灾难情景的聊天机器人研究报告——运用GPT-4-Turbo和全上下文引导

TLDR

在本文中,我们将探讨OpenAI全新的GPT-4-Turbo模型,使用其增加的128k token上下文窗口,通过传入完整的文档语料库进行信息检索。这种粗暴的蛮力方法——只有较大的上下文窗口才可能实现——实现简单,不需要文档嵌入和语义搜索,就像在检索增强生成(RAG)中使用的那样。应用于发布在令人惊叹的ReliefWeb平台上的人道主义灾难情况报告——使用稀疏引导表示(SPR)进行压缩——我们展示了GPT-4-Turbo能够回答关于最近灾难的基本问题。然而,即使OpenAI的令牌成本最近有所下降,这种方法仍然费用高昂,并且预览GPT-4-Turbo模型非常缓慢,有时需要最多一分钟才能响应。对于所有LLM信息检索模式来说,当然要实施验证框架来确保控制幻觉和信息遗漏。尽管如此,GPT-4-Turbo在能力方面迈出了重要的一步,特别是随着性能的提高和成本的降低,为快速扩展的LLM工具包增添了更多的功能。

全新的GPT-4-Turbo具有128k令牌的较大上下文窗口。图像由GPT-4 + Dall-E-3生成。

考虑到过去几个月中快速的发展,包括发布了autogenmemgptSemantic KernalOpenAI的GPT和GPT-4-Turbo,我想写一系列文章,比较这些新工具在对话式信息检索方面提供的一些技术。每种方法都有其优点和缺点,并且有些可能在我们使用大型语言模型(LLMs)的方式上引起潜在的范式转变。这是一个非常令人惊叹的时代,但在实际应用中使用这些新技术并不总是像最初的探索那样容易。

OpenAI发布GPT-4-Turbo(预览版)

OpenAI在DevDay的最新公告中包括了一些可能改变生成式人工智能领域的新功能。其中之一是(预览版)发布了GPT-4-Turbo,其上下文窗口(提示)限制增加到了128k个令牌,而之前只有32k个。以前的Claude AI提供了商业上最大的上下文限制100k个令牌,所以GPT-4-Turbo是一次突破。此外,OpenAI称其新模型在遵循指令方面更加精通,并且价格比GPT-4便宜3倍。作为许多LLM基准的领导者,GPT-4的任何进步都是重要的。

增加模型令牌限制以扩大上下文

那么为什么增加的令牌限制如此重要?在提示LLM时,您可以包含过去的对话,因此其中一个立即的好处就是,如果您在每个提示中提供对话历史记录,它会记住您之前谈论的内容。这在引用早期对话中可能在现在很重要的事实时非常有用。较大的上下文窗口意味着您还可以使用支持信息(如文档内容和数据)“预装”聊天。

但是也有一些不利因素。

更多的令牌意味着更高的成本和较慢的性能,因为随着变形器架构,内存和计算要求呈二次增加(比简单的直线增长要快得多)。此外,有一些研究表明,较长的上下文窗口会降低LLM的准确性(Liu等人,2023年)。

使用 GPT-4-Turbo

写作时,GPT-4-Turbo仅处于预览模式,可作为模型‘gpt-4–1106-preview’使用。我们将使用openai Python套件调用它,步骤如下…

import openaiopenai.api_key = '<YOUR KEY GOES KEY>'def run_llm(query, system_prompt, reference_content):    llm_query = {        "temperature": 1.0,        "max_tokens": 2000,        "top_p": 0.95,        "frequency_penalty": 0,        "presence_penalty": 0,    }    response = openai.ChatCompletion.create(        model=model,        messages=[  {                "role":"system",                "content": system_prompt            },            {                "role":"user",                "content": query            }        ],        temperature=llm_query['temperature'],        max_tokens=llm_query['max_tokens'],        top_p=llm_query['top_p'],        frequency_penalty=llm_query['frequency_penalty'],        presence_penalty=llm_query['presence_penalty'],        stop=None    )      answer = response['choices'][0]['message']['content']    return answer

分析ReliefWeb灾难情况报告

我们将利用GPT-4-Turbo的增加标记数限制,使用它来分析令人惊叹的ReliefWeb平台上的人道主义灾难情况报告。这些报告(称为‘Sitreps’)对于监测和应对全球人道主义灾难至关重要。它们还提供了一个文本数据语料库,可以压缩(摘要)以适应GPT-4-Turbo的上下文窗口进行分析。

构建灾难报告语料库

ReliefWeb提供了一个非常好的API,用于获取内容,因此我们将使用它来提取灾难和情况报告的列表…

import requests  import os  from bs4 import BeautifulSoup import reimport pandas as pdimport PyPDF2 import tracebackimport jsonimport astfrom langchain.text_splitter import RecursiveCharacterTextSplitterimport tiktokendef auto_translate(text):    """    此函数会自动检测语言并翻译为英文     参数:        text(str): 需要翻译的文本    返回值:        text (str): 如果是另一种语言,则返回翻译后的文本,否则返回输入文本    """    try:        lang = translator.detect(text)        lang = lang.lang        print(f"检测到的语言: {lang}")        q = translator.translate(text, dest='en')        text = q.text    except Exception as e:        print("尝试翻译时出现异常")    return textdef get_safe_name(name):    """    此函数接受一个字符串并返回一个安全可用作文件名的版本    参数:        name (str): 要转换为安全文件名的字符串    返回值:        name (str): 安全的文件名    """    name = str(name)    name = re.sub("[^0-9a-zA-Z]+", "_", name)    name = re.sub(r"_$","", name)    if len(name) == 0:        name = 'Unknown'     return namedef download_pdf(url, download_path):      """    从URL下载PDF并本地保存的函数    参数:        url (str): 在线PDF文件的位置        download_path (str): 保存PDF的文件夹    """    response = requests.get(url)      with open(download_path, 'wb') as f:          f.write(response.content)    def save_text(content, file_path):      """    将文本保存到本地文件的函数    参数:        content (str): 要保存的文本        file_path (str): 保存路径     """    with open(file_path, 'w') as file:          print(f'保存 {file_path}')        file.write(content)    def extract_text_from_pdf(pdf_path):      """    从PDF文件中提取文本的函数    参数:        pdf_path (str): PDF文件路径    返回值:        text (str): 从PDF文件中提取的文本    """    print(pdf_path)    pdf_reader = PyPDF2.PdfReader(pdf_path)      text = ''      for page_num in range(len(pdf_reader.pages)):          page_obj = pdf_reader.pages[page_num]        text += page_obj.extract_text()      return text  def get_rw_data(keyword, filter, sort, fields, endpoint, limit=10, \                save_body_to_text=False):      """    从ReliefWeb API中提取数据的函数。有关API详细信息,请参见:    https://apidoc.rwlabs.org/?utm_VoAGI=blog&utm_source=reliefweb+website&utm_campaign=api+doc+launching+2016_06    参数:        keyword (str): 搜索字符串        filter (dict): ReliefWeb过滤器json        sort (dict): ReliefWeb排序json        fields (list): 要返回的字段列表        endpoint (str): API端点,例如报告、灾难        limit (int): 要返回的最大记录数        save_body_to_text (bool) : 是否保存正文到文本文件中,包括页面上的任何PDF    返回值:        all_data (pandas dataframe): 来自API的数据框    """    query = {          "appname": "myapp",          "query": {              "value": keyword        },          "filter":filter,        "sort": sort,        "limit": limit,          "fields": fields    }      endpoint = f"{reliefweb_api_url}/{endpoint}?appname=apidoc&query[value]="    print(f"获取 {endpoint} ...")      all_data =[]    response = requests.post(endpoint, json=query)      if response.status_code == 200:          data = response.json()          for article in data["data"]:             article_url = article['fields']['url']               try:                r = article['fields']                print(article_url)                article_response = requests.get(article_url)                  if save_body_to_text:                    soup = BeautifulSoup(article_response.text, 'html.parser')                      main_content = [p.text for p in soup.find_all('p')]                      article_text = ' '.join(main_content)                    save_text(article_text, docs_folder + '/{}.txt'.format(get_safe_name(article['fields']['title'])))                      for link in soup.find_all('a'):                          href = link.get('href')                          if href.endswith('.pdf'):                              download_path = os.path.join(docs_folder, href.split('/')[-1])                              if href.startswith('/attachments'):                                pdf_url = f'{reliefweb_pdf_url}{href}'                            else:                                pdf_url = href                            download_pdf(pdf_url, download_path)                              print(f".    从 {pdf_url} 下载了PDF {download_path}")                            article_text = extract_text_from_pdf(download_path)                    r['article_text'] = article_text                    r['reliefweb_query'] = keyword                all_data.append(r)            except Exception as e:                print(f"提取 {article_url} 时发生异常")                tb_str = ''.join(traceback.format_exception(None, e, e.__traceback__))                print(tb_str)        all_data = pd.DataFrame(all_data)        for f in ['disaster','theme']:            if f in list(all_data.columns):                all_data[f] = all_data[f].astype(str)        return all_data      else:          print(f"请求失败,状态 {response.status_code} {response.text}")          return None 

在上述函数中,一些要点如下:

  1. 如果ReliefWeb内容涉及PDF,我们会从中提取文本
  2. 使用Google翻译API自动将任何文本翻译成英文
  3. 我们总是捕获来源以进行归属
  4. 对于这次快速分析,我们没有处理API响应分页的问题

以下是我们调用该函数以获取2023年11月1日以来的灾害情况报告的示例代码:

filter = {    "operator": "AND",    "conditions": [        {            "field": "disaster.status",            "value": "ongoing"        },        {            "field": "format.name",            "value": "Situation Report"        },        {            "field": "date.created",            "value": {                "from": "2023-11-01T00:00:00+00:00",                "to": "2023-11-30T23:59:59+00:00"            }        }    ]}sort = ["date.created:desc"]endpoint = "reports"fields = {      "include": ["title", "body", "url", "source", "date", "format", "theme",     "country", "status", "primary_country", "disaster", "language", "id"] }  reliefweb_query = ""articles = get_rw_data(reliefweb_query, filter, sort, fields, endpoint, 1000, True)

情况报告将以文本文件的形式保存在文件系统中…

for index, row in articles.iterrows():    date = row['date']['created']    source = row['source'][0]['name']    title = row['title']    id = row['id']    filename = f'{get_safe_name(title)}__{id}_{get_safe_name(date)}.txt'    text = f'''        title: {title}        source: {source}        date: {date}        id: {id}        {row['article_text']}    '''    text = text.encode('utf-8','ignore').decode('utf-8','ignore')    print(text)    save_text(text, docs_folder + '/' + filename) 

使用稀疏引导表示(SPR)压缩内容

我们可以直接使用情况报告中的原始文本向GPT-4-Turbo提供提示。然而,其中大部分文本都是无关的,如停用词、标题和页脚,因此包含所有文本很快就会超出GPT-4-Turbo的标记限制。我们将使用一种称为稀疏引导表示(SPR)的技术将文档压缩为关键事实,并稍作修改以保留定量信息。

以下是我们将为GPT-4-Turbo提供的系统提示,用于压缩我们的文档:

# 任务您是Sparse Priming Representation (SPR)写手。 SPR是用于高级NLP、NLU和NLG任务的一种特定语言使用方式,对于最新一代大型语言模型(LLM)非常有用。您将接收到用户提供的信息,您需要将其渲染为SPR。
# 理论LLM是一种深度神经网络。已证明它们可以嵌入知识、能力和概念,涵盖从推理到规划,甚至理论思维等各个方面。这些称为潜在能力和潜在内容,总称为潜在空间。通过正确的一系列词汇作为输入,可以激活LLM的潜在空间,从而创建神经网络的有用内部状态。这有些类似于正确的速记提示可以启动人类思考。与人类思维类似,LLM是联想性的,这意味着您只需要使用正确的关联词来“引导”另一个模型以相同的方式思考。例外是定量指标,您必须保留它们。
# 方法将输入呈现为简明陈述、断言、关联、概念、类比和隐喻的精炼列表。这样做的目的是在尽可能简洁的情况下捕捉尽可能多的概念,同时保留所有定量细节。以对您自己有意义的方式编写,因为未来的受众将是另一个语言模型,而不是人类。

这将把原始文本状态报告总结成类似于题为“African Polio Laboratory Network Bulletin (week 1–42, 2023)”的情况报告的情况…

# 信息来源于世界卫生组织。- 每周登革热病例减少,本周报告12,634例。- 本周有78例与登革热相关的死亡。- 自2023年1月以来的累计病例:267,680例,其中包括1,333例死亡。- 除了锡尔赫特以外,所有地区的病例都在减少。- 法里德布尔、库尔纳、拉杰沙希、拉杰巴里等地的登革热病例增加。- 世卫组织于10月26日在达卡举行了对嗜血昆虫学家的培训会议。- 总体病死率为0.5%,本周病死率为0.62%。- 达卡地区报告的病例和死亡人数最多。- 本周有13,430人在治疗后出院。- 男性与女性死亡比例为43%:57%。- 大部分死亡人群年龄在16-55岁之间。- 目前循环的登革病毒有四种:DENV-1(2.2%)、DENV-2(68.1%)、DENV-3(25.4%)、DENV-4(0.2%)。- 登革热防治和清理周于10月29日至11月4日期间在全国范围内启动。- 世卫组织派遣专家昆虫学家前往孟加拉国提供疫情应对的技术支持。- 罗兴亚难民营的每周登革热病例仍在下降。累计病例为12,969例,其中死亡17例(病死率为0.1%)。

这当然比原始文档少得多。

我不建议在没有进行重要分析和检查以控制信息遗漏的情况下使用此压缩技术,但对于我们的测试来说,这已足够。

以下是用于压缩报告的代码…

# gpt4 turbo是128k chunk_size = 100000llm_query = {    "prompt": "",    "temperature": 1.0,    "max_tokens": 2000,    "top_p": 0.95,    "frequency_penalty": 0,    "presence_penalty": 0,    "system_prompt":"""        #任务        您是一位稀疏引导表示(SPR)作家。 SPR是一种特殊的语言使用方式,适用于高级NLP、NLU和NLG任务,对于最新一代的大型语言模型(LLM)特别有用。您将获得用户提供的信息,您需要将其呈现为SPR。        #理论        LLM是一种深度神经网络。它们已经证明可以嵌入知识、能力和概念,从推理到规划,甚至到心智理论。这些被称为潜在能力和潜在内容,集体称为潜在空间。通过正确的一系列词语输入,可以激活LLM的潜在空间,从而创建神经网络的有用内部状态。这与正确的速记提示能够激励人类思考的方式很相似。与人类思维一样,LLM是联想性的,这意味着您只需要使用正确的关联来“引导”另一个模型以相同的方式进行思考。唯一的例外是您必须保留定量指标。        #方法论        将输入内容呈现为精简的陈述、断言、联想、概念、类比和隐喻的浓缩列表。目标是在保留所有定量细节的前提下,用尽可能少的词语来捕捉尽可能多的概念。以您自己理解的方式撰写,因为未来的受众将是另一个语言模型,而不是人类。    """}# 保存文本for index, row in articles.iterrows():    date = row['date']['created']    source = row['source'][0]['name']    report = row['title']    id = row['id']    text = row['article_text']    primary_country = row['primary_country']['name']    disaster = ''    disaster_types = ''    for d in ast.literal_eval(row['disaster']):        disaster += f"{d['name']}; "        for t in d['type']:            if 'primary' in t and t['primary'] == True:                disaster_types += f"{t['name']}; "    d = {        "disaster": disaster,        "date": date,        "disaster_types": disaster_types    }    prefix = ""    filename = f'{get_safe_name(report)}__{id}_{get_safe_name(date)}.txt'    header = f'- 报告:" {report}"\n- 灾害:"{disaster}"\n' + \             f'- 灾害类型:"{disaster_types}"\n' + \             f'- 主要国家:" {primary_country}"\n- 来源:" {source}"\n' + \             f'- 日期:" {date}"\n- id:" {id}"\n'    text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(        chunk_size=chunk_size, chunk_overlap=100    )    texts = text_splitter.split_text(text)    print(f"\n\n================ {report} =================\n")    print(primary_country)    print(disaster)    print(len(texts))    summarized_text = ''    for i, t in enumerate(texts):        response = openai.ChatCompletion.create(        model=model,        messages=[  {                "role":"system",                "content":llm_query['system_prompt']            },            {                "role":"user",                "content":t            }        ],        temperature=llm_query['temperature'],        max_tokens=llm_query['max_tokens'],        top_p=llm_query['top_p'],        frequency_penalty=llm_query['frequency_penalty'],        presence_penalty=llm_query['presence_penalty'],        stop=None)          summary = response['choices'][0]['message']['content']        summarized_text += "\n" + summary    summarized_text = auto_translate(summarized_text)    summarized_text = header + summarized_text    summarized_text = summarized_text.split("\n")    summarized_text_prefixed = ''    for s in summarized_text:        summarized_text_prefixed += f"{prefix}{s}\n"    print(summarized_text_prefixed)    save_text(summarized_text_prefixed, docs_folder2 + '/' + filename)

您会注意到上述中我们添加了一些关于报告的元数据以及由GPT-4-Turbo返回的SPR摘要。然后将压缩的报告保存为文本文件。

提取高级灾难列表

我们还将从ReliefWeb中提取一份高级灾难列表,以在我们的系统提示中使用,作为信息请求的辅助…

filter = {    "operator": "AND",    "conditions": [        {            "field": "status",            "value": "ongoing"        },        {            "field": "date.event",            "value": {                "from": "2020-01-01T00:00:00+00:00",                "to": "2023-11-30T23:59:59+00:00"            }        }    ]}sort = ["date.event:desc"]endpoint = "disasters"fields = {      "include": ["name","description","date","url","id","status","glide"] } reliefweb_query = ""disasters = get_rw_data(reliefweb_query, filter, sort, fields, endpoint, 1000, False)display(disasters)disasters.to_csv('disasters.csv')

这给我们提供了一个简明的列表…

使用ReleiefWeb API disasters endpoint提取的灾难列表

为GPT-4-Turbo创建提示

现在我们有了一份灾难列表和压缩的情况报告-从11月1日到11月10日-列出了这些灾难的关键事实。

让我们将它们合并成一个文本文件,作为GPT-4-Turbo系统提示的一部分使用…

disasters = pd.read_csv('disasters.csv')concatenated_content = "=========== 这一部分提供了一个灾难列表 =========== \n\n "+ disasters.to_csv() concatenated_content += "\n\n=========== 这一部分为每个灾难提供了灾难报告 =========== "for f in os.listdir(docs_folder2):  with open(f"{docs_folder2}/{f}", "r") as file:      file_content = file.read()      concatenated_content += f"\n\n----- 报告: {f} ----- \n\n"      concatenated_content += file_content + "\n\n"

有多少令牌以及费用是多少?

def num_tokens_from_string(string: str, encoding_name: str) -> int:    encoding = tiktoken.get_encoding(encoding_name)    num_tokens = len(encoding.encode(string))    gpt4_token_cost_per_1000 = 0.01    cost = (num_tokens/1000.0)*gpt4_token_cost_per_1000    return num_tokens, costtokens, cost = num_tokens_from_string(concatenated_content,"cl100k_base")OpenAI Tokens: 82001 ($0.82001)

因此,给定每1000个输入令牌0.01美元的费用,上述创建的文本的费用为0.82美元。还有一些完成令牌的成本,每1000个令牌0.03美元,但这应该远低于输入成本,因为令牌数量要少得多。

哎呀!

我们知道这种蛮力技术并不是解决我们特定任务的最佳方式,但高成本是另一个原因。

现在我们有了文本,我们可以构建一个系统提示…

def run_llm(query, reference_content):    llm_query = {        "temperature": 1.0,        "max_tokens": 2000,        "top_p": 0.95,        "frequency_penalty": 0,        "presence_penalty": 0,    }    response = openai.ChatCompletion.create(        model=model,        messages=[  {                "role":"system",                "content": f"""您是一个ReliefWeb灾难机器人。 请提供关于灾难的信息。如果要求提供灾难列表,请只使用下面的“灾难”部分。如果要求提供灾难的详细信息,请从下面的“情况报告”部分提取该信息。                                   {reference_content}"""            },            {                "role":"user",                "content": query            }        ],        temperature=llm_query['temperature'],        max_tokens=llm_query['max_tokens'],        top_p=llm_query['top_p'],        frequency_penalty=llm_query['frequency_penalty'],        presence_penalty=llm_query['presence_penalty'],        stop=None    )      answer = response['choices'][0]['message']['content']    return answer

您会注意到,系统提示中包含有关在连接的文本中使用不同类型的信息的说明。通过一些快速的提示实验 – 我不会真的称之为“工程” – 这产生了更好的结果。

测试我们的人道主义灾害情况报告机器人

好的,这里开始……

answer = run_llm("关于今年尼泊尔地震的最新情况是什么?", concatenated_content)print(answer)

截至2023年11月,尼泊尔地震的最新情况如下:- 地震:尼泊尔西部,6.4级,于2023年11月3日发生,震中位于贾贾尔科特的拉米丹达。- 伤亡情况:154人死亡,364人以上受伤。- 置身困境:约有25万人受到影响,大量房屋受损或毁坏。- 基础设施:13个地区内的超过6.2万座房屋受损(完全损坏26557座,部分损坏35455座)。数座政府建筑也受损。- 人道主义应对:联合国和其他人道主义组织一直积极参与救援行动,提供医疗帐篷、适合儿童的场所、卫生用品和心理社会支持等援助。- 恢复和重建:正在计划恢复和重建阶段,国际支援正前来协助协调和制定策略。- 教育和健康服务:由于学校受损,大约8万名儿童的教育受到干扰,健康服务也受到影响,增加了营养不良的风险,增加了产妇和新生儿护理的复杂性。请注意,这是对截至2023年11月10日的可用数据的概述,随着情况的发展和更多评估的进行,可能会有进一步的更新。

总体而言,这是对灾害的一个相当好的摘要。与ReliefWeb灾难页面(请注意,此页面可能会随着灾难的发展而变化)和用于此研究的最新情况报告相比,事实基本一致。

然而,一个事实略微不准确,数据显示不幸地有153人死亡,而模型返回的是154人。

answer = run_llm("2023年尼泊尔地震中有多少人死亡?", concatenated_content)print(answer)在2023年11月的尼泊尔地震中,有153人遇难。

所以在第一个提示中它被“知道”但是出现了幻觉。与LLM的所有应用一样,验证和检查是捕捉此类问题的关键。

让我们获取一些有关创建情况报告的组织的信息(对于11月1日至10日的情况)……

answer = run_llm("列出为尼泊尔地震提供情况报告的组织", concatenated_content)print(answer)为尼泊尔地震提供情况报告(sitrep)的组织包括:- 联合国人道事务协调厅(OCHA)- 尼泊尔红十字会- 国际红十字和红新月会联合会(IFRC)- 联合国驻尼泊尔协调员- 世界卫生组织(WHO)- 联合国儿童基金会(UNICEF)- 联合国驻尼泊尔国家组

ReliefWeb中相同的查询相比,这似乎是正确的。

让我们问一些更具细微差别的问题……

answer = run_llm("有多少流离失所的人是儿童?", concatenated_content)print(answer)在提供的数据中,有多个报告提到受灾儿童,但具体的流离失所儿童数量没有直接在任何摘录中提及。为了确定受流离失所影响的具体人数,需要更仔细地审查更详细的报告或数据来源,重点关注儿童流离失所的数字。

通过查看情况报告,我也无法找到这个信息。需要进行更详细的后期核查才能确定这是正确的。

让我们询问一些与潜在疾病和健康影响有关的问题……

answer = run_llm("尼泊尔2023年地震存在哪些疾病风险?", concatenated_content)print(answer)根据联合国儿童基金会在他们的第二份人道主义情况报告中所述,尼泊尔2023年地震的疾病风险主要集中在营养不良,尤其是在5岁以下儿童中,以及影响受灾人口的心理社会压力上。地震导致的医疗保健和水源、卫生和卫生防疫(WASH)服务中断,进一步加剧了健康风险。主要的疾病风险和健康问题包括:1. 营养不良:地震及其后果破坏了食品供应链,这可能增加了脆弱群体(尤其是儿童)患营养不良的风险。2. 孕产妇健康:由于医疗保健服务中断和无法获得基本医疗护理和设施,孕妇和新生儿可能面临增加的健康风险。3. 心理社会压力:地震造成的创伤,失去亲人和流离失所可能导致严重的心理社会压力和心理健康问题。4. 伤害和身体健康:在地震后有许多人受伤,需要医疗治疗和创伤护理。 5. 传染病:临时庇护所的过度拥挤可能导致传染病传播,尤其是在没有适当卫生设施的情况下。6. 水传播和媒介传播疾病:缺乏清洁水和卫生设施增加了水传播疾病(如腹泻、霍乱和痢疾)的风险。还存在媒介传播疾病(如疟疾和登革热)的担忧。7. 非传染性疾病:常规健康服务的中断可能影响慢性非传染性疾病的管理和治疗。8. 常规免疫接种中断:常规免疫接种服务的潜在中断可能增加疫苗可预防疾病的风险。针对这些健康风险,UNICEF和其他卫生部门合作伙伴一直提供卫生服务、医疗用品和心理社会支持,以确保儿童和母亲持续获得营养。

查看数据中的联合国儿童基金会报告,即使使用我们的SPF摘要,上述内容似乎捕捉到了主要观点。然而,我们在此使用的数据只有报告编号1,而上述提到了报告编号2。另一个小幻觉,再次证明任何LLM回应都需要自动反馈检查。

结论

这是一个非常快速的分析,用于了解GPT-4-Turbo(具有128k上下文窗口和改进的指令遵循)通过将所有所需的文本数据包含为系统提示,而无需任何其他处理,来执行信息检索的效果如何。这种蛮力方法是否是我们任务的最佳技术?

可能不是,至少还不是。

性能是一个严肃的考虑因素。提示需要30秒或更长时间,对于愉快的用户体验来说并不理想。

成本也是一个限制因素。为了提供完整的语料库,每个提示需要更多标记,造成了成本的增加 – 在这个分析中,每个提示的成本为0.82美元!因此,其他技术无疑会对许多组织更有吸引力,至少在LLM成本居高不下的情况下。话虽如此,我想起了多年来存储成本的减少,也许我们会看到LLM的相同降低。

生成查询数据的代码、使用与LLM注册的函数以及使用多个代理程序验证结果等替代方案可能提供更便宜和更准确的选择。它们还可以消除为了适应上下文窗口而压缩文档的需要,从而避免信息丢失。

话虽如此,我们能够显示提示GPT-4-Turbo可以支持对通过系统提示提供的压缩文档语料库进行基本信息检索。这在实现上非常简单-只需将所有内容提供给LLM并提问。随着人工智能的进步和成本的降低,这可能会成为未来非常常见的技术。