你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
注释
此功能目前处于公开预览状态。 此预览版未随附服务级别协议,建议不要用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款。
本文介绍用于构建使用 Azure AI 搜索进行知识检索的解决方案的方法或模式,以及如何将知识检索集成到包含 Azure AI 代理的自定义解决方案中。 此模式使用代理工具在 Azure AI 搜索中调用代理检索管道。
本练习与 代理检索快速入门 的不同之处在于:它使用 Azure AI 代理从索引中检索数据,并利用代理工具进行协调。 若要以最简单的形式了解检索管道,请从快速入门开始。
小窍门
若要运行本教程的代码,请在 GitHub 上下载 agentic-retrieval-pipeline-example Python 示例。
先决条件
此设计模式需要以下资源:
Azure AI 搜索,提供语义分级的区域中的基本定价层或更高层。
满足 代理检索索引条件的搜索索引。
Azure AI Foundry 中的项目,在基本设置中使用 Azure AI 代理。
按照 为 Azure AI Foundry 创建项目中的步骤进行操作。 创建项目还会在 Azure 订阅中创建 Azure AI Foundry 资源。
Azure OpenAI 部署了下面列出的聊天完成模型之一。 我们建议为模型至少提供 100,000 个令牌容量。 可以在 Azure AI Foundry 门户的模型部署列表中查找容量和速率限制。 如果需要 在查询时进行矢量化,还可以部署文本嵌入模型。
支持的大型语言模型
将以下聊天补全模型之一与 AI 智能体配合使用:
gpt-4ogpt-4o-minigpt-4.1gpt-4.1-nanogpt-4.1-minigpt-5gpt-5-nanogpt-5-mini
包版本要求
使用提供预览功能的包版本。 请参阅requirements.txt文件以了解示例解决方案中使用的更多包。
azure-ai-projects==1.1.0b3
azure-ai-agents==1.2.0b3
azure-search-documents==11.7.0b1
配置访问权限
在开始之前,请确保你有权访问内容和操作。 我们建议使用 Microsoft Entra ID 进行身份验证,并通过基于角色的访问来进行授权。 你必须是 所有者 或 用户访问管理员 才能分配角色。 如果角色不可行,则可以改用 基于密钥的身份验证 。
配置对此部分中标识的每个资源的访问。
Azure AI 搜索提供代理检索管道。 为自己、应用和搜索服务配置访问权限,以便下游访问模型。
开发任务
Azure AI 搜索端的开发任务包括:
- 创建一个知识源,映射到可搜索索引。
- 在 Azure AI 搜索上创建一个知识代理,该代理映射到 Azure AI Foundry 模型中的已部署模型。
- 调用检索器 并提供查询、对话和替代参数。
- 分析要包含在聊天应用程序中的部分的响应。 对于许多方案,仅响应的内容部分就足够了。 还可以尝试对更简单的工作流进行 答案合成 。
Azure AI 代理端的开发包括:
- 设置 AI 项目客户端和 AI 代理。
- 添加一个工具来协调 AI 智能体对检索器和知识智能体的调用。
查询处理由客户端应用中的用户交互(如聊天机器人)启动,该机器人调用 AI 代理。 AI 代理配置为使用一个工具来协调请求并指示响应。 聊天机器人调用代理时,该工具在 Azure AI 搜索上调用 检索器 ,等待响应,然后将响应发送回 AI 代理和聊天机器人。 在 Azure AI 搜索中,可以使用 答案合成 从查询管道中获取 LLM 生成的响应,或者如果需要更好地控制应答生成,可以在代码中调用 LLM。
解决方案的组件
自定义应用程序对 Azure AI 搜索和 Azure SDK 进行 API 调用。
- 外部数据可以来自任意位置,但我们建议使用 用于集成索引的数据源。
- Azure AI 搜索,托管索引数据和代理数据检索引擎。
- Azure AI Foundry,托管 AI 代理和工具。
- 使用 Foundry 项目的 Azure SDK,提供对 Azure AI Foundry 的程序化访问。
- Azure OpenAI,托管知识智能体使用的聊天补全模型以及矢量化器用于矢量搜索的任何嵌入模型。
配置你的环境
代理检索的规范用例是通过 Azure AI 代理服务实现的。 建议使用它,因为它是创建聊天机器人的最简单方法。
代理到代理解决方案将 Azure AI 搜索与用于生成自定义代理的 Foundry 项目相结合。 代理通过跟踪聊天历史记录和调用其他工具来简化开发。
需要以下终结点:
- Azure AI 搜索
- Azure OpenAI
- Azure AI Foundry 项目
可以在 Azure 门户中各资源的概述页中找到 Azure AI 搜索和 Azure OpenAI 的终结点。
可以在 Azure AI Foundry 门户中找到项目终结点:
登录到 Azure AI Foundry 门户 并打开项目。
在 “概述” 磁贴中,查找并复制 Azure AI Foundry 项目终结点。
假设终结点可能如下所示:
https://your-foundry-resource.services.ai.azure.com/api/projects/your-foundry-project
如果在 Foundry 项目中没有 Azure OpenAI 资源,请重新访问模型部署先决条件。 部署模型时会创建与资源的连接。
设置 AI 项目客户端并创建代理
使用 AIProjectClient 创建 AI 代理。
from azure.ai.projects import AIProjectClient
project_client = AIProjectClient(endpoint=project_endpoint, credential=credential)
list(project_client.agents.list_agents())
智能体由受支持的语言模型提供支持,说明会告知智能体其范围。
instructions = """
A Q&A agent that can answer questions about the Earth at night.
Sources have a JSON format with a ref_id that must be cited in the answer using the format [ref_id].
If you do not have the answer, respond with "I don't know".
"""
agent = project_client.agents.create_agent(
model=agent_model,
name=agent_name,
instructions=instructions
)
print(f"AI agent '{agent_name}' created or updated successfully")
将自主检索工具添加到 AI 代理系统中
端到端管道需要一种编排机制来协调在 Azure AI 搜索中对检索器和知识代理的调用。 可以使用工具来完成此任务。 该工具在 AI 代理中配置,并调用 Azure AI 搜索知识检索客户端,并发送回响应,以驱动用户聊天。
from azure.ai.agents.models import FunctionTool, ToolSet, ListSortOrder
from azure.search.documents.agent import KnowledgeAgentRetrievalClient
from azure.search.documents.agent.models import KnowledgeAgentRetrievalRequest, KnowledgeAgentMessage, KnowledgeAgentMessageTextContent
agent_client = KnowledgeAgentRetrievalClient(endpoint=endpoint, agent_name=agent_name, credential=credential)
thread = project_client.agents.threads.create()
retrieval_results = {}
# AGENTIC RETRIEVAL DEFINITION "LIFTED AND SHIFTED" TO NEXT SECTION
functions = FunctionTool({ agentic_retrieval })
toolset = ToolSet()
toolset.add(functions)
project_client.agents.enable_auto_function_calls(toolset)
如何构建消息
发送到代理工具的消息包括关于聊天历史记录的指示,以及如何使用在 Azure AI 搜索上从知识检索中获取的结果。 响应作为没有序列化或结构的大型单个字符串传递。
此代码片段是前面代码片段中提到的代理检索定义。
def agentic_retrieval() -> str:
"""
Searches a NASA e-book about images of Earth at night and other science related facts.
The returned string is in a JSON format that contains the reference id.
Be sure to use the same format in your agent's response
You must refer to references by id number
"""
# Take the last 5 messages in the conversation
messages = project_client.agents.messages.list(thread.id, limit=5, order=ListSortOrder.DESCENDING)
# Reverse the order so the most recent message is last
messages = list(messages)
messages.reverse()
retrieval_result = agent_client.retrieve(
retrieval_request=KnowledgeAgentRetrievalRequest(
messages=[
KnowledgeAgentMessage(
role=m["role"],
content=[KnowledgeAgentMessageTextContent(text=m["content"])]
) for m in messages if m["role"] != "system"
]
)
)
# Associate the retrieval results with the last message in the conversation
last_message = messages[-1]
retrieval_results[last_message.id] = retrieval_result
# Return the grounding response to the agent
return retrieval_result.response[0].content[0].text
如何启动对话
若要开始聊天,请使用标准的 Azure AI 代理工具调用 API。 发送包含问题的消息,然后智能体会使用智能体检索来决定何时从搜索索引中检索知识。
from azure.ai.agents.models import AgentsNamedToolChoice, AgentsNamedToolChoiceType, FunctionName
message = project_client.agents.messages.create(
thread_id=thread.id,
role="user",
content="""
Why do suburban belts display larger December brightening than urban cores even though absolute light levels are higher downtown?
Why is the Phoenix nighttime street grid is so sharply visible from space, whereas large stretches of the interstate between midwestern cities remain comparatively dim?
"""
)
run = project_client.agents.runs.create_and_process(
thread_id=thread.id,
agent_id=agent.id,
tool_choice=AgentsNamedToolChoice(type=AgentsNamedToolChoiceType.FUNCTION, function=FunctionName(name="agentic_retrieval")),
toolset=toolset)
if run.status == "failed":
raise RuntimeError(f"Run failed: {run.last_error}")
output = project_client.agents.messages.get_last_message_text_by_role(thread_id=thread.id, role="assistant").text.value
print("Agent response:", output.replace(".", "\n"))
如何提高数据质量
搜索结果被合并成一个完整的统一字符串,可以传递给聊天生成模型,以获取基于可靠信息的答案。 Azure AI 搜索中的以下索引和相关性优化功能可帮助你生成高质量的结果。 可以在搜索索引中实现这些功能,搜索相关性的改进在检索期间返回的响应质量中显而易见。
评分配置文件(已添加到搜索索引中)提供内置提升条件。 您的索引必须指定一个默认评分配置文件,当查询包含与该配置文件关联的字段时,检索引擎将使用这个配置文件。
语义配置 是必需的,但你可以确定哪些字段的优先级并用于排名。
对于纯文本内容,可以使用 分析器 控制索引期间的标记化。
对于多模式或图像内容,可以使用图像语言化实现 LLM 生成的图像描述,或者在索引期间通过技能集进行经典 OCR 和图像分析。
控制子查询数
LLM 根据以下因素确定子查询的数量:
- 用户查询
- 聊天历史记录
- 语义排名器输入约束
作为开发人员,控制子查询数的最佳方式是在知识代理中设置 maxSubQueries 属性。
语义排名器处理多达 50 个文档作为输入,系统创建子查询以容纳语义排名器的所有输入。 例如,如果只需要两个子查询,则可以设置为 maxSubQueries 100 以容纳两批中的所有文档。
索引中的语义配置确定了输入是否为 50。 如果值较少,则查询计划指定满足较小输入大小所需的子查询数。
控制聊天历史记录中的对话主题数
Azure AI 搜索中的知识代理对象通过对 Azure Evaluations SDK 的 API 调用来获取聊天历史记录,该 SDK 维护线程历史记录。 可以筛选此列表以获取消息的子集,例如,最后五个会话轮次。
控制成本和限制运作
查看 活动数组 中的输出令牌,了解查询计划。
改进性能的建议
清理资源
在自己的订阅中操作时,最好在项目结束时移除不再需要的资源。 持续运行资源可能会产生费用。 可以逐个删除资源,也可以删除资源组以删除整个资源集。
还可以删除单个对象: