Taxbit 分享基于 Amazon Bedrock AgentCore 构建合规 AI 助手 Taxbit Assist 的架构与实践
Taxbit Assist: A grounded, role-aware AI agent on Amazon Bedrock AgentCore
Taxbit 在 AWS Machine Learning Blog 复盘了嵌入其税务合规产品仪表盘的 AI 助手 Taxbit Assist,该助手基于 Amazon Bedrock AgentCore 构建,答案全部引用可打开的来源并校验用户角色权限。
Taxbit 是一个数字资产税务与会计合规平台。Taxbit 成立于 2018 年,帮助交易所、支付服务和经纪商等企业规模化地计算损益、收集税务文档并申报信息申报表。如今,一个带引用来源、具备权限感知能力的 AI 智能体,让合规团队能够直接在产品控制台内找到答案。
但要用好这个控制台所需的知识,散落在公开网站、API 文档和帮助中心文章中,而且相当一部分内容从未被记录下来。当客户询问“这个表单状态是什么意思?”时,他们要么自己去翻找,要么提交一个支持工单。根据 Taxbit 的内部生产环境分析数据,如今在 24 小时内向 Assist 提问的用户中,超过 55% 会回来再次提问。
在这篇文章中,我们分享了如何在 Amazon Bedrock AgentCore 上构建 Taxbit Assist——现已嵌入 Taxbit 控制台的 AI 智能体。Amazon Bedrock AgentCore 是一个可以使用任意框架或模型大规模构建、连接和优化智能体的平台。我们将介绍其架构、让答案足够可信以至于可以交付给受监管客户的检索工作、我们如何处理安全性和数据驻留,以及如何在实时生产流量上持续衡量答案质量。
智能体必须做对的事情
通用的聊天机器人无法满足这个领域的要求。四个约束条件塑造了我们的构建方式:
- 有依据且带引用 – 我们的用户要做出申报决策。每个答案都必须能追溯到用户可以打开并阅读的来源,当智能体不知道答案时,它必须如实说明。
- 角色与组织感知 – 智能体不应引导支持用户走只有管理员才能执行的流程,也不应把他们发送到无法打开的页面。
- 不提供税务建议 – 解释 Taxbit 如何计算成本基础(用于计算收益或亏损的会计方法)属于产品文档。告诉用户应该选择哪种方法则是税务建议。两者的界限很窄。
- 区域数据驻留 – 通过单一代码库提供支持,并在生产环境中进行持续的质量衡量。
- 纳入我们的合规体系 – Taxbit Assist 的开发和运营符合 ISO/IEC 42001——AI 管理体系的国际标准。Taxbit 还通过了 ISO/IEC 27001 和 ISO/IEC 27701 认证,并持有 SOC 2 Type II 报告。Taxbit 不训练或微调任何模型,Amazon Bedrock 也不会使用提示词或补全内容来训练模型。
我们也是一个很小的团队。与其自行构建和运维智能体循环、会话状态存储和会话隔离,我们选择 Amazon Bedrock AgentCore 有三个原因:其托管的智能体运行时免除了基础设施运维工作,内置的 AgentCore memory(Amazon Bedrock AgentCore 的一项能力)省去了单独的会话状态存储,而按会话隔离则确保了每个用户的上下文相互独立。这让我们可以把大部分精力投入到下文将要介绍的检索和安全工作上。
解决方案概览
Taxbit Assist 是一个运行在 AgentCore runtime(Amazon Bedrock AgentCore 的一项能力)上的 Strands Agents SDK 应用。下图展示了该解决方案的架构。
图 1:从控制台提问开始,经过护栏筛选、知识库检索、模型推理、权限检查和响应流式传输的请求流程
该工作流包含以下步骤:
- 用户在 Taxbit 控制面板中提出一个问题。流式聊天 API 将该问题连同用户的已验证身份(电子邮件、组织 ID 和控制面板角色)一起转发给 AgentCore 运行时。
- 运行时使用 Amazon Bedrock Guardrails 对传入的消息进行筛查。个人身份信息(PII)会被就地遮蔽。如果消息被拦截,则不会调用模型。
- 智能体从 Amazon Bedrock Knowledge Bases 知识库中检索候选段落,然后在服务器端进行重排序。该知识库使用 Amazon Bedrock 的全托管检索增强生成(RAG)功能,底层由 Amazon S3 Vectors 支持,这是 Amazon Simple Storage Service(Amazon S3)的一项功能。
- Amazon Bedrock 模型对检索到的段落进行推理,并在推荐任何工作流之前验证用户是否有权访问相关功能和角色。有关各 AWS 区域的模型可用性,请参阅 Supported models by AWS Region。
- 答案以流式方式返回到控制面板,并附带来源链接。AgentCore 记忆功能在多轮对话之间保持对话上下文。
- 每个请求都会向 Amazon CloudWatch 发送 OpenTelemetry 跟踪数据,这些数据会输入到我们的评估工具中。
智能体运行时
该智能体是一个小型 Python 应用程序:包含一个系统提示词、一个模型和八个工具。它以 ARM64 容器镜像的形式交付,由 AgentCore 运行时从 Amazon Elastic Container Registry(Amazon ECR)拉取并按需扩展。
这些工具特意设计得非常聚焦:
- 知识库搜索,这是首要工具。
- 两项访问检查:一项用于组织权限验证,另一项用于用户的仪表板角色。
- 四个支持工单工具,用于创建、列出、更新和关闭呼叫者自己的工单。
- 当前时间,用于极少数需要亚天级精度的问题。
在这个版本中,智能体对客户税务数据没有读取权限。它仅从产品知识作答,且唯一能执行的写入操作是呼叫者自己的支持工单。
一个安全决策支撑了所有这一切:模型从不处理身份。用户的邮箱、组织 ID 和角色来自可信的调用服务,并在模型看到之前通过闭包绑定到每个工具中。模型可以决定是否检查权限,但无法决定检查谁的权限,因为身份不是它可以设置的参数。用户输入在边界处进行清理,因此提示词注入无法冒充可信的上下文行。
该智能体通过 Amazon Bedrock 运行基础模型(FM),并通过跨区域推理配置文件进行调用。
具备地域感知能力的推理负责处理数据驻留。推理配置文件 ID 带有由部署区域派生的地域前缀,因此欧盟部署的推理保持在欧盟境内,美国部署则保留在美国境内。除了让推理保持在正确的地域之外,我们还支持自带密钥(BYOK)模式。在 BYOK 账户中,对话历史和其他存储客户数据的存储都使用客户自己的 AWS Key Management Service (AWS KMS) 密钥进行加密。
应用程序推理配置文件用于处理成本可见性。每个部署都将系统推理配置文件包装在带标签的应用程序配置文件中,因此每次模型调用都带有成本分摊标签,并会显示在 AWS Cost Explorer 中,按工作负载进行细分。
Amazon Bedrock 提示词缓存降低了延迟和 token 成本。系统提示词对每个请求都是字节级一致的,并以缓存检查点结尾,因此静态前缀可以跨用户缓存。每个请求的上下文则随用户消息传递。
将回答建立在精选的知识库之上
我们的工程精力大部分投入到知识库上:一个由 Amazon S3 Vectors 支持的 Amazon Bedrock 知识库,使用 Cohere Embed English v3 生成嵌入向量,产生 1,024 维 float32 向量并通过余弦距离进行比较。全部都是托管服务,因此我们无需运维任何向量数据库。
数据摄取
内容来自三类来源,各自落入同一个 Amazon S3 存储桶中属于自己的前缀下。
下图展示了内容如何到达索引。
图 2:内容摄取流水线,来自已发布内容、代码衍生内容和精选内容,经 Lambda 爬虫进入 Amazon S3 和知识库
首先是已发布的内容:我们的公开网站、API 文档和帮助中心文章,由定时的 AWS Lambda 函数爬取。借助站点地图的 lastmod 时间戳和内容哈希,一次典型运行只会处理自上一次以来发生变化的内容。范围界定比我们预想的更重要。我们的站点地图大约有 400 多个 URL,但只有约 70 多个适合放入回答生成的语料库,而 /blogs/ 一个目录就占了 300 多个营销页面。如果不加排除,这些营销内容会与帮助中心竞争,成为合规问题回答中被引用的来源。将其排除是我们最有价值的检索优化之一,而且完全不需要对模型做任何改动。
第二个来源不太常规:Lambda 函数读取我们的产品源代码,生成涵盖仪表盘路由、权限控制、表单资格逻辑和报表配置的 Markdown 文档。这捕捉到了在其他任何文字材料中都不存在的产品事实,并且由于它是从代码本身重新生成的,因此始终保持最新。第三个来源是精选内容:手工撰写的文章和经批准的修正,用于填补自动化来源未覆盖的空白。
Amazon EventBridge 按错开的每夜和每周节奏调度爬取,每个爬虫只在内容有变化时才触发摄取作业。我们将九个爬虫分组为三个总体数据源,按 S3 子前缀划分(product-public/、product-internals/、curated/),从而将相关内容保存在一起。
上下文分块
我们选择了语义分块,它在自然边界处切分文档,并在我们的检索测试中优于固定大小分块。但从文档中间取出的块会丢失对文档主题的把握。在税务报告场景中,这一上下文往往就是整个答案:一段仅适用于非美国申报制度的文字,如果被返回用于回答关于 IRS Form 1099(用于报告付款的信息申报表)的问题,就会产生严重的误导。
为解决此问题,我们利用知识库的自定义转换钩子运行一个 POST_CHUNKING Lambda 函数,为每个块前面加上其文档的 H1 标题和导语段落,导语通常会说明内容的适用范围。前缀限制在约 128 个 token(标题 80 字符,适用范围 300 字符)。由于 Cohere Embed English v3 每个输入最多接受 512 个 token,块正文被限制在 384 个,以便头部和正文一起容纳在该窗口内。一次生产环境探测发现,约 28% 的块位于 385–512 区间,其尾部会被静默截断。
这是我们做出的影响最大的检索改动:块现在将自身的适用范围带入向量索引,而不是只存在于文档的第一个块中。
两点实用提示:第一,Amazon Bedrock 要求转换的中间存储与数据源存储桶分开,必须是不同的存储桶。同一存储桶上使用不同前缀会被拒绝。第二,对现有数据源启用自定义转换会强制进行替换,因此要规划完整的重新摄取,而不是原地修改。
检索
在查询时,流水线会先超量获取,然后进行修剪:
question ─► vector search (75 candidates)
─► Cohere Rerank 3.5, server-side in the same Retrieve call
─► top 12 reranked
─► cap of 2 chunks per source document
─► top 5 passed to the model重排序器在 Amazon Bedrock 内部作为同一个 Retrieve 调用的一部分运行,因此没有额外的服务跳转。我们保留 75 个候选的较宽池,因为权威文章通常位于向量排名第 20–50 位,只有在进入候选池后才能重排到前列。每篇文档的上限防止一个分块繁多的页面占满所有名额。
引用资格在代码中按来源类型强制执行,而不是通过提示指令。只有三个已发布的来源可被引用,因为只有它们的 URL 能解析为客户可以打开的内容。代码衍生和策划的内容为回答提供依据,但不会生成客户无法访问的链接。
安全与数据处理
三个边界确保一个租户的数据不会进入另一个租户的会话:
- 知识库不含任何租户特定的内容:只有已发布的文档、代码衍生的产品参考和策划的文章。
- 权限和角色检查工具从已经对调用者进行身份验证的服务中获取调用者的组织和电子邮件,因此模型无法扩大该范围。
- AgentCore 运行时隔离每个会话,对话历史按内存、会话和参与者 ID 进行分区。该参与者 ID 必须来自调用服务而不是 AWS 调用者身份,因为运行时在单一服务角色下执行。推断的身份会把所有用户的历史放入同一个分区。
Amazon Bedrock Guardrails 可根据应用程序要求提供可配置的防护措施,在智能体运行前筛查每条传入消息。我们将其作为独立的 ApplyGuardrail 调用应用,范围限于当前用户轮次,从而避免在每一轮都重新扫描整个对话历史。
PII 策略针对税务数据进行了调优。那些根本不该流经语言模型的机密信息,例如密码、银行卡验证码和云访问密钥,会被直接拦截。格式狭窄的数字标识符,包括社会安全号码(SSN)、个人纳税人识别号(ITIN)、银行账号与路由号码以及国际银行账号(IBAN),会被就地匿名化。这让智能体可以在帮助完成工作流程的同时,从始至终看不到具体数值。外部集成的凭证存放在 AWS Secrets Manager 中并在运行时获取,绝不会内置到镜像或配置中。
在生产流量上衡量质量
收益最大的习惯做法,是在生产环境中持续衡量质量,同时绝不阻塞响应。下图展示了追踪数据如何扇出到四个独立的消费者,以及专家的修正如何回流到检索中。
图 3:评估流程,其中 CloudWatch 追踪数据扇出到在线评估、质量评判器、税务建议分类器和人工审核,经批准的修正回流到知识库
AgentCore 在线评估从 CloudWatch 追踪数据中抽取 10% 的实时会话,并使用六个内置的 LLM-as-a-judge 评估器进行打分:有用性、有害性、连贯性、指令遵循、工具选择准确性和工具参数准确性。结果以指标和逐会话得分的形式写入 CloudWatch,因此质量回退会体现在仪表板上,而不是客户投诉中。
我们在其上叠加了自己的评判器,通过 CloudWatch 订阅过滤器读取相同的追踪数据流。一个 Lambda 函数对每条抽样答案在检索来源的忠实度和检索文章的相关性两方面进行评分,并将结果作为 CloudWatch 指标输出。我们将忠实度与相关性分开衡量,因为答案可能忠实于本不该被检索到的来源。发生这种情况时,问题出在检索管线,而不是模型。
一个基础模型分类器会检查每条响应是否存在税务建议漂移。产品文档与税务建议之间的界限对主题过滤器来说太过细微:“在自己钱包之间转账不属于应税事件”是建议,而解释 Taxbit 如何应用 FIFO(先进先出) 则是产品文档。一个用指令和示例进行提示的模型可以达到近乎零的误报率,相比之下主题过滤器的误报率约为 25%。这两个分类器都不增加延迟。
由人来完成闭环。抽样的答案(其中问题和答案的个人细节均已清除)会发送到内部审核频道,领域专家可以在其中回复修正意见。经批准的修正会写入知识库的精选前缀,并触发增量摄取任务,因此专家的修正可在几分钟内到达下一位用户的答案,而无需部署。
部署与运维
整个技术栈由 AWS Cloud Development Kit (AWS CDK) 定义,因此搭建一个新环境,或搭建一个具有不同数据驻留要求的新区域,只需更改配置即可。每个拉取请求都会运行一个离线评估套件:一组黄金场景,按预期的工具路径和行为进行评判,因此提示词和检索的变更在发布前就能得到衡量。该套件还会每晚针对生产环境运行。合并后先部署到预发布环境,再通过人工审批门禁部署到生产环境。
成果与影响
Taxbit Assist 自 2026 年 5 月起已在美国和欧盟投入生产,欧盟流量由本地地理区域内的推理服务提供。回答基于精心整理的知识库,并注明来源,而且智能体在推荐工作流之前会先检查功能可用性和用户权限。对于嵌入式支持界面而言,重复使用率是团队最关注的指标。
有一个早期案例非常突出。一家新客户在与 Taxbit 集成以收集税务文档(W-8 和 W-9 表格,即美国国税局的税务预扣与身份识别表格)的过程中,在开发阶段大量依赖这个智能体。过去会落到我们团队共享频道或支持工单中的集成问题,都能当场得到解答。该客户的集成工作无需等待 Taxbit 的支持团队就能持续推进,而支持团队完全没有看到这些流量。
每个会话的平均模型成本低于 20 美分。提示词缓存功不可没:大约四分之三的输入令牌由缓存提供,这使模型成本降低了一半以上。
我们的改进之处
- 在调整提示词之前先界定语料库范围。在我们将索引缩小到支持和文档内容,并为每个文本块赋予其所属文档的范围之后,回答质量的提升超过了以往任何一次提示词修改的效果。
- 用自己的流量来衡量护栏过滤器的强度。我们针对自己的流量测试了 Amazon Bedrock Guardrails 的 PII 检测器,并将 PIN 码和银行路由号检测器设为仅检测模式,这样像 1099 这样的数字表单标识符可以正常通过,同时检测器仍能标记真正敏感的值。
- 保持系统提示词字节级稳定,以便提示词缓存能跨用户生效。
- 从第一个原型开始就在代码中绑定身份。我们早期的测试版本是由模型将身份作为参数传递给工具。我们在上线前将其改为由调用服务传递,这样注入的提示词就无法扩大自身的访问权限。
下一步
目前,该智能体基于产品知识进行回答。下一步是让智能体能够通过相同的身份绑定、权限校验的工具模式,查询客户自己的报表数据,来回答诸如“我的收款方中有多少缺少税务文档?”之类的问题。用户提出问题,模型决定使用哪个工具和过滤器,但经过身份验证的调用方决定该工具可以读取谁的数据,因此模型无法更改这一点。
结语
Amazon Bedrock AgentCore 让一个小团队得以向两个地理区域的受监管企业客户交付一个有引用来源、具备权限感知能力的智能体,而无需自行运维编排、向量搜索、内容安全或评估方面的基础设施。这让我们可以把时间花在最关键的地方:语料库、检索管道,以及在税务信息申报中什么才算是一个好答案。
欲了解更多信息,请参阅 Amazon Bedrock AgentCore、Amazon Bedrock Knowledge Bases、Amazon Bedrock Guardrails 以及 GitHub 上的 Strands Agents SDK。
如果你有问题,或想分享你解决类似问题的方法,请留言评论。
关于作者
来源: AWS Machine Learning Blog · aws.amazon.com


