category
检索增强生成(RAG)是一种通过添加提供基础数据的信息检索系统来增强大型语言模型(LLM)(如ChatGPT)的能力的架构。添加信息检索系统可以控制LLM在制定响应时使用的基础数据。对于企业解决方案,RAG架构意味着,如果您有针对企业内容的嵌入模型,您可以将生成性人工智能约束到源于矢量化文档和图像以及其他数据格式的企业内容。
决定使用哪种信息检索系统至关重要,因为它决定了LLM的输入。信息检索系统应提供:
- 索引策略,可按您需要的频率为您的所有内容大规模加载和刷新。
- 查询功能和相关性调整。系统应以满足LLM输入的令牌长度要求所需的简短格式返回相关结果。
- 数据和操作的安全性、全球覆盖范围和可靠性。
- 与用于索引的嵌入模型以及用于检索的聊天模型或语言理解模型集成。
Azure AI Search是RAG架构中经过验证的信息检索解决方案。它提供索引和查询功能,以及Azure云的基础设施和安全性。通过代码和其他组件,您可以设计一个全面的RAG解决方案,其中包括在您的专有内容上生成人工智能的所有元素。
笔记
副驾驶和RAG概念的新手?观看Generative AI应用程序的矢量搜索和最先进的检索。
Azure AI搜索的RAG方法
微软有几个在RAG解决方案中使用Azure AI搜索的内置实现。
- Azure AI Studio,使用矢量索引和检索增强。
- Azure OpenAI Studio,使用带有或不带有矢量的搜索索引。
- Azure机器学习,使用搜索索引作为提示流中的矢量存储。
经过策划的方法使入门变得简单,但为了更好地控制体系结构,您需要一个自定义的解决方案。这些模板在以下位置创建端到端解决方案:
本文的其余部分探讨了Azure人工智能搜索如何融入自定义RAG解决方案。
Azure AI搜索的自定义RAG模式
模式的高级摘要如下所示:
- 从用户问题或请求(提示)开始。
- 将其发送到Azure AI Search以查找相关信息。
- 将排名靠前的搜索结果发送给LLM。
- 使用LLM的自然语言理解和推理能力生成对初始提示的响应。
Azure AI Search为LLM提示提供输入,但不训练模型。在RAG架构中,没有额外的训练。LLM是使用公共数据进行预训练的,但它生成的响应会被来自检索器的信息所增强。
包括Azure AI搜索在内的RAG模式具有下图所示的元素。
使用搜索和ChatGPT进行信息检索的体系结构图。
- 用户体验的应用程序UX(网络应用程序)
- 应用服务器或协调器(集成和协调层)
- Azure AI搜索(信息检索系统)
- Azure OpenAI(生成人工智能LLM)
网络应用程序提供用户体验,提供演示、上下文和用户交互。用户的问题或提示从这里开始。输入通过集成层,首先进入信息检索以获得搜索结果,还进入LLM以设置上下文和意图。
应用程序服务器或协调器是协调信息检索和LLM之间切换的集成代码。一种选择是使用LangChain来协调工作流。LangChain与Azure AI Search集成,使Azure AI Search更容易作为检索器包含在您的工作流程中。语义内核是另一种选择。
信息检索系统提供可搜索索引、查询逻辑和有效载荷(查询响应)。搜索索引可以包含矢量或非矢量内容。尽管大多数示例和演示都包含向量场,但这不是必需的。该查询使用Azure AI search中现有的搜索引擎执行,该引擎可以处理关键字(或术语)和矢量查询。索引是根据您定义的架构预先创建的,并加载来自文件、数据库或存储的内容。
LLM接收原始提示,以及Azure AI搜索的结果。LLM分析结果并制定响应。如果LLM是ChatGPT,则用户交互可能是来回对话。如果您使用的是Davinci,提示可能是一个完全合成的答案。Azure解决方案很可能使用Azure OpenAI,但对该特定服务没有硬性依赖。
Azure AI Search不提供用于提示流或聊天保存的本地LLM集成,因此您需要编写处理编排和状态的代码。您可以查看演示源(Azure Samples/Azure search openai demo),了解完整解决方案的蓝图。我们还建议Azure AI Studio或Azure OpenAI Studio创建与LLM集成的基于RAG的Azure AI搜索解决方案。
Azure AI搜索中的可搜索内容
在Azure AI搜索中,所有可搜索内容都存储在您的搜索服务上托管的搜索索引中。搜索索引是为响应时间为毫秒的快速查询而设计的,因此它的内部数据结构可以支持这一目标。为此,搜索索引存储索引内容,而不是像整个PDF或图像那样存储整个内容文件。在内部,数据结构包括标记化文本的反向索引、嵌入的矢量索引,以及在需要逐字匹配的情况下(例如,在过滤器、模糊搜索、正则表达式查询中)的未更改文本。
当您为RAG解决方案设置数据时,您将使用在Azure AI搜索中创建和加载索引的功能。索引包括重复或表示源内容的字段。索引字段可能是简单的转移(源文档中的标题或描述变成搜索索引中的标题和描述),或者字段可能包含外部过程的输出,例如生成图像的表示或文本描述的矢量化或技能处理。
由于您可能知道要搜索的内容类型,请考虑适用于每种内容类型的索引功能:
Content type | Indexed as | Features |
---|---|---|
text | tokens, unaltered text | Indexers can pull plain text from other Azure resources like Azure Storage and Cosmos DB. You can also push any JSON content to an index. To modify text in flight, use analyzers and normalizers to add lexical processing during indexing. Synonym maps are useful if source documents are missing terminology that might be used in a query. |
text | vectors 1 | Text can be chunked and vectorized externally and then indexed as vector fields in your index. |
image | tokens, unaltered text 2 | Skills for OCR and Image Analysis can process images for text recognition or image characteristics. Image information is converted to searchable text and added to the index. Skills have an indexer requirement. |
image | vectors 1 | Images can be vectorized externally for a mathematical representation of image content and then indexed as vector fields in your index. You can use an open source model like OpenAI CLIP to vectorize text and images in the same embedding space. |
1矢量支持的通用功能要求您调用其他库或模型进行数据分块和矢量化。但是,集成矢量化(预览)嵌入了这些步骤。有关显示这两种方法的代码示例,请参阅azure搜索向量repo。
2技能是对人工智能丰富的内置支持。对于OCR和图像分析,索引管道对Azure AI Vision API进行内部调用。这些技能将提取的图像传递给Azure AI进行处理,并接收Azure AI搜索索引的文本输出。
矢量为不同的内容(多种文件格式和语言)提供了最佳的适应能力,因为内容在数学表示中是通用的。矢量还支持相似性搜索:在与矢量查询最相似的坐标上进行匹配。与在标记化术语上匹配的关键词搜索(或术语搜索)相比,相似性搜索更微妙。如果内容或查询中存在歧义或解释要求,这是一个更好的选择。
Azure AI搜索中的内容检索
一旦你的数据在搜索索引中,你就可以使用Azure AI搜索的查询功能来检索内容。
在非RAG模式中,查询从搜索客户端进行往返。查询被提交,在搜索引擎上执行,响应返回到客户端应用程序。响应或搜索结果完全由索引中的逐字内容组成。
在RAG模式中,查询和响应在搜索引擎和LLM之间进行协调。用户的问题或查询被转发到搜索引擎和LLM作为提示。搜索结果从搜索引擎返回并重定向到LLM。返回给用户的响应是生成人工智能,要么是LLM的总和,要么是答案。
Azure AI搜索中没有构成新答案的查询类型,甚至没有语义或矢量搜索。只有LLM提供生成人工智能。以下是Azure人工智能搜索中用于制定查询的功能:
Query feature | Purpose | Why use it |
---|---|---|
Simple or full Lucene syntax | Query execution over text and nonvector numeric content | Full text search is best for exact matches, rather than similar matches. Full text search queries are ranked using the BM25 algorithm and support relevance tuning through scoring profiles. It also supports filters and facets. |
Filters and facets | Applies to text or numeric (nonvector) fields only. Reduces the search surface area based on inclusion or exclusion criteria. | Adds precision to your queries. |
Semantic ranking | Re-ranks a BM25 result set using semantic models. Produces short-form captions and answers that are useful as LLM inputs. | Easier than scoring profiles, and depending on your content, a more reliable technique for relevance tuning. |
Vector search | Query execution over vector fields for similarity search, where the query string is one or more vectors. | Vectors can represent all types of content, in any language. |
Hybrid search | Combines any or all of the above query techniques. Vector and nonvector queries execute in parallel and are returned in a unified result set. | The most significant gains in precision and recall are through hybrid queries. |
构建查询响应
查询的响应为LLM提供了输入,因此搜索结果的质量对成功至关重要。结果是一个表格行集。结果的组成或结构取决于:
- 用于确定响应中包含索引的哪些部分的字段。
- 表示与索引匹配的行。
当属性为“可检索”时,字段将显示在搜索结果中。索引模式中的字段定义具有属性,这些属性决定响应中是否使用字段。在全文或矢量查询结果中只返回“可检索”字段。默认情况下,会返回所有“可检索”字段,但您可以使用“选择”来指定子集。除了“可检索”之外,这个领域没有任何限制。字段可以是任何长度或类型。关于长度,Azure AI搜索中没有最大字段长度限制,但API请求的大小有限制。
行是查询的匹配项,按相关性、相似性或两者进行排名。默认情况下,全文搜索的结果上限为前50个匹配项,矢量搜索的结果下限为k近邻匹配项。您可以更改默认值以增加或减少限制,最多1000个文档。您还可以使用top和skip分页参数将结果作为一系列分页结果进行检索。
按相关性排序
当您处理复杂的流程、大量的数据和对毫秒级响应的期望时,至关重要的是,每一步都要增加价值并提高最终结果的质量。在信息检索方面,相关性调整是一种提高发送到LLM的结果质量的活动。结果中只应包括最相关或最相似的匹配文档。
相关性适用于关键字(非向量)搜索和混合查询(在非向量字段上)。在Azure AI搜索中,没有针对相似性搜索和矢量查询的相关性调整。BM25排名是用于全文搜索的排名算法。
通过增强BM25排名的功能支持相关性调整。这些方法包括:
- 如果在特定搜索字段或其他条件中找到匹配项,则可以提高搜索分数的评分配置文件。
- 语义排序,使用Bing的语义模型对BM25结果集进行重新排序,以使结果在语义上更好地适应原始查询。
在比较和基准测试中,具有文本和矢量字段的混合查询,再加上对BM25排名结果的语义排名,产生了最相关的结果。
RAG场景的Azure AI搜索查询示例代码
以下代码是从演示站点的retrievetherread.py文件中复制的。它从混合查询搜索结果中为LLM生成内容。您可以编写一个更简单的查询,但此示例包含向量搜索和关键字搜索,以及语义重新排序和拼写检查。在演示中,此查询用于获取初始内容。
Python
# Use semantic ranker if requested and if retrieval mode is text or hybrid (vectors + text)
if overrides.get("semantic_ranker") and has_text:
r = await self.search_client.search(query_text,
filter=filter,
query_type=QueryType.SEMANTIC,
query_language="en-us",
query_speller="lexicon",
semantic_configuration_name="default",
top=top,
query_caption="extractive|highlight-false"
if use_semantic_captions else None,
vector=query_vector,
top_k=50 if query_vector else None,
vector_fields="embedding" if query_vector else None)
else:
r = await self.search_client.search(query_text,
filter=filter,
top=top,
vector=query_vector,
top_k=50 if query_vector else None,
vector_fields="embedding" if query_vector else None)
if use_semantic_captions:
results = [doc[self.sourcepage_field] + ": " + nonewlines(" . ".join([c.text for c in doc['@search.captions']])) async for doc in r]
else:
results = [doc[self.sourcepage_field] + ": " + nonewlines(doc[self.content_field]) async for doc in r]
content = "\n".join(results)
集成代码和LLM
包括Azure AI Search的RAG解决方案需要其他组件和代码才能创建完整的解决方案。前几节介绍了通过Azure AI搜索进行的信息检索,以及哪些功能用于创建和查询可搜索内容,而本节介绍了LLM集成和交互。
演示存储库中的笔记本是一个很好的起点,因为它们显示了将搜索结果传递给LLM的模式。RAG解决方案中的大多数代码都由对LLM的调用组成,因此您需要了解这些API是如何工作的,这超出了本文的范围。
chat-read-retriev-read.ipynb笔记本中的以下单元格块显示聊天会话上下文中的搜索调用:
Python
# Execute this cell multiple times updating user_input to accumulate chat history
user_input = "Does my plan cover annual eye exams?"
# Exclude category, to simulate scenarios where there's a set of docs you can't see
exclude_category = None
if len(history) > 0:
completion = openai.Completion.create(
engine=AZURE_OPENAI_GPT_DEPLOYMENT,
prompt=summary_prompt_template.format(summary="\n".join(history), question=user_input),
temperature=0.7,
max_tokens=32,
stop=["\n"])
search = completion.choices[0].text
else:
search = user_input
# Alternatively simply use search_client.search(q, top=3) if not using semantic ranking
print("Searching:", search)
print("-------------------")
filter = "category ne '{}'".format(exclude_category.replace("'", "''")) if exclude_category else None
r = search_client.search(search,
filter=filter,
query_type=QueryType.SEMANTIC,
query_language="en-us",
query_speller="lexicon",
semantic_configuration_name="default",
top=3)
results = [doc[KB_FIELDS_SOURCEPAGE] + ": " + doc[KB_FIELDS_CONTENT].
replace("\n", "").replace("\r", "") for doc in r]
content = "\n".join(results)
prompt = prompt_prefix.format(sources=content) +
prompt_history + user_input + turn_suffix
completion = openai.Completion.create(
engine=AZURE_OPENAI_CHATGPT_DEPLOYMENT,
prompt=prompt,
temperature=0.7,
max_tokens=1024,
stop=["<|im_end|>", "<|im_start|>"])
prompt_history += user_input + turn_suffix + completion.choices[0].text
+ "\n<|im_end|>" + turn_prefix
history.append("user: " + user_input)
history.append("assistant: " + completion.choices[0].text)
print("\n-------------------\n".join(history))
print("\n-------------------\nPrompt:\n" + prompt)
如何开始
使用Azure AI Studio创建搜索索引。- 使用Azure OpenAI Studio并“自带数据”,在操场上对现有搜索索引进行提示实验。这一步可以帮助您决定使用什么模型,并向您展示现有索引在RAG场景中的工作效果。
- Azure AI搜索团队构建的“与数据聊天”解决方案加速器可帮助您创建自己的自定义RAG解决方案。
- 企业聊天应用程序模板使用Contoso和Northwind的虚拟健康计划文档部署Azure资源、代码和示例基础数据。此端到端解决方案只需15分钟即可为您提供一个可操作的聊天应用程序。这些模板的代码是一些演示中介绍的azure搜索openai演示。以下链接提供特定于语言的版本:
- 审查索引概念和策略,以确定您希望如何吸收和刷新数据。决定是使用矢量搜索、关键字搜索还是混合搜索。需要搜索的内容类型和要运行的查询类型决定了索引设计。
- 查看创建查询以了解更多搜索请求语法和要求。
笔记
一些Azure人工智能搜索功能是为人类互动而设计的,在RAG模式中没有用处。具体来说,您可以跳过自动完成和建议。其他功能(如facet和orderby)可能很有用,但在RAG场景中并不常见。
另请参阅
- 登录 发表评论
- 42 次浏览
最新内容
- 2 days 13 hours ago
- 2 days 13 hours ago
- 2 days 13 hours ago
- 2 days 13 hours ago
- 3 days 18 hours ago
- 1 week 4 days ago
- 1 week 4 days ago
- 1 week 4 days ago
- 2 weeks ago
- 2 weeks ago