如何用一套标准化框架撑起变更风险评估?agent-mid项目总结
本文提出"agent-mid"项目,这是一个用于变更风险评估的Go单体仓库(多main模式)架构方案。项目旨在解决当前变更风险控制领域面临的四大挑战:单体仓库规范缺失、技能与规则管理割裂、反馈闭环缺失和基础设施重复建设。架构包含8个核心模块:skill-registry(技能管理)、rule-engine(规则评估)、data-base(观测数据存储)、agent(主决策编排)
背景
在变更风险控制领域,随着业务复杂度和系统规模的增长,团队面临一系列典型挑战:
-
单体仓库缺乏统一规范:多个服务共享同一仓库,但各自独立维护数据库连接、配置加载、API契约,导致重复代码和运维复杂度上升。
-
技能与规则管理割裂:风险评估依赖技能(Skill)和规则(Rule)两套体系,但二者各自为政,缺乏统一Catalog和联动机制。
-
反馈闭环缺失:模型决策、规则匹配和最终审核结果之间的差异无法被系统性地捕捉和利用,难以持续优化技能与规则的准确性。
-
基础设施重复建设:每个服务都要重新实现配置解析、数据源初始化(包括Nacos、KMS)、HTTP服务器启动等基础能力,研发效率低下。
为应对上述问题,项目“agent-mid”应运而生——一个用于变更风险评估的Go单体仓库(多main),旨在建立一套可复用的基础框架和一组明确的服务边界。
虽然是尽可能走的标准化路线, 但是接下来的项目是以nacos的配置风控作为目标的实践架构方案
ps: 说下这么设计的前提首先 模型外购,存在网关,网关有健全的安全策略,数据库理论最好推荐postgresql, 但是目前业务现成的是mysql, 只要8.0以上问题不大。
skill之所以放到表里面 首先为了这个闭环先跑起来,方便管理, 如果想独立出去,需要单独一个skill仓库,并且写好配套服务 对skill做好版本管理和发布管理, 然后就是gitlab或者其他业务内部仓库, skill还需要可以外抛 给不同的agent使用
任务
项目需要达成的核心任务包括:
-
定义标准化目录与配置约定:确保所有新服务遵循统一的代码组织方式,支持本地YAML、环境变量、Nacos + KMS动态解析MySQL DSN。
-
实现四个关键已就绪服务:
-
skill-registry:技能目录管理,支持CRUD、版本控制、反馈信号入队。 -
rule-engine:规则存储与expr-lang求值,提供规则热加载和评估API。 -
data-base:风险评估观测数据(Observation)的写入、查询和统计。 -
shared/pkg与internal/dbsource:公共模型、技能契约、数据源解析库。
-
-
规划五个骨架服务:
agent(主决策编排)、approval-adapter(审核回调落库)、feedback-refiner(不一致样本学习)、evaluation(只读指标计算)、security(可选校验与脱敏)。 -
建立主流程闭环:审核触发 → agent拉取技能与规则 → 调用模型 + 规则引擎 → 建议给人 → 审批适配器写最终结果 → 不一致样本触发反馈精炼 → 评估系统只读分析。
-
明确工程习惯:外部HTTP超时、异步写库不阻塞主链路、带trace_id、集成测试按需添加。
落地架构方案
本文档定义了一套用于变更风险评估的Go单体仓库(多main模式)的完整架构规范。仓库内每个子目录是一个可独立部署的服务;所有服务共用shared/pkg中的契约模型,并通过internal/dbsource统一解析MySQL DSN(支持直连或Nacos+KMS动态配置)。
适用范围:所有模块的职责、目录约定、API接口、数据表迁移路径、配置与环境变量、工程习惯。子目录不再单独维护README,本文档为唯一权威说明。
1. 模块总览
| 目录 | 职责 |
|---|---|
skill-registry |
技能目录管理:CRUD、版本控制、反馈信号入队(异步处理) |
rule-engine |
规则存储与确定性评估:基于expr-lang对facts求值,返回匹配规则 |
data-base |
风险评估观测数据(Observation)的写入、查询、统计 |
agent |
主决策编排:接收风险评估请求,拉取技能与规则,调用模型,聚合结果,异步写入观测 |
approval-adapter |
审核回调适配:接收最终审批结果,写入data-base,保证trace_id对齐 |
feedback-refiner |
反馈精炼:从不一致的样本中学习,更新规则/技能或导出分析数据 |
evaluation |
只读评估:基于data-base计算指标(人模一致率、不一致趋势、技能失败率等),支持人工抽检 |
shared/pkg |
公共代码:数据模型(model)、技能契约(skill)、错误码、下游客户端占位 |
security/pkg |
可选安全库:输入校验、日志脱敏(不做登录鉴权,由网关负责, 建议单独网关服务, 不要放在这里面) |
internal/dbsource |
数据源统一解析:直连MySQL DSN 或 Nacos+KMS解析 |
2. 主流程(设计意图)
-
审核触发 →
agent接收POST /v1/risk_assess请求。 -
agent从skill-registry拉取技能catalog,从rule-engine预加载或调用评估接口,并结合模型网关(MODEL_GATEWAY_URL)的输出。 -
生成风险评估建议返回给前端(人)。
-
人执行最终决策后,审核系统回调
approval-adapter。 -
approval-adapter将最终结果(含trace_id)写入data-base。 -
feedback-refiner定时或事件驱动拉取不一致样本(模型建议 vs 人审结果),判断问题归属(技能问题、规则问题或数据问题),并调用相应服务更新skill-registry或rule-engine,必要时导出分析文件。 -
evaluation模块只读data-base,定期计算指标并提供人工抽检界面,不直接修改规则或技能。
3. 标准目录约定(所有服务强制遵循)
text
<service>/
cmd/<service>/main.go # 唯一入口
internal/
api/ # HTTP Handler、路由注册
config/ # 配置加载(YAML + env)、Validate、提供DBSource()
repository/ # GORM仓储层
server/ # http.Server配置、超时、Recover中间件
config/
local.yaml.example # 配置模板,本地复制为local.yaml(禁止提交密钥)
internal/migrations/sql/ # 仅存放*.sql文件,应用不自动执行,由人工/DBA运行
配置规则:
-
优先使用环境变量
${SERVICE}_CONFIG_FILE指定的配置文件。 -
否则使用
{service}/config/${DEPLOY_ENV}.yaml,DEPLOY_ENV默认为local。 -
非空环境变量可覆盖YAML中的同名字段(如
HTTP_ADDR、DB_DSN等)。
数据库:当前所有服务统一使用MySQL 8。迁移SQL按文件名顺序执行。
鉴权:默认不做鉴权,由API网关或专线层统一处理。
4. 共享基础设施:internal/dbsource
所有需要数据库访问的服务(data-base、rule-engine、skill-registry)必须通过本库解析MySQL DSN。
工作流程:
-
在服务配置中定义
mysql.dsn字段,或设置database.from_nacos: true并提供Nacos/KMS参数。 -
调用
ResolveMySQLDSN(ctx, cfg.DBSource()):-
若
from_nacos=true,则从Nacos拉取配置YAML → 解析spring.datasource格式 → 对ENC(...)加密字段调用KMS或代理解密 → 返回明文DSN。 -
否则直接返回配置中的
mysql.dsn。
-
-
支持全局环境变量(如
INFRA_DB_FROM_NACOS)与服务级前缀变量(如DATA_BASE_DB_FROM_NACOS)并存,服务级优先。
调试:设置INFRA_DB_DEBUG=1可在stderr输出单行提示(不泄露加密配置内容)。
5. data-base 模块
职责:存储风险评估观测数据,提供查询与统计接口。
数据表:
-
infra_observations(迁移:internal/migrations/sql/001_infra_observations.up.sql)
契约模型:使用shared/pkg/model.Observation和shared/pkg/model.StatsSummary。
HTTP API:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /healthz |
健康检查 |
| POST | /v1/observations |
写入一条观测记录 |
| GET | /v1/observations |
分页查询观测记录(支持过滤条件) |
| GET | /v1/stats |
获取统计数据(总数、趋势等) |
配置要点(环境变量或YAML):
-
DATA_BASE_HTTP_ADDR:监听地址,默认:8082 -
DATA_BASE_DB_DSN:直连DSN(若未使用Nacos) -
DATA_BASE_DB_FROM_NACOS:布尔值,是否从Nacos解析 -
DATA_BASE_MAX_PAGE_SIZE:分页最大限制,默认100 -
通用Nacos变量:
NACOS_ADDR、NACOS_NAMESPACE、NACOS_GROUP、SECRET_*、DATA_BASE_NACOS_DATA_ID
启动命令(仓库根目录):
bash
go run ./data-base/cmd/data-base
6. rule-engine 模块
职责:存储规则,对输入facts进行确定性布尔匹配,返回匹配的规则列表(不调用大模型)。
数据表:
-
infra_rules(迁移:internal/migrations/sql/001_infra_rules.up.sql)
契约模型:shared/pkg/model.Rule、EvaluateRequest、EvaluateResponse、MatchedRule。
规则表达式:默认rule_type=expr,使用expr-lang对facts JSON求值。
HTTP API:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /healthz |
健康检查 |
| POST | /v1/rules/evaluate |
对给定facts进行评估,返回匹配规则 |
| GET | /v1/rules |
列出所有规则(可分页) |
| POST | /v1/rules |
创建新规则 |
| GET | /v1/rules/{id} |
获取单个规则 |
| PUT | /v1/rules/{id} |
更新规则 |
| DELETE | /v1/rules/{id} |
删除规则 |
热加载机制:
-
服务启动时从数据库加载所有规则,编译后驻留内存。
-
定时器根据
reload_interval_sec(默认30秒)触发全量重载。 -
写库操作(POST/PUT/DELETE)后异步触发一次重载,确保新规则快速生效。
配置要点:
-
RULE_ENGINE_HTTP_ADDR:监听地址,默认:8083 -
RULE_ENGINE_DB_DSN/RULE_ENGINE_DB_FROM_NACOS -
RULE_ENGINE_RELOAD_INTERVAL_SEC:重载间隔(秒) -
可选的
RULE_ENGINE_SLOW_SQL_THRESHOLD_MS:GORM慢日志阈值
启动命令:
bash
go run ./rule-engine/cmd/rule-engine
7. skill-registry 模块
职责:技能目录管理,支持技能CRUD、版本控制、反馈信号接收(异步处理)。
数据表:
-
infra_skills(技能主表) -
infra_skill_versions(版本历史) -
infra_skill_feedback_signals(反馈信号队列)
迁移脚本:internal/migrations/sql/001_infra_skills.up.sql
契约模型:使用shared/pkg/skill包。
HTTP API:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /healthz |
健康检查 |
| GET | /v1/skills/catalog |
获取技能目录(扁平或树形) |
| POST | /v1/skills/feedback-signals |
提交反馈信号(仅入队,异步处理) |
| GET | /v1/skills |
列技能 |
| POST | /v1/skills |
创建技能 |
| GET | /v1/skills/{id} |
获取技能详情 |
| PUT | /v1/skills/{id} |
更新技能 |
| DELETE | /v1/skills/{id} |
删除技能 |
| GET | /v1/skills/{id}/versions |
获取版本列表 |
| POST | /v1/skills/{id}/versions |
创建新版本 |
技能类型:
-
builtin:内置技能,需指定builtin_key,实际逻辑在agent中实现。 -
http:外部HTTP技能,需提供http_url,由agent或skill-registry调用。
配置要点:
-
SKILL_REGISTRY_HTTP_ADDR:默认:8084 -
SKILL_REGISTRY_DB_DSN/SKILL_REGISTRY_DB_FROM_NACOS -
SKILL_REGISTRY_FEEDBACK_ASYNC:是否异步处理反馈(默认true)
启动命令:
bash
go run ./skill-registry/cmd/skill-registry
8. shared/pkg 使用原则
-
禁止复制:任何两个服务不得各自定义同一结构的请求/响应JSON。所有共享模型必须放入
shared/pkg/model或shared/pkg/skill。 -
版本管理:修改公共字段时,通过包版本或字段标记(如
json:"xxx,omitempty")保持向后兼容。重大变更需提供golden JSON对拍测试。 -
客户端占位:
shared/pkg/client目前仅包含下游HTTP客户端的接口定义和占位实现。实际使用时必须补充超时、重试、错误分类逻辑。
9. 骨架模块详细设计
以下模块虽未提供完整HTTP实现,但已明确API契约和集成要点。
9.1 agent
入口:POST /v1/risk_assess
输入:风险评估上下文(变更描述、系统状态、用户属性等)
处理流程:
-
调用
skill-registry获取当前可用的技能列表(catalog),筛选适用于本次评估的技能。 -
对每个技能:
-
若为
builtin,根据builtin_key执行内部逻辑。 -
若为
http,调用配置的http_url获得技能输出。
-
-
从
rule-engine获取规则评估结果(调用POST /v1/rules/evaluate,传入facts)。 -
聚合模型网关(
MODEL_GATEWAY_URL,大模型服务)的输出、技能输出、规则匹配结果,生成最终建议。 -
异步调用
data-base的POST /v1/observations写入本次评估的原始输入、中间输出和建议结果(失败时记录日志但不阻塞响应)。 -
返回建议给前端。
环境变量:
-
MODEL_GATEWAY_URL:大模型服务地址 -
SKILL_REGISTRY_URL:技能注册服务地址(默认http://localhost:8084) -
DATA_BASE_URL:观测服务地址(默认http://localhost:8082) -
RULE_ENGINE_URL:规则引擎地址(默认http://localhost:8083) -
AGENT_HTTP_ADDR:服务监听地址,默认:8081 -
AGENT_ASYNC_WRITE_TIMEOUT:异步写observation的超时时间,默认2秒
9.2 approval-adapter
入口:POST /v1/feedback(由审核系统回调)
处理流程:
-
解析回调请求,提取
trace_id(与agent生成的trace_id对齐)、最终审批结果(通过/拒绝/人工修改的备注)。 -
构造
Observation更新请求(或补全字段),调用data-base的POST /v1/observations写入最终结果。 -
支持幂等:如果同
trace_id已存在最终结果,则忽略或更新(根据业务需求)。 -
设置合理的HTTP超时(默认5秒),超时或失败时记录告警,但不重试(避免重复写)。
配置:
-
APPROVAL_ADAPTER_HTTP_ADDR:默认:8085 -
DATA_BASE_URL:同上
9.3 feedback-refiner
职责:定期从不一致的样本中学习,自动或半自动优化规则和技能。
工作模式:
-
从
data-base拉取一段时间内模型建议与人工审批结果不一致的记录。 -
对每条不一致样本,分析原因:
-
若技能输出明显错误 → 记录为技能问题,调用
skill-registry的POST /v1/skills/feedback-signals入队反馈。 -
若规则匹配错误(误报/漏报) → 调用
rule-engine的规则更新API(需人工审核后启用)或导出建议规则修改。
-
-
支持
SKILL_FEEDBACK_DRY_RUN=true模式,仅打印日志不实际调用更新接口。
配置:
-
FEEDBACK_REFINER_HTTP_ADDR:默认:8086 -
DATA_BASE_URL、RULE_ENGINE_URL、SKILL_REGISTRY_URL -
FEEDBACK_REFINER_INTERVAL_SEC:拉取不一致样本的间隔,默认300秒 -
FEEDBACK_REFINER_INCONSISTENCY_WINDOW:时间窗口,默认24h
启动:可作为独立服务或定时Job运行。
9.4 evaluation
职责:只读data-base,计算评估指标,提供人工抽检界面或API。
指标示例:
-
人模一致率(模型建议与最终审批一致的比例)
-
不一致趋势(按时间、技能、规则维度)
-
技能调用失败率
-
规则命中覆盖率
API设计(建议):
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /v1/metrics/human-ai-agreement |
人模一致率 |
| GET | /v1/metrics/trend |
趋势数据(时序) |
| GET | /v1/sampling/daily |
每日抽检样本(随机或按策略) |
| POST | /v1/golden/upload |
上传golden集用于对拍测试 |
配置:
-
EVALUATION_HTTP_ADDR:默认:8087 -
DATA_BASE_URL(只读连接,可使用只读库)
9.5 security
使用方式:按需引用security/pkg/validate(输入校验)和security/pkg/sanitize(日志脱敏)。不提供登录鉴权。
10. 工程习惯(保持简单)
-
超时控制:所有对外部服务的HTTP调用必须设置超时(如
http.Client{Timeout: 5 * time.Second})。 -
异步非阻塞:
agent写入observation必须异步,失败时仅记录错误和告警,不得阻塞主响应。 -
链路追踪:全链路传递
trace_id(通过HTTP头X-Trace-Id),日志中打印该ID以便排错。 -
集成测试:仅在必要时添加集成测试与golden JSON对拍;优先保证单元测试覆盖核心逻辑。
-
启动方式:所有服务统一在仓库根目录执行
go run ./<service>/cmd/<service>。
11. 环境变量速查表(通用)
| 变量名 | 用途 | 示例 |
|---|---|---|
DEPLOY_ENV |
部署环境(local/dev/prod) | prod |
*_HTTP_ADDR |
服务监听地址 | :8082 |
*_DB_DSN |
直连MySQL DSN | user:pass@tcp(host:3306)/db |
*_DB_FROM_NACOS |
是否从Nacos解析DSN | true |
NACOS_ADDR |
Nacos服务器地址 | nacos.example.com:8848 |
NACOS_NAMESPACE |
Nacos命名空间 | risk |
NACOS_GROUP |
Nacos分组 | DEFAULT_GROUP |
SECRET_KEY |
KMS或代理解密密钥ID | alias/risk-db |
INFRA_DB_DEBUG |
调试Nacos解析过程 | 1 |
每个服务的具体前缀见相应模块配置要点。
附录:快速参考表
| 模块 | 默认端口 | 核心数据表 | 关键API |
|---|---|---|---|
| agent | 8081 | 无(无状态) | POST /v1/risk_assess |
| data-base | 8082 | infra_observations | POST/GET /v1/observations |
| rule-engine | 8083 | infra_rules | POST /v1/rules/evaluate |
| skill-registry | 8084 | infra_skills等 | GET /v1/skills/catalog |
| approval-adapter | 8085 | 无(写data-base) | POST /v1/feedback |
| feedback-refiner | 8086 | 无(读data-base写规则/技能) | 定时任务或API触发 |
| evaluation | 8087 | 只读data-base | GET /v1/metrics/* |
agent内部实际上只要做好模型调用和失败后的降级处理, 好处是设计好周边配套工具, 一方面可以用清晰的结构,形成feedback 闭环 也就是OODA循环 (Observe–Orient–Decide–Act)(观察-定向-决策-行动)
当然标准化的方案不是唯一的 如果后面迭代无论是评估方案, 还是这套闭环系统的设计都还是存在优化空间的。
更多推荐


所有评论(0)