Skip to content

Repository files navigation

AgentCore Harness 全栈 demo(售后智能体)

一个端到端可跑的 AWS Bedrock AgentCore Harness 示例:从浏览器登录到数据落地, 中间的身份透传、工具授权、知识检索、评测护栏都在仓库里,不是片段。

起点是一个真实的大型 Dify 路由型售后智能体(12k 行 DSL / 192 节点):它的意图识别层 用"工具描述即路由"的方式复刻,18 路条件分支随之消失。但真正花掉时间的不是复刻, 而是当智能体代替技师访问业务系统时,权限该怎么办——那是四层授权的由来。

选 Harness 而非 Runtime:不需要自建容器,工具以 inline_function 在客户端执行, 因此身份可以原样透传给数据源与策略引擎。代价见下文实测结论与关键技术点。

串起来的 AgentCore 模块:

模块 承担
Harness 托管 agent 循环、工具路由、多轮上下文(Managed Memory)
Gateway + Cedar 受限工具以 MCP 暴露,按 JWT 岗位声明判权(默认拒绝)
Managed KB 车主手册 / 维修手册 / 质保政策,按知识域隔离检索
Evaluations + Observability 确定性评测 + LLM 裁判 + 代码型合规校验
Cognito / DynamoDB / Lambda / S3 代演车企既有系统与工具执行体

本仓库为技术方案与工程实现。工具名与平台名已匿名化为通用标识;VIN / 车牌 / 车主姓名 / 手机号 / 各类单号均为构造的测试数据。车型名是车企公开产品名(取自其公开文档), 刻意与知识库语料对齐——对不上不会表现为"查不到",而是答出另一车型的政策, 因为该 KB 的检索分数被归一化,问语料未覆盖的车型也返回高分。

内容

文件 说明
agent/tools_def.py 22 个工具定义(description 就是路由规则,改路由=改描述),其中 12 个已接真实后端
agent/system_prompt.py 横切规则:实体识别 / 反问 / 多轮 / 脱敏 / 平台裁剪
agent/invoke.py InvokeHarness 封装:流解析、toolResult 回填、模型/缓存 override
agent/eval_dataset.py 80 条 GSR 导向评测集(可接受工具集合 + 必须实体)
agent/run_eval.py 确定性评测器(PASS/ENTITY/FAIL 三级判定,支持 --model/--cache)
agent/run_mtg_eval.py Mind-the-Goal LLM 裁判接入(AgentCore Evaluations),含 harness span 正文合并 adapter
deploy.sh harness 供给:以 tools_def.py / system_prompt.py 为配置源推送线上配置
agent/kb_def.py 知识库域定义(6 个知识域 → S3 前缀 → 对应工具),含与 tools_def.py 的交叉自检
deploy_kb.sh Managed KB 供给:建 KB + 每域一个 data source,含 upload / sync / query
tools/ 工具实现,按后端依赖分组(一组=一个 Lambda):vehicle-data 7 个、knowledge 5 个
tools/gateway.sh Lambda / Gateway / Cedar 策略供给(受限工具的判权落点)
webui/ 服务端桥(SSE ↔ InvokeHarness,含 toolResult 回填)+ 单文件前端,无构建
simulated-oem/ 车企既有系统的替身:Cognito 账号体系 + 业务库演示数据(生产整体退场)
eval/ 代码型评估器(输出合规硬校验,如回答中出现完整 VIN 即判失败)
teardown.sh 环境拆除:按名字白名单删本项目资源,dry-run 默认、要求键入账号号码

评测报告 agent/eval_*.json 为运行产物,不入库(各人跑出的结果不同,入库只会互相覆盖); 历史实测数字见 EVALUATION-REPORT.md

运行

cp agent/.env.example agent/.env   # 填入你的 harness ARN 等

# 部署(需 aws CLI >= 2.36,旧版无 harness 子命令)
./deploy.sh create <execution-role-arn>   # 新建 harness,输出 ARN
./deploy.sh grant-memory                  # 一次性:给执行角色补 managed memory 权限
./deploy.sh update                        # 改完工具描述/prompt 后推送,生成新版本
./deploy.sh show                          # 线上状态 + 本地/线上工具集漂移检查

# 拆除(切换环境后回收旧环境;默认 dry-run,真删要 --yes 并键入账号号码)
AWS_PROFILE=<profile> ./teardown.sh        # 只列出将删什么
AWS_PROFILE=<profile> ./teardown.sh --yes  # 真删(托管 KB 索引拆除约 18 分钟)

# WebUI(本地起,浏览器看编排与授权)
./webui/run.sh --check                     # 只校验环境变量与登录连通性
./webui/run.sh                             # http://localhost:8088

# 评测
python3 agent/run_eval.py --workers 6                 # 全量评测
python3 agent/run_eval.py --cache                     # 开 prompt caching
python3 agent/run_eval.py --model <model-id> --cache  # 换模型
python3 agent/run_mtg_eval.py --demo                  # LLM 裁判演示

# 知识库(Bedrock Managed KB,全托管 RAG)
./deploy_kb.sh bootstrap-role              # 一次性:建 KB 服务角色
./deploy_kb.sh create                      # bucket + KB + 每域一个 data source
./deploy_kb.sh upload warranty-policy a.pdf b.pdf   # 上传 + 侧车 metadata + 自动 sync
./deploy_kb.sh query warranty-policy "三电质保多久"   # retrieve 冒烟(按域过滤)
./deploy_kb.sh show                        # KB 状态 + 各域文档数 + 漂移检查

须用 python3(boto3 ≥ 1.43):默认 python3 是 3.9,既不支持 str | None 语法,其 boto3 1.42 也缺 harness 与 managed KB 的 shape。deploy_kb.sh 走 aws CLI (≥ 2.36)以绕开这一点。

grant-memory 是必要的一步:harness 会自动配 managed memory,但不会给执行角色对应权限, 不补则首次调用即 ListEvents AccessDenied。它单列而非挂进 create,因为需要 iam:PutRolePolicy 这一高危权限,常规部署不该带着它跑。

实测结论(80 条评测集)

配置 GSR 端到端 p50/p90/p99 成本/千次
Sonnet 无缓存 100% 3.6 / 5.0 / 12.0s ~$20
Sonnet + cache(已设为默认) 100% 3.8 / 5.4 / 11.5s ~$4.6
Haiku 4.5 + cache 92.5% LLM p50 1.4s ~$1.1

关键技术点:

  • harness 无原生 cachePoint 配置,经 model.bedrockModelConfig.additionalParams 覆写 Converse system 数组注入,span 中 cache_read_input_tokens 验证生效
  • inline_function 回填 toolResult 须与 assistant toolUse 消息成对传
  • harness 的 aws/spans 不含消息正文,正文在 runtime 日志组 OTel records, 喂给 Evaluations 前需合并(见 run_mtg_eval.py 的 merge())

授权模型

四层,各管一件事。面向评审的完整说明页是 webui/static/about.html,从登录页可进:

管什么 落在哪
身份 你是谁,不由你自己说 IdP 签名的 cognito:groupsstaffId 不在任何工具 schema 里
工具 这个岗位能否用这个能力 Gateway 上的 Cedar 策略,默认拒绝
数据范围 能看哪些车 门店级隔离,校验放在工具分发处
字段 同一台车能看哪些字段 拆工具:维修上下文与车主隐私读不同的排序键

前端不做任何权限判断:受限工具照常下发给模型、模型照常调用,由服务端拒绝。 前端隐藏按钮式的"权限"是假的,而这正是本项目要证伪的东西。

客户原始 DSL、接口清单等敏感材料不入库(见 .gitignore)。

约定:资源名入库,资源 id 不入库

本仓库外发,且多人各有自己的 AWS 环境,所以:

入库
资源 aftersales-gwaftersales_demoaftersales_policy_engine
资源 id / ARN / 账号 / 池 id / 端点 一律走环境变量或 *.local(见 .gitignore

理由有两条。一是脱敏:id 里含账号号码。二是避免张冠李戴——曾出现一份文档按某个人的 环境断言"harness 已重建、实验资源已清理",而另一人的线上完全是另一回事,据此做清理会误删在用资源。

所以描述线上状态时只写资源名 + 用途, 具体 id 各自记在本地不入库的文件里。每个供给脚本都提供 show 子命令, 现状以脚本读回的为准,而非文档里的记载。

同一条理由决定了 teardown.sh名字白名单删而不按 aftersales-* 前缀匹配: 账号认错时,前缀匹配会删掉别人的同类资源。

About

End-to-end demo on Amazon Bedrock AgentCore Harness: web chat, identity passthrough, four-layer authorization with Cedar, managed KB retrieval, and an evaluation harness.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages