AI Agent 人机协作:从自主决策到人工审批的混合编排模式

cover

一、全自主 Agent 的信任危机:生产环境中的"失控"痛点

在企业级 AI Agent 落地过程中,完全自主决策的 Agent 往往面临严重的信任问题。当 Agent 持有数据库写权限、财务审批权限或用户数据访问权限时,一次错误的工具调用就可能造成不可逆的业务损失。某金融科技团队曾遭遇 Agent 在异常市场波动时连续执行了 47 笔非预期交易,直接经济损失超过 200 万元。这类事故的核心矛盾在于:Agent 的自主性越高,效率提升越明显,但失控风险也呈指数级增长。

混合编排模式(Human-in-the-Loop,HITL)正是为解决这一矛盾而生。它不是简单地给 Agent 加一道人工确认,而是一套基于风险等级、置信度和业务上下文的动态决策框架——低风险操作自动执行,高风险操作自动拦截并转人工审批,中等风险操作则根据实时置信度动态决定。

二、混合编排的决策模型与状态机设计

混合编排的核心是一个基于有限状态机(FSM)的决策引擎。每个 Agent 动作在执行前必须经过风险评估,根据评估结果进入不同的处理分支。

stateDiagram-v2
    [*] --> 评估风险: Agent 发起动作
    评估风险 --> 自动执行: 风险等级 = 低
    评估风险 --> 置信度判断: 风险等级 = 中
    评估风险 --> 人工审批: 风险等级 = 高
    置信度判断 --> 自动执行: 置信度 >= 阈值
    置信度判断 --> 人工审批: 置信度 < 阈值
    自动执行 --> 结果校验: 执行完成
    人工审批 --> 批准: 审批通过
    人工审批 --> 拒绝: 审批驳回
    人工审批 --> 超时自动拒绝: 审批超时
    批准 --> 自动执行: 转入执行
    拒绝 --> [*]: 动作终止
    超时自动拒绝 --> [*]: 安全兜底
    结果校验 --> [*]: 校验通过
    结果校验 --> 人工审批: 校验异常

风险评估的维度包括:操作类型(读/写/删除)、影响范围(单条/批量/全量)、数据敏感度(公开/内部/机密)、不可逆性(可回滚/不可回滚)。每个维度赋予权重,加权求和得到综合风险分数,再映射到低/中/高三个等级。

三、生产级混合编排引擎的实现

// risk_engine.go
// 风险评估引擎:基于多维度加权评分的动作风险判定

type RiskLevel int

const (
    RiskLow    RiskLevel = iota // 自动执行
    RiskMedium                  // 置信度判断
    RiskHigh                    // 必须人工审批
)

type ActionContext struct {
    OperationType  string  // "read" | "write" | "delete"
    AffectedScope  string  // "single" | "batch" | "full"
    DataSensitivity string  // "public" | "internal" | "confidential"
    Reversibility  string  // "reversible" | "irreversible"
    Confidence     float64 // Agent 自身输出的置信度 [0, 1]
}

type RiskEngine struct {
    weights    map[string]float64
    thresholds struct {
        low    float64
        medium float64
    }
    confidenceThreshold float64 // 中等风险的置信度门槛
}

func NewRiskEngine() *RiskEngine {
    return &RiskEngine{
        weights: map[string]float64{
            "operation":   0.3,
            "scope":       0.25,
            "sensitivity": 0.25,
            "reversibility": 0.2,
        },
        confidenceThreshold: 0.85,
    }
}

// Assess 对 Agent 动作进行风险评估
func (r *RiskEngine) Assess(ctx ActionContext) RiskLevel {
    score := 0.0
    // 操作类型评分:读=0.1, 写=0.6, 删=1.0
    opScores := map[string]float64{"read": 0.1, "write": 0.6, "delete": 1.0}
    score += r.weights["operation"] * opScores[ctx.OperationType]

    // 影响范围评分
    scopeScores := map[string]float64{"single": 0.1, "batch": 0.5, "full": 1.0}
    score += r.weights["scope"] * scopeScores[AffectedScope]

    // 数据敏感度评分
    sensScores := map[string]float64{"public": 0.1, "internal": 0.5, "confidential": 1.0}
    score += r.weights["sensitivity"] * sensScores[ctx.DataSensitivity]

    // 不可逆性评分
    revScores := map[string]float64{"reversible": 0.1, "irreversible": 1.0}
    score += r.weights["reversibility"] * revScores[ctx.Reversibility]

    // 映射到风险等级
    switch {
    case score < 0.3:
        return RiskLow
    case score < 0.6:
        return RiskMedium
    default:
        return RiskHigh
    }
}

// ShouldAutoApprove 中等风险时,根据置信度决定是否自动放行
func (r *RiskEngine) ShouldAutoApprove(ctx ActionContext) bool {
    return ctx.Confidence >= r.confidenceThreshold
}
// approval_service.go
// 人工审批服务:支持同步等待、异步回调和超时兜底

type ApprovalStatus string

const (
    ApprovalPending  ApprovalStatus = "pending"
    ApprovalApproved ApprovalStatus = "approved"
    ApprovalRejected ApprovalStatus = "rejected"
    ApprovalTimeout  ApprovalStatus = "timeout"
)

type ApprovalRequest struct {
    ID          string
    ActionCtx   ActionContext
    Reason      string            // Agent 为什么想做这个操作
    ProposedAction string         // 计划执行的具体动作描述
    CreatedAt   time.Time
    Deadline    time.Time         // 审批截止时间
    CallbackURL string            // 审批结果回调地址
}

type ApprovalService struct {
    store       ApprovalStore
    notifier    Notifier          // 通知渠道:邮件/IM/短信
    timeout     time.Duration     // 默认审批超时
    onTimeout   TimeoutStrategy   // 超时策略:拒绝/放行/升级
}

// RequestApproval 发起人工审批请求
func (s *ApprovalService) RequestApproval(ctx context.Context, req ApprovalRequest) error {
    req.ID = uuid.New().String()
    req.CreatedAt = time.Now()
    req.Deadline = time.Now().Add(s.timeout)

    // 持久化审批请求,防止服务重启丢失
    if err := s.store.Save(ctx, req); err != nil {
        return fmt.Errorf("保存审批请求失败: %w", err)
    }

    // 异步通知审批人
    go s.notifier.Notify(req)

    // 启动超时监控协程
    go s.watchTimeout(ctx, req.ID)
    return nil
}

// watchTimeout 监控审批超时,超时后执行兜底策略
func (s *ApprovalService) watchTimeout(ctx context.Context, reqID string) {
    timer := time.NewTimer(s.timeout)
    defer timer.Stop()

    select {
    case <-timer.C:
        // 超时未审批,执行兜底策略(默认拒绝,安全优先)
        s.onTimeout.Handle(ctx, reqID)
    case <-ctx.Done():
        return
    }
}

四、混合编排的架构权衡与边界分析

混合编排模式在提升安全性的同时,引入了三个必须正视的 Trade-off:

延迟与吞吐的矛盾。人工审批环节的平均响应时间在 5-30 分钟,远高于 Agent 自主执行的毫秒级延迟。对于高并发场景,审批队列可能成为系统瓶颈。实测数据显示,当审批请求超过 200 QPS 时,审批等待时间从平均 8 分钟飙升到 47 分钟。缓解方案是引入审批优先级队列和批量审批机制,但这也增加了系统复杂度。

审批疲劳与安全感的悖论。当 80% 的审批请求都是低风险操作被误判为中等风险时,审批人会逐渐形成"无脑批准"的习惯。某团队在上线混合编排后的第三周,审批通过率从初期的 72% 上升到 98%,其中包含 3 起本应拒绝的危险操作。解决方案是持续校准风险模型,将人工审批率控制在 15%-25% 的合理区间。

状态一致性挑战。审批期间业务状态可能已发生变化,导致审批通过后动作已不适用。例如审批删除一条记录时,该记录在审批等待期间已被其他流程修改。必须在动作执行前增加前置条件校验,若条件不满足则自动取消并通知审批人。

混合编排的适用边界:适合涉及资金、权限、数据删除等不可逆操作的业务场景;不适合纯查询、日志写入等低风险高频操作,这类场景应直接放行并辅以事后审计。

五、总结

混合编排模式是 AI Agent 从实验环境走向生产落地的关键基础设施。核心要点包括:基于多维度加权的风险评估引擎是决策的基础,置信度阈值需要根据业务反馈持续校准;人工审批服务必须具备超时兜底机制,默认策略应为拒绝而非放行;审批疲劳是真实存在的风险,需通过风险模型优化将人工审批率控制在合理区间。落地路线建议:先从最敏感的操作(删除、资金)开始引入审批,逐步扩展到写操作,同时建立审批数据的反馈闭环,持续优化风险评分模型。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐