用 Bedrock 知识库把监管问询从数天压缩到数小时——Amazon FinTech 的做法

2026-05-13 16 预计阅读时间:1 分钟
来源:aws.amazon.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:13 分钟

监管问询(regulatory inquiry)是金融团队最头疼的事之一:审计机构或监管部门抛出一连串问题,团队需要在海量文档里翻找依据、组织措辞、逐条回复。传统流程靠人工检索和邮件流转,一条问询可能耗时数天甚至数周。Amazon FinTech 团队用 Amazon Bedrock + Knowledge Base 把这个过程做成了可扩展的 AI 应用,每个业务团队维护自己的专属知识库,问询响应速度大幅提升。

为什么监管问询适合用 RAG 解决

监管问询有几个天然特征,让它和检索增强生成(RAG)高度契合:

  • 答案必须可溯源——回复不能凭空捏造,每条结论都要指向内部文档的原文段落。
  • 文档量大且分散——政策手册、合规指引、内部流程文档分布在多个系统里,人工翻找效率极低。
  • 团队边界清晰——不同业务线面对不同监管机构,文档集合互不重叠,天然需要隔离的知识库。

Amazon 的方案正是围绕这三点设计的:每个团队拥有独立 Knowledge Base,RAG 只在自己的文档池里检索,生成结果附带来源引用,避免跨团队数据泄漏。

架构拆解

整体方案的核心组件:

  1. Amazon Bedrock Knowledge Base——每个团队创建独立 KB,上传自己的合规文档(PDF、Word、HTML 等),Bedrock 自动做分块、向量化、索引。
  2. S3 作为文档存储层——原始文档放在团队专属 S3 bucket,KB 定期同步更新。
  3. Bedrock Foundation Model——选用 Claude 等大模型做生成,输入是检索到的文档片段 + 问询问题,输出是结构化回复 + 来源标注。
  4. Orchestration 层——用 Step Functions 或 Lambda 编排检索→生成→审核→提交的完整流程。

关键设计决策:不共享知识库。每个团队独立维护 KB,既满足了数据隔离要求,也让文档更新节奏由团队自己掌控,不需要全局协调。

从零搭建一个监管问询 RAG 系统

下面用一个最小可运行示例,演示如何在 AWS 上创建团队专属 Knowledge Base 并接入 Bedrock 模型。假设你已有 AWS 账号且在 us-east-1 区域启用了 Bedrock 和 Claude 模型访问。

第一步:准备文档并上传到 S3

# 创建团队专属 S3 bucket
aws s3 mb s3://regulatory-kb-team-alpha --region us-east-1

# 上传合规文档
aws s3 cp ./compliance-docs/ s3://regulatory-kb-team-alpha/docs/ \
  --recursive --include "*.pdf" --include "*.docx"

# 确认文件已上传
aws s3 ls s3://regulatory-kb-team-alpha/docs/ --recursive

第二步:创建 Knowledge Base(Python + boto3)

前提:已安装 boto3 且 AWS CLI 凭证已配置。Bedrock Knowledge Base API 在 boto3 >= 1.34 中可用。

import boto3
import time
import uuid

bedrock_agent = boto3.client("bedrock-agent", region_name="us-east-1")

KB_NAME = "regulatory-kb-team-alpha"
S3_URI = "s3://regulatory-kb-team-alpha/docs/"
# 使用 Bedrock 自带的 Titan Embedding 模型
EMBED_MODEL_ID = "amazon.titan-embed-text-v1"

# 1. 创建 Knowledge Base
create_resp = bedrock_agent.create_knowledge_base(
    name=KB_NAME,
    description="Team Alpha 专属监管合规文档知识库",
    roleArn="arn:aws:iam::<YOUR_ACCOUNT_ID>:role/BedrockKBRole",  # 需预创建,赋予 S3 读取权限
    knowledgeBaseConfiguration={
        "type": "VECTOR",
        "vectorKnowledgeBaseConfiguration": {
            "embeddingModelArn": f"arn:aws:bedrock:us-east-1::foundation-model/{EMBED_MODEL_ID}"
        }
    },
    storageConfiguration={
        "type": "OPENSEARCH_SERVERLESS",  # Bedrock 自动管理向量索引
        "opensearchServerlessConfiguration": {
            "collectionArn": "<COLLECTION_ARN>",  # 可通过 aoss client 创建,或让 Bedrock 自动创建
            "fieldMapping": {
                "vectorField": "vector",
                "textField": "text",
                "metadataField": "metadata"
            }
        }
    }
)

kb_id = create_resp["knowledgeBase"]["knowledgeBaseId"]
print(f"Knowledge Base ID: {kb_id}")

# 2. 添加 S3 数据源
ds_resp = bedrock_agent.create_data_source(
    knowledgeBaseId=kb_id,
    name="team-alpha-s3-docs",
    description="合规文档 S3 数据源",
    dataSourceConfiguration={
        "type": "S3",
        "s3Configuration": {
            "bucketArn": "arn:aws:s3:::regulatory-kb-team-alpha",
            "prefix": "docs/"
        }
    },
    vectorIngestionConfiguration={
        "chunkingConfiguration": {
            "chunkingStrategy": "FIXED_SIZE",
            "fixedSizeChunkingConfiguration": {
                "maxTokens": 500,       # 每块最大 token 数
                "overlapPercentage": 20  # 块间重叠,避免关键信息被截断
            }
        }
    }
)

ds_id = ds_resp["dataSource"]["dataSourceId"]
print(f"Data Source ID: {ds_id}")

# 3. 触发同步(将 S3 文档向量化并写入索引)
sync_resp = bedrock_agent.start_ingestion_job(
    knowledgeBaseId=kb_id,
    dataSourceId=ds_id
)
job_id = sync_resp["ingestionJob"]["ingestionJobId"]

# 等待同步完成
while True:
    status = bedrock_agent.get_ingestion_job(
        knowledgeBaseId=kb_id,
        dataSourceId=ds_id,
        ingestionJobId=job_id
    )["ingestionJob"]["status"]
    print(f"同步状态: {status}")
    if status in ("COMPLETE", "FAILED"):
        break
    time.sleep(10)

print(f"知识库同步完成,状态: {status}")

第三步:检索 + 生成回复

bedrock_runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
bedrock_agent_runtime = boto3.client("bedrock-agent-runtime", region_name="us-east-1")

MODEL_ID = "anthropic.claude-3-sonnet-20240229"

def answer_regulatory_query(question: str, kb_id: str) -> dict:
    """检索知识库并生成监管问询回复"""

    # 1. 从 Knowledge Base 检索相关文档片段
    retrieve_resp = bedrock_agent_runtime.retrieve(
        knowledgeBaseId=kb_id,
        retrievalQuery={"text": question},
        maxResults=5  # 返回最相关的 5 个片段
    )

    # 2. 组装检索结果为上下文
    context_parts = []
    citations = []
    for result in retrieve_resp["retrievalResults"]:
        text = result["content"]["text"]
        source = result["location"]["s3Location"]["uri"]
        context_parts.append(text)
        citations.append({"text": text, "source": source})

    context = "\n\n---\n\n".join(context_parts)

    # 3. 构造 prompt,要求模型引用来源
    prompt = f"""你是一名合规分析师,正在回复监管机构的问询。
请基于以下内部文档内容回答问题。如果文档中没有相关信息,明确说明"现有文档未覆盖此问题"。
每条结论必须标注来源文档路径。

内部文档内容:
{context}

监管问询问题:
{question}

请给出结构化回复,包含:
1. 直接回答
2. 依据的文档段落(引用原文)
3. 来源文档路径
"""

    # 4. 调用 Bedrock 模型生成回复
    body = {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 2048,
        "messages": [{"role": "user", "content": prompt}]
    }

    model_resp = bedrock_runtime.invoke_model(
        modelId=MODEL_ID,
        body=json.dumps(body),
        contentType="application/json",
        accept="application/json"
    )

    response_body = json.loads(model_resp["body"].read())
    answer = response_body["content"][0]["text"]

    return {"answer": answer, "citations": citations}

# 使用示例
result = answer_regulatory_query(
    question="我们在欧洲市场的反洗钱(AML)审查流程是什么?",
    kb_id=kb_id
)

print("=== 回复 ===")
print(result["answer"])
print("\n=== 检索来源 ===")
for c in result["citations"]:
    print(f"  文档: {c['source']}")
    print(f"  片段: {c['text'][:100]}...")

运行前需要修改的地方: - <YOUR_ACCOUNT_ID> 替换为你的 AWS 账号 ID。 - BedrockKBRole 需要提前创建 IAM Role,赋予 Bedrock 调用权限和 S3 读取权限。 - OpenSearch Serverless Collection 可以通过 aoss client 预创建,或参考 Bedrock 文档让服务自动管理。 - 确保在 Bedrock 控制台已申请 Claude 和 Titan Embedding 的模型访问权限。

分块策略和来源标注的细节

这个方案里有两个容易被忽视但直接影响回复质量的环节:

分块参数选择——上面示例用了 maxTokens=500, overlapPercentage=20。监管文档通常段落较长,500 token 的块大小能保留完整段落语义,20% 重叠确保跨块的关键句子不会丢失上下文。如果你的文档以短条款为主(比如条文式法规),可以把 maxTokens 降到 300,重叠提到 10%。

来源标注的可靠性——retrieve API 返回的每个结果都携带 location 信息(S3 URI + 文档内偏移)。在 prompt 中明确要求模型"标注来源文档路径",配合检索结果里的原始 S3 URI,审计人员可以直接追溯到原文。这是监管场景的硬性要求,也是纯聊天模型无法满足的。

多团队隔离的运维考量

Amazon 方案强调每个团队独立维护 KB,这带来几个实际好处和需要注意的点:

  • 好处:文档更新不需要排队等全局索引重建;团队 A 的合规文档不会出现在团队 B 的检索结果里;各团队可以选用不同的分块策略适配自己的文档格式。
  • 注意:S3 bucket 和 IAM policy 要严格隔离。每个团队的 KB Role 只能读自己 bucket 的文档,否则数据泄漏风险会直接破坏合规隔离要求。
  • 成本:每个 KB 背后是一个独立的 OpenSearch Serverless Collection。团队数量多时,向量存储成本会线性增长。对于文档量小的团队,可以考虑合并到共享 Collection 但用 metadata filter 做逻辑隔离,不过这牺牲了部分隔离强度。

上线前的检查清单

把这套方案从 demo 推向生产,至少要过这几项:

检查项 说明
模型访问权限 Bedrock 控制台确认 Claude 和 Titan Embedding 已启用
IAM 隔离 每个 KB Role 的 S3 读取范围限定到团队 bucket
文档同步频率 监管文档更新后,KB 需及时重新 ingestion;建议配置 S3 Event 触发自动同步
回复审核流程 AI 生成内容必须经过合规人员审核后才能正式提交给监管机构
幻觉兜底 prompt 中明确要求"无依据时声明文档未覆盖",并在前端对这类回复做醒目提示
日志与审计 Bedrock invocation log 和 KB retrieval log 需持久化,满足监管审计追溯要求

这套方案的核心价值不是"AI 替代人写回复",而是把人工从翻文档的机械劳动中解放出来,让合规人员专注于审核和判断。检索速度从小时级降到秒级,生成初稿从天级降到分钟级,最终审核环节仍然由人把关——这才是监管场景里 AI 的正确站位。


相关推荐