电商场景 Agent 设计:从商品推荐到售后客服的完整链路

一、用户说"这件衣服有我尺码吗",Agent 该如何理解?

电商场景的 AI Agent 和通用 Agent 有本质区别:电商的每一次对话都可能涉及交易,信息的准确性直接影响下单决策和售后体验。

一个典型的用户问题:"这件黑色卫衣有 XXL 吗?红色的同款还有吗?" Agent 需要理解:用户问的是两个维度的库存(黑色/XXL、红色/通用),并且这两个查询和同一件商品关联。

更复杂的是售后场景:"我上周买的那个蓝牙耳机有杂音,能换吗?" Agent 需要先查订单、再查售后政策、最后生成换货工单——这是多轮多工具的联动。

二、电商 Agent 的全链路架构

三、Go 实现电商 Agent 核心逻辑

Agent 入口:意图路由

package ecommerce

import (
    "context"
    "encoding/json"
    "fmt"
    "strings"
)

// EcommerceIntent 电商意图类型
type EcommerceIntent string

const (
    IntentProductSearch  EcommerceIntent = "product_search"   // 商品搜索
    IntentProductCompare EcommerceIntent = "product_compare"  // 商品对比
    IntentOrderQuery     EcommerceIntent = "order_query"      // 订单查询
    IntentRefund         EcommerceIntent = "refund"           // 退款/退货
    IntentLogisticsTrack EcommerceIntent = "logistics_track"  // 物流追踪
    IntentCouponQuery    EcommerceIntent = "coupon_query"     // 优惠券查询
    IntentEscalate       EcommerceIntent = "escalate"         // 升级人工
)

// EcommerceContext 电商对话上下文
type EcommerceContext struct {
    SessionID   string
    UserID      string
    UserProfile *UserProfile       // 用户画像
    OrderHistory []OrderSummary   // 最近订单
    CurrentProduct *Product        // 当前讨论的商品
}

type UserProfile struct {
    UserID     string
    Tags       []string  // 用户标签: 高消费, 母婴, 数码爱好者
    History    []string  // 浏览历史: 商品 ID 列表
    Preferences map[string]string // 偏好: size→XXL, color→黑色
}

type Product struct {
    ID       string
    Name     string
    Price    float64
    Stock    map[string]int // SKU → 库存: "黑色_XXL" → 10
    Category string
    Rating   float64
}

// EcommerceAgent 电商 Agent
type EcommerceAgent struct {
    llm        LLMClient
    tools      *EcommerceToolRegistry  // 电商专用工具集
    router     *IntentRouter
}

// HandleUserQuery 处理用户查询的主入口
func (ea *EcommerceAgent) HandleUserQuery(
    ctx context.Context,
    sessionCtx *EcommerceContext,
    userQuery string,
) (string, error) {
    // 1. 意图识别
    intent, confidence := ea.router.Classify(userQuery)
    
    fmt.Printf("[AGENT] 意图: %s (置信度: %.2f)\n", intent, confidence)
    
    // 2. 根据意图选择处理策略
    switch intent {
    case IntentProductSearch:
        return ea.handleProductSearch(ctx, sessionCtx, userQuery)
    
    case IntentProductCompare:
        return ea.handleProductCompare(ctx, sessionCtx, userQuery)
    
    case IntentOrderQuery:
        return ea.handleOrderQuery(ctx, sessionCtx, userQuery)
    
    case IntentRefund:
        // 退款操作需要用户已登录
        if sessionCtx.UserID == "" {
            return "请先登录后再申请退款", nil
        }
        return ea.handleRefund(ctx, sessionCtx, userQuery)
    
    case IntentLogisticsTrack:
        return ea.handleLogisticsTrack(ctx, sessionCtx, userQuery)
    
    case IntentEscalate:
        // 无缝转接人工
        return ea.transferToHuman(ctx, sessionCtx, userQuery)
    
    default:
        // 降级:让 LLM 自由回答
        return ea.llm.Generate(ctx, userQuery)
    }
}

商品搜索 Agent

// handleProductSearch 商品搜索——多条件筛选 + 库存校验
func (ea *EcommerceAgent) handleProductSearch(
    ctx context.Context,
    session *EcommerceContext,
    query string,
) (string, error) {
    // 第一步:提取搜索条件
    searchParams, err := ea.tools.ExtractSearchParams(ctx, query)
    if err != nil {
        return "抱歉,我没能理解您的搜索条件,能再描述一下吗?", nil
    }

    // 第二步:调用搜索工具
    products, err := ea.tools.SearchProducts(ctx, searchParams)
    if err != nil {
        return "搜索服务暂时不可用,请稍后再试", err
    }

    if len(products) == 0 {
        return fmt.Sprintf("没有找到符合\"%s\"的商品,试试换个关键词?", query), nil
    }

    // 第三步:结合用户画像做个性化排序
    ranked := ea.rankByUserProfile(products, session.UserProfile)

    // 第四步:生成推荐文案——突出库存和用户可能关心的属性
    return ea.formatProductRecommendation(ranked[:min(5, len(ranked))], session), nil
}

// rankByUserProfile 基于用户画像的个性化排序
func (ea *EcommerceAgent) rankByUserProfile(products []Product, profile *UserProfile) []Product {
    if profile == nil {
        return products // 无画像时保持原始排序
    }

    // 评分加权:基础分 + 偏好匹配分
    type scored struct {
        product Product
        score   float64
    }

    var scoredList []scored
    for _, p := range products {
        score := p.Rating * 0.3 // 基础分:好评率

        // 偏好匹配
        for _, tag := range profile.Tags {
            if strings.Contains(p.Category, tag) {
                score += 2.0 // 品类偏好加分
            }
        }

        // 有库存的优先
        totalStock := 0
        for _, s := range p.Stock {
            totalStock += s
        }
        if totalStock > 0 {
            score += 1.0
        }

        scoredList = append(scoredList, scored{p, score})
    }

    // 按分数降序排列
    sortByScore(scoredList)

    result := make([]Product, len(scoredList))
    for i, s := range scoredList {
        result[i] = s.product
    }
    return result
}

// formatProductRecommendation 生成推荐文案
func (ea *EcommerceAgent) formatProductRecommendation(products []Product, session *EcommerceContext) string {
    var sb strings.Builder
    sb.WriteString("为您找到以下商品:\n\n")

    for i, p := range products {
        sb.WriteString(fmt.Sprintf("%d. **%s**\n", i+1, p.Name))
        sb.WriteString(fmt.Sprintf("   价格: ¥%.2f | 评分: %.1f\n", p.Price, p.Rating))
        
        // 展示库存状态
        totalStock := 0
        for sku, stock := range p.Stock {
            totalStock += stock
            if stock <= 3 && stock > 0 {
                sb.WriteString(fmt.Sprintf("   ⚠️ %s 仅剩 %d 件\n", sku, stock))
            }
        }
        if totalStock == 0 {
            sb.WriteString("   [暂时缺货]\n")
        }
        
        sb.WriteString("\n")
    }

    return sb.String()
}

售后处理 Agent

// handleRefund 退款处理——查订单 + 校验政策 + 创建工单
func (ea *EcommerceAgent) handleRefund(
    ctx context.Context,
    session *EcommerceContext,
    query string,
) (string, error) {
    // 第一步:从查询中提取订单信息
    orderInfo, err := ea.tools.ExtractOrderInfo(ctx, query)
    if err != nil {
        return "请提供订单号或告诉我您要退哪件商品", nil
    }

    // 第二步:查询订单详情
    order, err := ea.tools.QueryOrder(ctx, session.UserID, orderInfo.OrderID)
    if err != nil {
        return fmt.Sprintf("未找到订单 %s,请核对订单号", orderInfo.OrderID), err
    }

    // 第三步:检查售后资格
    eligibility := ea.checkRefundEligibility(order)
    if !eligibility.Eligible {
        return fmt.Sprintf(
            "抱歉,%s(原因: %s)",
            eligibility.Message, eligibility.Reason,
        ), nil
    }

    // 第四步:执行退款
    refundResult, err := ea.tools.ProcessRefund(ctx, session.UserID, order.OrderID, orderInfo.Reason)
    if err != nil {
        // 退款失败,升级人工
        ea.transferToHuman(ctx, session, 
            fmt.Sprintf("退款失败: 订单 %s, 原因: %v", order.OrderID, err))
        return "退款处理遇到问题,已为您转接人工客服,请稍候。", nil
    }

    return fmt.Sprintf(
        "已为您处理退款。订单 %s,金额 ¥%.2f,预计 3-5 个工作日内退回原支付方式。",
        order.OrderID, refundResult.Amount,
    ), nil
}

type RefundEligibility struct {
    Eligible bool
    Message  string
    Reason   string
}

func (ea *EcommerceAgent) checkRefundEligibility(order *Order) RefundEligibility {
    // 规则一:订单已完成且未超过 7 天
    daysSinceComplete := time.Since(order.CompletedAt).Hours() / 24
    if daysSinceComplete > 7 {
        return RefundEligibility{
            Eligible: false,
            Message:  "该订单已超过 7 天无理由退货期",
            Reason:   "超期",
        }
    }

    // 规则二:非定制/虚拟商品
    nonRefundCategories := []string{"定制商品", "虚拟商品", "生鲜食品"}
    for _, cat := range nonRefundCategories {
        if strings.Contains(order.Category, cat) {
            return RefundEligibility{
                Eligible: false,
                Message:  fmt.Sprintf("%s 不支持无理由退货", cat),
                Reason:   "品类限制",
            }
        }
    }

    return RefundEligibility{
        Eligible: true,
        Message:  "符合退货条件,正在为您处理",
    }
}

四、边界分析与 Trade-offs

意图识别准确率

  • 电商意图分类比通用场景更难——用户表达方式多样
  • "这个怎么样"可能是问评价、问库存、问价格——需要结合上下文消歧
  • 建议:意图分类的置信度 < 0.7 时,追问澄清而非猜测

库存实时性

  • 商品搜索必须展示实时库存,不能返回已售罄商品
  • 但库存查询本身有成本(数据库+缓存),需要合理设置缓存 TTL
  • 高并发场景使用库存预扣减 + 定期同步

金额相关的安全处理

  • 退款金额必须由服务端计算,不能信任 LLM 的参数
  • 订单查询必须过滤当前用户的订单(不能跨用户查询)
  • 所有写操作(退款、下单)需要有完整的审计日志

人工客服的无缝衔接

  • Agent 转人工时需要传递对话摘要(用户问题、已执行的步骤)
  • 避免用户向人工客服重复描述问题
  • 摘要应包含:订单号、问题类型、自动处理结果

五、总结

电商 Agent 设计的关键是将"不确定的 LLM 生成"和"确定的电商业务规则"分离开:

  1. 售前:LLM 负责理解 + 生成文案,搜索结果和库存由确定性 API 提供
  2. 购买:LLM 不参与金额计算和支付流程,只做引导
  3. 售后:LLM 负责意图分类和参数提取,退款决策由规则引擎决定

电商场景对准确性要求极高。一个错误的退款金额或库存信息,比"回复不够好"的伤害大得多。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐