首页 / 文章 / Azure上的生产级RAG:分块、混合搜索、过滤条件与引用功能

Azure上的生产级RAG:分块、混合搜索、过滤条件与引用功能

企业级检索需要结构感知的文本块、混合搜索、ACL过滤器、重排序功能、基于事实的提示词以及评估机制,而非PDF演示文稿。

1350 词

RAG演示看起来很简单:PDF → 分块 → 嵌入向量 → 向量数据库 → 提问模型。但当有五千份文档涌入,且有人询问国际差旅报销规则时,难点就出现了——如何可靠地将正确的证据输入模型。

1. 从数据入手,而非直接使用大语言模型

在选择聊天模型之前,先梳理数据来源、访问控制、数据更新频率以及格式。劣质的语料库会导致模型给出错误的回答。

2. 分块处理:不要盲目按固定字符数分割

应采用考虑结构的分块方式(如标题、页面、表格),并且各分块之间要有重叠。费用表和政策条款这类内容根本无法通过简单的字符窗口处理。

3>生成嵌入向量

固定使用一种嵌入向量生成方式;为每个索引记录对应的维度信息和模型编号。混用不同模型会悄悄降低模型的检索效果。

document = {
   "document_id": "HR-2026-001",
   "title": "Employee Benefits Policy",
   "department": "HR",
   "country": "India",
   "version": "2026.1",
   "effective_date": "2026-01-01",
   "source": "HR Portal"
}
def chunk_text(text, size=1000):
   return [
     text[i:i + size]
     for i in range(0, len(text), size)
]
def chunk_by_sections(document):
  chunks = []
  for section in document.sections:
    chunks.append({
      "title": section.title,
      "content": section.text,
      "document_id": document.id
    })
  return chunks
pip install openai azure-identity
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
  DefaultAzureCredential(),
  "https://ai.azure.com/.default"
)

client = OpenAI(
  base_url="https://YOUR-RESOURCE.openai.azure.com/openai/v1/",
  api_key=token_provider
)

response = client.embeddings.create(
  model="text-embedding-3-small",
  input="Employees are eligible after completing 12 months of service."
)
vector = response.data[0].embedding
{
  "id": "HR-2026-001-004",
  "document_id": "HR-2026-001",
  "title": "Employee Benefits Policy",
  "content": "...",
  "country": "India",
  "version": "2026.1",
  "content_vector": embedding
}
from azure.search.documents import SearchClient
from azure.search.documents.models import VectorizedQuery

query = "Can I work remotely from another country?"

query_vector = client.embeddings.create(
  model="text-embedding-3-small",
  input=query
).data[0].embedding

vector_query = VectorizedQuery(
  vector=query_vector,
  k_nearest_neighbors=10,
  fields="content_vector"
)

results = search_client.search(
  search_text=query,
  vector_queries=[vector_query],
  top=5,
  select=["title", "content", "document_id", "country"]
)
results = search_client.search(
  search_text=query,
  vector_queries=[vector_query],
  filter="country eq 'India'",
  top=5
)
context = "\n\n".join(
  f"Source: {r['title']}\n{r['content']}"
  for r in results
)
prompt = f"""
You are an enterprise policy assistant.
Answer the user's question using only the provided evidence.
If the evidence does not contain the answer, say that you don't have enough information.
Do not invent policies.
Evidence: {context}
Question: {query}
"""
{
  "document_id": "HR-2026-001",
  "page": 14,
  "section": "Eligibility",
  "content": "..."
}
def answer_question(question):

  # 1. Embed the question
  vector = embed(question)

  # 2. Hybrid retrieval
  candidates = search(
    query=question,
    vector=vector,
    top=20
  )

  # 3. Apply metadata/business filters
  candidates = apply_filters(candidates)

  # 4. Rerank
  ranked = rerank(question, candidates)

  # 5. Keep only useful evidence
  evidence = ranked[:5]

  # 6. Build grounded prompt
  prompt = build_prompt(
    question,
    evidence
  )

  # 7. Generate answer
  response = generate(prompt)

  # 8. Return answer + citations
  return {
    "answer": response,
    "sources": extract_sources(evidence)
  }
test_cases = [
  {
    "question": "What is the India travel allowance?",
    "expected_source": "travel-policy-india.pdf"
  },
  {
    "question": "How long is parental leave?",
    "expected_source": "leave-policy-2026.pdf"
  }
]

4. 在 Azure AI Search 中存储嵌入向量

保存文本、向量以及可筛选的元数据(文档ID、产品信息、区域设置、ACL组、更新时间)。

5> 对大多数企业而言,混合搜索优于纯向量搜索

将密集相似度算法与BM25/关键词检索结合使用,以处理ID、代码及罕见的专有名词。

6. 在浪费上下文之前先进行过滤

在查询阶段就应用安全与租户相关过滤器,而非等到模型已处理过被禁止的内容后再过滤。

7> 检索结果并非最终上下文

需要对检索结果进行重新排序、去重,并控制token使用量。更多的内容片段并不代表更好的答案。

8> 根据证据构建提示词

说明应要求答案仅来自所提供的段落,并在缺乏证据时明确指出。

9. 以引用为依据

需提供段落编号/页面信息以便用户核实。无引用的流畅回答反而会带来风险。

10. 可投入使用的处理流程

数据导入 → 分块 → 嵌入 → 编索引 → 混合检索 → 过滤 → 重新排序 → 提示生成 → 内容生成 → 引用添加 → 评估。

11. 常见问题

分块不当;元数据质量差;仅依赖向量检索;上下文长度过大;没有评估集;没有引用信息;缺少访问控制机制;嵌入模型在后台悄悄更换;缺乏内容更新说明。

总结

实际应用中的RAG是带有LLM端点的信息检索系统,而非相反。应重视分块处理、混合搜索、过滤机制、引用添加及评估环节;聊天模型仅是最后的呈现步骤。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成流程中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成流程中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成流程中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成流程中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成流程中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

为每个领域保存一份标准问题集:包含精确ID查询、改写后的问题以及ACL否定案例。每当分块或嵌入设置发生变化时,就在持续集成环境中自动处理这些任务。

评估功能应与分块配置放在同一个仓库中:当有人“稍作调整”导致重叠时,黄金数据包应在用户察觉之前就出现错误。

混合搜索仍需要针对领域术语的高质量分析工具和同义词列表;仅靠嵌入模型无法弥补拼写错误的策略代码带来的问题。

将ACL字段的规范记录在一页纸上,这样每个新的数据导入任务都会写入与检索过滤器所期望完全一致的字段值。

评估功能应与分块配置放在同一个仓库中:当有人“稍作调整”导致重叠时,黄金数据包应在用户察觉之前就出现错误。