Buy 领域智能体 · Spring AI 全量工程与 Staff 面试
定位 :全球运动零售 Buy Team / Commerce 在存量 Spring Boot 上落地的 14 个智能化场景 ------每个场景含 POC 架构图 、可联调级 Spring AI 代码骨架 、2 道 Staff 面试满分答 、Guardrails 红线 。
前置 :08 §10--11 场景总览 · 14 §12 LiteLLM/MCP/多 VectorStore · 17 §4--5 Guardrails
冲刺 :98 §5.13--5.14 C.98--C.122
0. 共享平台骨架(14 场景复用)
0.1 依赖与模型路由(LiteLLM 主路径)
xml
<!-- pom.xml 片段 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-pgvector</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-redis</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
</dependency>
yaml
# application-ai.yml
spring:
ai:
openai:
api-key: ${LITELLM_API_KEY}
base-url: ${LITELLM_PROXY_URL:http://litellm.internal:4000/v1}
chat:
options:
model: commerce-smart # LiteLLM 别名 → azure-gpt-4o / qwen 等
temperature: 0.2
embedding:
options:
model: text-embedding-3-small
commerce:
ai:
max-tool-iterations: 5
scene-header: X-Commerce-AI-Scene # CARTS_ADD | STYLIST | CS | PRICING | ...
0.2 Advisor 链(生产默认顺序)
java
@Configuration
public class CommerceAdvisorConfig {
@Bean
ChatClient commerceChatClient(ChatClient.Builder builder,
List<Advisor> commerceAdvisors) {
return builder
.defaultAdvisors(commerceAdvisors.toArray(Advisor[]::new))
.defaultSystem("""
你是运动零售 Buy/Commerce 助手。
规则:①金额/库存/定价/券面额/支付渠道仅引用 Tool JSON;
②禁止承诺赔偿、中签、自动改价;③不确定时建议转人工。
""")
.build();
}
@Bean
List<Advisor> commerceAdvisors(
SafeGuardAdvisor safeGuard,
SimpleLoggerAdvisor logger,
QuestionAnswerAdvisor faqRag, // L1 Redis FAQ
MessageChatMemoryAdvisor memory) { // Redis session
return List.of(safeGuard, logger, faqRag, memory);
}
}
0.3 场景路由 Controller 模式
java
@RestController
@RequestMapping("/api/v1/commerce-ai")
@RequiredArgsConstructor
public class CommerceAiGatewayController {
private final Map<String, CommerceAiSceneHandler> handlers;
@PostMapping("/{scene}")
public Object invoke(@PathVariable String scene,
@RequestHeader("X-User-Id") String userId,
@RequestBody CommerceAiRequest req) {
return handlers.get(scene).handle(userId, req);
}
}
public interface CommerceAiSceneHandler {
String scene();
Object handle(String userId, CommerceAiRequest req);
}
#mermaid-svg-gcLAFO1WTIkYNn1G{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gcLAFO1WTIkYNn1G .error-icon{fill:#552222;}#mermaid-svg-gcLAFO1WTIkYNn1G .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gcLAFO1WTIkYNn1G .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gcLAFO1WTIkYNn1G .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gcLAFO1WTIkYNn1G .marker.cross{stroke:#333333;}#mermaid-svg-gcLAFO1WTIkYNn1G svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gcLAFO1WTIkYNn1G p{margin:0;}#mermaid-svg-gcLAFO1WTIkYNn1G .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster-label text{fill:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster-label span{color:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster-label span p{background-color:transparent;}#mermaid-svg-gcLAFO1WTIkYNn1G .label text,#mermaid-svg-gcLAFO1WTIkYNn1G span{fill:#333;color:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G .node rect,#mermaid-svg-gcLAFO1WTIkYNn1G .node circle,#mermaid-svg-gcLAFO1WTIkYNn1G .node ellipse,#mermaid-svg-gcLAFO1WTIkYNn1G .node polygon,#mermaid-svg-gcLAFO1WTIkYNn1G .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gcLAFO1WTIkYNn1G .rough-node .label text,#mermaid-svg-gcLAFO1WTIkYNn1G .node .label text,#mermaid-svg-gcLAFO1WTIkYNn1G .image-shape .label,#mermaid-svg-gcLAFO1WTIkYNn1G .icon-shape .label{text-anchor:middle;}#mermaid-svg-gcLAFO1WTIkYNn1G .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gcLAFO1WTIkYNn1G .rough-node .label,#mermaid-svg-gcLAFO1WTIkYNn1G .node .label,#mermaid-svg-gcLAFO1WTIkYNn1G .image-shape .label,#mermaid-svg-gcLAFO1WTIkYNn1G .icon-shape .label{text-align:center;}#mermaid-svg-gcLAFO1WTIkYNn1G .node.clickable{cursor:pointer;}#mermaid-svg-gcLAFO1WTIkYNn1G .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gcLAFO1WTIkYNn1G .arrowheadPath{fill:#333333;}#mermaid-svg-gcLAFO1WTIkYNn1G .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gcLAFO1WTIkYNn1G .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gcLAFO1WTIkYNn1G .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gcLAFO1WTIkYNn1G .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gcLAFO1WTIkYNn1G .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gcLAFO1WTIkYNn1G .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster text{fill:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G .cluster span{color:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gcLAFO1WTIkYNn1G .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gcLAFO1WTIkYNn1G rect.text{fill:none;stroke-width:0;}#mermaid-svg-gcLAFO1WTIkYNn1G .icon-shape,#mermaid-svg-gcLAFO1WTIkYNn1G .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gcLAFO1WTIkYNn1G .icon-shape p,#mermaid-svg-gcLAFO1WTIkYNn1G .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gcLAFO1WTIkYNn1G .icon-shape .label rect,#mermaid-svg-gcLAFO1WTIkYNn1G .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gcLAFO1WTIkYNn1G .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gcLAFO1WTIkYNn1G .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gcLAFO1WTIkYNn1G :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DomainServices
AI
Handlers
SceneRouter
Gateway
API Gateway
CommerceAiGateway
StylistHandler
CsHandler
PricingHandler
CartsHandler
ChatClient + Advisors
LiteLLM Proxy
Tool Facades
PIM/OMS/Carts/Pricing/Payment
1. 智能导购 Agent(Stylist)
1.1 业务(Buy + C 端)
自然语言选品 → 多轮澄清(场景/尺码/预算)→ 推荐 3 SKU + 对比 → 可选加车。LLM 编排;价格库存只读 Tool。
1.2 POC 架构
CatalogFacade StylistTools ProductRAG ChatClient StylistHandler User CatalogFacade StylistTools ProductRAG ChatClient StylistHandler User #mermaid-svg-lBW8oYVPBADtlCJK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lBW8oYVPBADtlCJK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lBW8oYVPBADtlCJK .error-icon{fill:#552222;}#mermaid-svg-lBW8oYVPBADtlCJK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lBW8oYVPBADtlCJK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lBW8oYVPBADtlCJK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lBW8oYVPBADtlCJK .marker.cross{stroke:#333333;}#mermaid-svg-lBW8oYVPBADtlCJK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lBW8oYVPBADtlCJK p{margin:0;}#mermaid-svg-lBW8oYVPBADtlCJK .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-lBW8oYVPBADtlCJK text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-lBW8oYVPBADtlCJK .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-lBW8oYVPBADtlCJK .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-lBW8oYVPBADtlCJK .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-lBW8oYVPBADtlCJK .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-lBW8oYVPBADtlCJK #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-lBW8oYVPBADtlCJK .sequenceNumber{fill:white;}#mermaid-svg-lBW8oYVPBADtlCJK #sequencenumber{fill:#333;}#mermaid-svg-lBW8oYVPBADtlCJK #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-lBW8oYVPBADtlCJK .messageText{fill:#333;stroke:none;}#mermaid-svg-lBW8oYVPBADtlCJK .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-lBW8oYVPBADtlCJK .labelText,#mermaid-svg-lBW8oYVPBADtlCJK .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-lBW8oYVPBADtlCJK .loopText,#mermaid-svg-lBW8oYVPBADtlCJK .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-lBW8oYVPBADtlCJK .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-lBW8oYVPBADtlCJK .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-lBW8oYVPBADtlCJK .noteText,#mermaid-svg-lBW8oYVPBADtlCJK .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-lBW8oYVPBADtlCJK .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-lBW8oYVPBADtlCJK .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-lBW8oYVPBADtlCJK .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-lBW8oYVPBADtlCJK .actorPopupMenu{position:absolute;}#mermaid-svg-lBW8oYVPBADtlCJK .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-lBW8oYVPBADtlCJK .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-lBW8oYVPBADtlCJK .actor-man circle,#mermaid-svg-lBW8oYVPBADtlCJK line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-lBW8oYVPBADtlCJK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} User request: height, weight, running info prompt + advisors similaritySearch product chunks searchProducts(query, size, maxPrice) search catalog skus with price and stock getMemberTier(userId) StylistRecommendation JSON
1.3 Spring AI 完整示例
java
@Component
public class StylistTools {
private final CatalogFacade catalog;
private final MemberFacade member;
@Tool(description = "按自然语言+尺码+预算搜索跑鞋/服饰 SKU")
public List<SkuCardDto> searchProducts(
String query,
@ToolParam(required = false) String size,
@ToolParam(required = false) BigDecimal maxPriceCny) {
return catalog.search(query, size, maxPriceCny);
}
@Tool(description = "会员等级与可用权益,只读")
public MemberTierDto getMemberTier(String userId) {
return member.getTier(userId);
}
@Tool(description = "对比多款 SKU 关键参数")
public CompareTableDto compareSkus(List<String> skuIds) {
return catalog.compare(skuIds);
}
}
@Service
@RequiredArgsConstructor
public class StylistHandler implements CommerceAiSceneHandler {
private final ChatClient chatClient;
private final StylistTools tools;
@Override public String scene() { return "STYLIST"; }
@Override
public StylistRecommendation handle(String userId, CommerceAiRequest req) {
return chatClient.prompt()
.tools(tools)
.user("userId=" + userId + ";" + req.message())
.call()
.entity(StylistRecommendation.class);
}
}
public record StylistRecommendation(
List<String> recommendedSkuIds,
String comparisonSummary,
List<Citation> citations) {}
public record Citation(String source, String chunkId) {}
java
// StylistRecommendation 校验:sku 必须来自最近一次 searchProducts 返回集
@Component
public class StylistOutputVerifier implements OutputVerifier {
public void verify(ChatResponse response, ToolContext ctx) {
// 正则:禁止 response 中出现未在 tool 日志出现的 price 字面量
}
}
1.4 Staff 面试题
B01 · 导购 Agent 和搜索推荐服务如何分工?
| 段 | 要点 |
|---|---|
| 结论 | ML 召回排序仍走 Search/Rec 服务 ;Spring AI 做 意图澄清 + 解释 + 跨品类对话 ;Tool 调 searchProducts 而非让 LLM 背 SKU 列表。 |
| 原理 | 召回需要 LTR/向量索引规模;LLM 擅长语言不擅长百万 SKU 全排序。 |
| 工程 | QuestionAnswerAdvisor 接 pgvector 商品知识;maxIterations=5;SSE 流式。 |
| 验证 | golden:价/库存 100% 与 Tool 一致;cite rate >0.8。 |
| 风险 | 绕过搜索直出 LLM 编造 SKU → 合规与转化双输。 |
B02 · 首 token 延迟如何压到 800ms 内?
| 段 | 要点 |
|---|---|
| 结论 | LiteLLM 路由 commerce-fast;RAG topK≤5;Tool 并行;Semantic Cache 热点问句。 |
| 原理 | TTFT = 网关 + 检索 + 首包模型;Decode 可流式。 |
| 工程 | Redis L1 FAQ 命中则跳过 Milvus;Resilience4j 超时 3s fallback 模板答。 |
| 验证 | 大促压测 P99 TTFT;按 scene 分池 Bulkhead。 |
| 风险 | 为快关掉 RAG → 幻觉升。 |
1.5 Guardrails
- 价格/库存/促销 仅 Tool
- 竞品诋毁 / 医疗承诺 → SafeGuard 拦截
- 推荐 SKU ⊆ 最近
searchProducts结果集
2. 智能客服 24/7
2.1 POC 架构
#mermaid-svg-5uaIZUYGWHgl2HqV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5uaIZUYGWHgl2HqV .error-icon{fill:#552222;}#mermaid-svg-5uaIZUYGWHgl2HqV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5uaIZUYGWHgl2HqV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5uaIZUYGWHgl2HqV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5uaIZUYGWHgl2HqV .marker.cross{stroke:#333333;}#mermaid-svg-5uaIZUYGWHgl2HqV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5uaIZUYGWHgl2HqV p{margin:0;}#mermaid-svg-5uaIZUYGWHgl2HqV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster-label text{fill:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster-label span{color:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster-label span p{background-color:transparent;}#mermaid-svg-5uaIZUYGWHgl2HqV .label text,#mermaid-svg-5uaIZUYGWHgl2HqV span{fill:#333;color:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV .node rect,#mermaid-svg-5uaIZUYGWHgl2HqV .node circle,#mermaid-svg-5uaIZUYGWHgl2HqV .node ellipse,#mermaid-svg-5uaIZUYGWHgl2HqV .node polygon,#mermaid-svg-5uaIZUYGWHgl2HqV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5uaIZUYGWHgl2HqV .rough-node .label text,#mermaid-svg-5uaIZUYGWHgl2HqV .node .label text,#mermaid-svg-5uaIZUYGWHgl2HqV .image-shape .label,#mermaid-svg-5uaIZUYGWHgl2HqV .icon-shape .label{text-anchor:middle;}#mermaid-svg-5uaIZUYGWHgl2HqV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5uaIZUYGWHgl2HqV .rough-node .label,#mermaid-svg-5uaIZUYGWHgl2HqV .node .label,#mermaid-svg-5uaIZUYGWHgl2HqV .image-shape .label,#mermaid-svg-5uaIZUYGWHgl2HqV .icon-shape .label{text-align:center;}#mermaid-svg-5uaIZUYGWHgl2HqV .node.clickable{cursor:pointer;}#mermaid-svg-5uaIZUYGWHgl2HqV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5uaIZUYGWHgl2HqV .arrowheadPath{fill:#333333;}#mermaid-svg-5uaIZUYGWHgl2HqV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5uaIZUYGWHgl2HqV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5uaIZUYGWHgl2HqV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uaIZUYGWHgl2HqV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5uaIZUYGWHgl2HqV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uaIZUYGWHgl2HqV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster text{fill:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV .cluster span{color:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5uaIZUYGWHgl2HqV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5uaIZUYGWHgl2HqV rect.text{fill:none;stroke-width:0;}#mermaid-svg-5uaIZUYGWHgl2HqV .icon-shape,#mermaid-svg-5uaIZUYGWHgl2HqV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5uaIZUYGWHgl2HqV .icon-shape p,#mermaid-svg-5uaIZUYGWHgl2HqV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5uaIZUYGWHgl2HqV .icon-shape .label rect,#mermaid-svg-5uaIZUYGWHgl2HqV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5uaIZUYGWHgl2HqV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5uaIZUYGWHgl2HqV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5uaIZUYGWHgl2HqV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} FAQ Match
Policy
Order/Logistics
Sensitive
User
Three-level Router
L1 Redis Vector
L2 pgvector
Agent + OMS Tools
Human Agent
Output Verifier
2.2 Spring AI 完整示例
java
@Component
public class CustomerServiceTools {
private final OrderFacade orders;
private final LogisticsFacade logistics;
private final RefundFacade refunds;
@Tool(description = "查询订单状态,只读")
public OrderStatusDto getOrderStatus(String orderId, String userId) {
return orders.getStatus(orderId, userId);
}
@Tool(description = "创建退款申请草稿,写操作需 idempotencyKey,不直接打款")
public RefundDraftDto createRefundDraft(
String orderId, String reason, String idempotencyKey) {
return refunds.createDraft(orderId, reason, idempotencyKey);
}
}
@Service
public class CsHandler implements CommerceAiSceneHandler {
private final ChatClient chatClient;
private final CustomerServiceTools tools;
private final VectorStore faqStore; // Redis
private final VectorStore policyStore; // pgvector
@Override public String scene() { return "CUSTOMER_SERVICE"; }
@Override
public CsResponse handle(String userId, CommerceAiRequest req) {
if (SensitiveKeywordDetector.matches(req.message())) {
return CsResponse.escalate("检测到敏感诉求,已转人工");
}
return chatClient.prompt()
.advisors(
QuestionAnswerAdvisor.builder(faqStore).build(),
QuestionAnswerAdvisor.builder(policyStore).searchRequestTransformer(
r -> r.withFilterExpression("tenant == 'global'")).build())
.tools(tools)
.user("userId=" + userId + ";" + req.message())
.call()
.entity(CsResponse.class);
}
}
2.3 Staff 面试题
B03 · 客服三级路由如何设计?
| 段 | 要点 |
|---|---|
| 结论 | L1 FAQ Redis <2ms → L2 政策 pgvector → L3 Agent+Tool 查单 → 关键词转人工 ;误承诺 Verifier 零容忍。 |
| 原理 | 80/15/5 流量分布;越往后成本越高。 |
| 工程 | createRefundDraft 非 executeRefund;赔偿类关键词 bypass LLM。 |
| 验证 | 红队「赔双倍」必须 escalate;自助率 >70%。 |
| 风险 | Agent 直连退款 API → 资损(对齐 14 §13 STAR)。 |
B04 · 多 VectorStore 如何按意图路由?
| 段 | 要点 |
|---|---|
| 结论 | 意图分类器(轻量模型/规则)选 Advisor;或串联 Advisor 按置信短路。 |
| 工程 | @Qualifier 多 Bean;filter `doc_type=faq |
| 验证 | 政策题 citation 必须来自 policy 索引版本号。 |
| 风险 | 单库混放 → 过滤慢且易串库。 |
2.4 Guardrails
- 退款/赔偿 仅 Draft + HITL
- 输出 Verifier 禁「保证/一定赔」
- 审计
trace_id+tool_calls7 年
3. AI 商品分析(PIM enrichment)
3.1 POC + 代码
#mermaid-svg-jYQkGVRkXiXjsIM4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jYQkGVRkXiXjsIM4 .error-icon{fill:#552222;}#mermaid-svg-jYQkGVRkXiXjsIM4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jYQkGVRkXiXjsIM4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .marker.cross{stroke:#333333;}#mermaid-svg-jYQkGVRkXiXjsIM4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jYQkGVRkXiXjsIM4 p{margin:0;}#mermaid-svg-jYQkGVRkXiXjsIM4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster-label text{fill:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster-label span{color:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster-label span p{background-color:transparent;}#mermaid-svg-jYQkGVRkXiXjsIM4 .label text,#mermaid-svg-jYQkGVRkXiXjsIM4 span{fill:#333;color:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .node rect,#mermaid-svg-jYQkGVRkXiXjsIM4 .node circle,#mermaid-svg-jYQkGVRkXiXjsIM4 .node ellipse,#mermaid-svg-jYQkGVRkXiXjsIM4 .node polygon,#mermaid-svg-jYQkGVRkXiXjsIM4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .rough-node .label text,#mermaid-svg-jYQkGVRkXiXjsIM4 .node .label text,#mermaid-svg-jYQkGVRkXiXjsIM4 .image-shape .label,#mermaid-svg-jYQkGVRkXiXjsIM4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-jYQkGVRkXiXjsIM4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .rough-node .label,#mermaid-svg-jYQkGVRkXiXjsIM4 .node .label,#mermaid-svg-jYQkGVRkXiXjsIM4 .image-shape .label,#mermaid-svg-jYQkGVRkXiXjsIM4 .icon-shape .label{text-align:center;}#mermaid-svg-jYQkGVRkXiXjsIM4 .node.clickable{cursor:pointer;}#mermaid-svg-jYQkGVRkXiXjsIM4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .arrowheadPath{fill:#333333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jYQkGVRkXiXjsIM4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jYQkGVRkXiXjsIM4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jYQkGVRkXiXjsIM4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster text{fill:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 .cluster span{color:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jYQkGVRkXiXjsIM4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jYQkGVRkXiXjsIM4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-jYQkGVRkXiXjsIM4 .icon-shape,#mermaid-svg-jYQkGVRkXiXjsIM4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jYQkGVRkXiXjsIM4 .icon-shape p,#mermaid-svg-jYQkGVRkXiXjsIM4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jYQkGVRkXiXjsIM4 .icon-shape .label rect,#mermaid-svg-jYQkGVRkXiXjsIM4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jYQkGVRkXiXjsIM4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jYQkGVRkXiXjsIM4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jYQkGVRkXiXjsIM4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} No
Yes
PIM Change Event
Spring Batch
Embedding
ChatClient temp=0
ProductAttributeDto
Confidence >= 0.85?
Review Queue
Write Back to PIM
java
@Service
@RequiredArgsConstructor
public class ProductEnrichmentJob {
private final ChatClient chatClient;
private final PimWriteFacade pim;
@Scheduled(cron = "0 */10 * * * *")
public void enrichBatch() {
pim.listPendingEnrichment(500).forEach(sku -> {
ProductAttributeDto attrs = chatClient.prompt()
.system("只输出 JSON。类目/材质/场景标签。不确定填 unknown。")
.user("title=" + sku.title() + "\ndesc=" + sku.description())
.call()
.entity(ProductAttributeDto.class);
if (attrs.confidence() >= 0.85) {
pim.applyAttributes(sku.id(), attrs);
} else {
pim.enqueueReview(sku.id(), attrs);
}
});
}
}
3.2 Staff 面试题
B05 · 商品分析为什么用批处理而不是在线 Chat?
| 段 | 要点 |
|---|---|
| 结论 | 离线 Batch + temperature=0 控成本与一致性;在线只读已生成「AI 解读」缓存。 |
| 工程 | embedding 版本 pin;低置信 HITL。 |
| 验证 | 属性准确率 >95% 人工抽检。 |
| 风险 | 在线实时抽属性 → 成本与抖动不可控。 |
B06 · 多模态商品分析链路?
| 段 | 要点 |
|---|---|
| 结论 | 图+文 → Vision API / CLIP embedding 入 Milvus;文本走 Batch LLM。 |
| 工程 | 图文一致性阈值 <0.7 进人审。 |
| 验证 | 图文不符客诉 -8% 目标。 |
| 风险 | 仅文本忽略图 → 退货率高。 |
4. 智能搭配 Outfit Builder
4.1 POC + 代码
java
@Component
public class OutfitTools {
@Tool(description = "按锚点SKU与风格标签返回搭配候选")
public List<OutfitSkuDto> getOutfitCandidates(String anchorSkuId, String styleTag) { ... }
@Tool(description = "校验套装内所有 SKU 同仓有货")
public BundleStockDto checkBundleStock(List<String> skuIds, String storeId) { ... }
}
public record OutfitBundle(List<String> skuIds, String styleNarrative, BigDecimal bundlePrice) {}
// bundlePrice 来自 checkBundleStock 返回,非 LLM 计算
4.2 Staff 面试题
B07 · 搭配推荐如何保证有货?
| 段 | 要点 |
|---|---|
| 结论 | 生成后 强制 checkBundleStock;无货剔除并再生成或降级单件推荐。 |
| 验证 | Eval:无货 SKU 不得出现在最终 bundle。 |
| 风险 | 只看风格不看 ATP → 结账失败。 |
B08 · Vision RAG 在搭配中的作用?
| 段 | 要点 |
|---|---|
| 结论 | CLIP/SigLIP 向量检索风格相近 SKU;LLM 写叙事与场合。 |
| 工程 | Milvus 多模态索引 + metadata category=footwear。 |
| 风险 | 纯文本 RAG 忽略配色 → 搭配违和。 |
5. AI 满减 / 优惠券推荐
完整序列图与三 Tool 见 08 §10.5.1。
5.1 Staff 面试题
B09 · 为何 System prompt 禁止输出数字金额? → 见 98 C.100。
B10 · CouponAdviceResponse 如何防话术夹带金额?
| 段 | 要点 |
|---|---|
| 结论 | 正则 \d+\.?\d* 扫 explanation;失败则重试或模板化回复。 |
| 工程 | 前端只展示 Tool JSON 渲染组件。 |
| 风险 | 只拦模型不拦前端拼接 → 仍可能误导。 |
6. 限量发售个性化故事(SNKRS 类)
6.1 POC + 代码
java
@Component
public class DropStoryTools {
@Tool(description = "用户脱敏偏好:品类/收藏,不含PII")
public UserTasteDto getUserTaste(String userId) { ... }
@Tool(description = "发售元数据:系列名/设计师/年份,只读")
public DropMetaDto getDropMeta(String dropId) { ... }
}
@Service
public class DropStoryHandler implements CommerceAiSceneHandler {
public DropStoryResponse handle(String userId, CommerceAiRequest req) {
return chatClient.prompt()
.system("禁止暗示保证购买/内部名额/必中签")
.tools(dropStoryTools)
.user("dropId=" + req.dropId())
.call()
.entity(DropStoryResponse.class);
}
}
PushService ChatClient StoryWorker Kafka Draw Result PushService ChatClient StoryWorker Kafka Draw Result #mermaid-svg-FFq9s9hY6R3mBh7T{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FFq9s9hY6R3mBh7T .error-icon{fill:#552222;}#mermaid-svg-FFq9s9hY6R3mBh7T .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FFq9s9hY6R3mBh7T .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FFq9s9hY6R3mBh7T .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FFq9s9hY6R3mBh7T .marker.cross{stroke:#333333;}#mermaid-svg-FFq9s9hY6R3mBh7T svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FFq9s9hY6R3mBh7T p{margin:0;}#mermaid-svg-FFq9s9hY6R3mBh7T .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-FFq9s9hY6R3mBh7T text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-FFq9s9hY6R3mBh7T .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-FFq9s9hY6R3mBh7T .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-FFq9s9hY6R3mBh7T #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-FFq9s9hY6R3mBh7T .sequenceNumber{fill:white;}#mermaid-svg-FFq9s9hY6R3mBh7T #sequencenumber{fill:#333;}#mermaid-svg-FFq9s9hY6R3mBh7T #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-FFq9s9hY6R3mBh7T .messageText{fill:#333;stroke:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-FFq9s9hY6R3mBh7T .labelText,#mermaid-svg-FFq9s9hY6R3mBh7T .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .loopText,#mermaid-svg-FFq9s9hY6R3mBh7T .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-FFq9s9hY6R3mBh7T .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-FFq9s9hY6R3mBh7T .noteText,#mermaid-svg-FFq9s9hY6R3mBh7T .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-FFq9s9hY6R3mBh7T .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-FFq9s9hY6R3mBh7T .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-FFq9s9hY6R3mBh7T .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-FFq9s9hY6R3mBh7T .actorPopupMenu{position:absolute;}#mermaid-svg-FFq9s9hY6R3mBh7T .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-FFq9s9hY6R3mBh7T .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-FFq9s9hY6R3mBh7T .actor-man circle,#mermaid-svg-FFq9s9hY6R3mBh7T line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-FFq9s9hY6R3mBh7T :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DropResultEvent Generate story/comfort message story text Personalized Push
6.2 Staff 面试题
B11 · LLM 能否参与抽签决策?
| 段 | 要点 |
|---|---|
| 结论 | 绝对不能 ;LLM 只生成 中签后故事 / 未中签安抚 + 相似款推荐。 |
| 验证 | 架构图抽签服务与 Story 服务无写边。 |
| 风险 | 合规模型暗示「提高中签率」→ 监管与品牌危机。 |
B12 · 异步生成的幂等与去重?
| 段 | 要点 |
|---|---|
| 结论 | eventId 幂等;Redis SETNX story:{userId}:{dropId}。 |
| 工程 | 失败进 DLQ 重试最多 3 次。 |
| 风险 | 重复 Push → 用户骚扰。 |
7. AI 选品助手(Buy Team · Assortment)
7.1 POC + 代码
java
@Component
public class AssortmentTools {
@Tool(description = "SKU 近28天销量增速")
public VelocityDto getSalesVelocity(String skuId, String region) { ... }
@Tool(description = "毛利率,只读")
public MarginDto getMargin(String skuId) { ... }
@Tool(description = "竞品价,只读")
public CompetitorPriceDto getCompetitorPrice(String skuId) { ... }
@Tool(description = "创建采购建议草稿,非正式 PO")
public AssortmentDraftDto createAssortmentDraft(
AssortmentDraftRequest req, String idempotencyKey) { ... }
}
#mermaid-svg-ensAkVmdqrHXYuil{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ensAkVmdqrHXYuil .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ensAkVmdqrHXYuil .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ensAkVmdqrHXYuil .error-icon{fill:#552222;}#mermaid-svg-ensAkVmdqrHXYuil .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ensAkVmdqrHXYuil .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ensAkVmdqrHXYuil .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ensAkVmdqrHXYuil .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ensAkVmdqrHXYuil .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ensAkVmdqrHXYuil .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ensAkVmdqrHXYuil .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ensAkVmdqrHXYuil .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ensAkVmdqrHXYuil .marker.cross{stroke:#333333;}#mermaid-svg-ensAkVmdqrHXYuil svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ensAkVmdqrHXYuil p{margin:0;}#mermaid-svg-ensAkVmdqrHXYuil .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ensAkVmdqrHXYuil .cluster-label text{fill:#333;}#mermaid-svg-ensAkVmdqrHXYuil .cluster-label span{color:#333;}#mermaid-svg-ensAkVmdqrHXYuil .cluster-label span p{background-color:transparent;}#mermaid-svg-ensAkVmdqrHXYuil .label text,#mermaid-svg-ensAkVmdqrHXYuil span{fill:#333;color:#333;}#mermaid-svg-ensAkVmdqrHXYuil .node rect,#mermaid-svg-ensAkVmdqrHXYuil .node circle,#mermaid-svg-ensAkVmdqrHXYuil .node ellipse,#mermaid-svg-ensAkVmdqrHXYuil .node polygon,#mermaid-svg-ensAkVmdqrHXYuil .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ensAkVmdqrHXYuil .rough-node .label text,#mermaid-svg-ensAkVmdqrHXYuil .node .label text,#mermaid-svg-ensAkVmdqrHXYuil .image-shape .label,#mermaid-svg-ensAkVmdqrHXYuil .icon-shape .label{text-anchor:middle;}#mermaid-svg-ensAkVmdqrHXYuil .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ensAkVmdqrHXYuil .rough-node .label,#mermaid-svg-ensAkVmdqrHXYuil .node .label,#mermaid-svg-ensAkVmdqrHXYuil .image-shape .label,#mermaid-svg-ensAkVmdqrHXYuil .icon-shape .label{text-align:center;}#mermaid-svg-ensAkVmdqrHXYuil .node.clickable{cursor:pointer;}#mermaid-svg-ensAkVmdqrHXYuil .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ensAkVmdqrHXYuil .arrowheadPath{fill:#333333;}#mermaid-svg-ensAkVmdqrHXYuil .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ensAkVmdqrHXYuil .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ensAkVmdqrHXYuil .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ensAkVmdqrHXYuil .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ensAkVmdqrHXYuil .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ensAkVmdqrHXYuil .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ensAkVmdqrHXYuil .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ensAkVmdqrHXYuil .cluster text{fill:#333;}#mermaid-svg-ensAkVmdqrHXYuil .cluster span{color:#333;}#mermaid-svg-ensAkVmdqrHXYuil div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ensAkVmdqrHXYuil .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ensAkVmdqrHXYuil rect.text{fill:none;stroke-width:0;}#mermaid-svg-ensAkVmdqrHXYuil .icon-shape,#mermaid-svg-ensAkVmdqrHXYuil .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ensAkVmdqrHXYuil .icon-shape p,#mermaid-svg-ensAkVmdqrHXYuil .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ensAkVmdqrHXYuil .icon-shape .label rect,#mermaid-svg-ensAkVmdqrHXYuil .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ensAkVmdqrHXYuil .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ensAkVmdqrHXYuil .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ensAkVmdqrHXYuil :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Merchandiser
Assortment Agent
Trend Report RAG
AssortmentTools
Data Warehouse
Draft Proposal
Buy Committee Approval
7.2 Staff 面试题
B13 · 选品 Agent 为什么是 Plan-Execute 而非 ReAct 无限循环?
| 段 | 要点 |
|---|---|
| 结论 | 买手任务步骤固定:取数→对比→草稿→人审;Plan 限 4--6 步可控。 |
| 工程 | Java 状态机编排子步骤;每步 Tool 超时 10s。 |
| 风险 | 自主下单 → 供应链事故。 |
B14 · 区域 RBAC 如何在 RAG 体现?
| 段 | 要点 |
|---|---|
| 结论 | metadata `region=APAC |
| 验证 | 越权访问测试 100% 403。 |
| 风险 | 全球趋势泄露给单区买手 → 合规。 |
8. 库存调拨(WMS · HITL)
8.1 POC + 代码
java
@Component
public class TransferTools {
@Tool(description = "区域库存快照")
public InventorySnapshotDto getInventorySnapshot(String skuId) { ... }
@Tool(description = "创建调拨草稿,不写库存")
public TransferDraftDto createTransferDraft(
TransferDraftRequest req, String idempotencyKey) { ... }
}
8.2 Staff 面试题
B15 · 为何「工作流优先」而非全自动 Agent 调拨?
| 段 | 要点 |
|---|---|
| 结论 | 写库存副作用大;LLM 解释 + 草稿 ;WMS 审批后执行。 |
| 工程 | createTransferDraft 幂等;LLM 无 deductStock Tool。 |
| 验证 | 渗透测试无直写 API。 |
| 风险 | Agent 自动调拨 → 错仓爆仓。 |
B16 · 调拨建议如何引用运输时效?
| 段 | 要点 |
|---|---|
| 结论 | @Tool getTransitEta(fromDc,toDc) 只读;LLM 比较方案。 |
| 验证 | 建议 ETA 与 TMS 一致。 |
| 风险 | LLM 估算物流天数 → 履约超时。 |
9. 定价 Copilot(HITL mandatory)
9.1 POC + 代码
java
@Component
public class PricingTools {
@Tool public CompetitorSnapshotDto getCompetitorPrices(String skuId) { ... }
@Tool public SalesCurveDto getSalesCurve(String skuId, int days) { ... }
@Tool(description = "提交调价审批单,不修改生效价")
public PriceChangeRequestDto submitPriceChangeRequest(
PriceChangeRequest req, String idempotencyKey) { ... }
}
9.2 Staff 面试题
B17 · 定价 Copilot 审批流如何与 LLM 解耦? → 见 98 C.102。
B18 · 竞品数据延迟如何处理?
| 段 | 要点 |
|---|---|
| 结论 | Tool 返回 dataAsOf;LLM 必须引用时间戳;过期数据触发人工标注。 |
| 验证 | dataAsOf > 24h 时 UI 警告。 |
| 风险 | 静默用过期价 → 错误跟价。 |
10. 评价情感分析(UGC)
10.1 POC + 代码
java
@Service
public class ReviewSentimentPipeline {
private final ChatClient chatClient;
@KafkaListener(topics = "ugc.review.created")
public void onReview(ReviewEvent e) {
ReviewInsight insight = chatClient.prompt()
.system("输出 JSON: sentiment, issues[], severity, suggestedAction")
.user(PiiMasker.mask(e.text()))
.call()
.entity(ReviewInsight.class);
if (insight.severity() >= Severity.HIGH) {
alertPublisher.publish(e.skuId(), insight);
}
}
}
10.2 Staff 面试题
B19 · 为何批处理 + 结构化输出而非在线 Chat?
| 段 | 要点 |
|---|---|
| 结论 | UGC 量大;ReviewInsight POJO 入告警/工单;在线仅展示聚合标签。 |
| 工程 | PII 正则脱敏进 prompt;不自动删评。 |
| 验证 | 负面 24h 触达率 >95%。 |
| 风险 | LLM 自动删评 → 法律风险。 |
B20 · 虚假好评如何与 LLM 分工?
| 段 | 要点 |
|---|---|
| 结论 | XGBoost/规则主判 ;LLM 生成 人审 reasoning。 |
| 验证 | recall >85% 离线集。 |
| 风险 | LLM 单独封禁 → 误杀。 |
11. 营销活动 Multi-Agent
11.1 POC + 代码
java
@Service
public class CampaignOrchestrator {
private final ChatClient copyAgent;
private final ChatClient audienceAgent;
private final ChatClient complianceAgent;
public CampaignPackage plan(CampaignBrief brief) {
var audience = audienceAgent.prompt().user(brief.toAudiencePrompt()).call().entity(AudiencePlan.class);
var copy = copyAgent.prompt().user(brief.toCopyPrompt(audience)).call().entity(CopyDraft.class);
var verdict = complianceAgent.prompt().user(copy.toCompliancePrompt()).call().entity(ComplianceVerdict.class);
if (!verdict.approved()) {
throw new ComplianceRejectedException(verdict.reasons());
}
return new CampaignPackage(audience, copy, verdict);
}
}
#mermaid-svg-3eq5SrZYO8gSlRxo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3eq5SrZYO8gSlRxo .error-icon{fill:#552222;}#mermaid-svg-3eq5SrZYO8gSlRxo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3eq5SrZYO8gSlRxo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3eq5SrZYO8gSlRxo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3eq5SrZYO8gSlRxo .marker.cross{stroke:#333333;}#mermaid-svg-3eq5SrZYO8gSlRxo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3eq5SrZYO8gSlRxo p{margin:0;}#mermaid-svg-3eq5SrZYO8gSlRxo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster-label text{fill:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster-label span{color:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster-label span p{background-color:transparent;}#mermaid-svg-3eq5SrZYO8gSlRxo .label text,#mermaid-svg-3eq5SrZYO8gSlRxo span{fill:#333;color:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo .node rect,#mermaid-svg-3eq5SrZYO8gSlRxo .node circle,#mermaid-svg-3eq5SrZYO8gSlRxo .node ellipse,#mermaid-svg-3eq5SrZYO8gSlRxo .node polygon,#mermaid-svg-3eq5SrZYO8gSlRxo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3eq5SrZYO8gSlRxo .rough-node .label text,#mermaid-svg-3eq5SrZYO8gSlRxo .node .label text,#mermaid-svg-3eq5SrZYO8gSlRxo .image-shape .label,#mermaid-svg-3eq5SrZYO8gSlRxo .icon-shape .label{text-anchor:middle;}#mermaid-svg-3eq5SrZYO8gSlRxo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3eq5SrZYO8gSlRxo .rough-node .label,#mermaid-svg-3eq5SrZYO8gSlRxo .node .label,#mermaid-svg-3eq5SrZYO8gSlRxo .image-shape .label,#mermaid-svg-3eq5SrZYO8gSlRxo .icon-shape .label{text-align:center;}#mermaid-svg-3eq5SrZYO8gSlRxo .node.clickable{cursor:pointer;}#mermaid-svg-3eq5SrZYO8gSlRxo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3eq5SrZYO8gSlRxo .arrowheadPath{fill:#333333;}#mermaid-svg-3eq5SrZYO8gSlRxo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3eq5SrZYO8gSlRxo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3eq5SrZYO8gSlRxo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3eq5SrZYO8gSlRxo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3eq5SrZYO8gSlRxo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3eq5SrZYO8gSlRxo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster text{fill:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo .cluster span{color:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3eq5SrZYO8gSlRxo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3eq5SrZYO8gSlRxo rect.text{fill:none;stroke-width:0;}#mermaid-svg-3eq5SrZYO8gSlRxo .icon-shape,#mermaid-svg-3eq5SrZYO8gSlRxo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3eq5SrZYO8gSlRxo .icon-shape p,#mermaid-svg-3eq5SrZYO8gSlRxo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3eq5SrZYO8gSlRxo .icon-shape .label rect,#mermaid-svg-3eq5SrZYO8gSlRxo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3eq5SrZYO8gSlRxo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3eq5SrZYO8gSlRxo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3eq5SrZYO8gSlRxo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Rejected
Approved
Campaign Brief
Orchestrator
Audience Agent
Copy Agent
Compliance Agent
Terminate
MA Delivery
11.2 Staff 面试题
B21 · 合规 Agent 一票否决如何工程保证?
| 段 | 要点 |
|---|---|
| 结论 | ComplianceVerdict.approved==false 时 不调用 MA 写接口;编排器硬编码。 |
| 验证 | 红队敏感词 100% 拦截。 |
| 风险 | 仅 prompt 约束无代码分支 → 漏发。 |
B22 · Token 预算熔断?
| 段 | 要点 |
|---|---|
| 结论 | LiteLLM daily-usd-cap + 应用侧 campaignId 计数器。 |
| 工程 | 超 85% 告警,100% 拒绝新任务。 |
| 风险 | 无限生成文案 → FinOps 爆炸。 |
12. 反欺诈 / 黄牛(SNKRS)
12.1 POC + 代码
java
@Component
public class AntiFraudTools {
@Tool(description = "规则+模型风险分,只读")
public RiskScoreDto getRiskScore(String orderId) { ... }
@Tool(description = "生成人审说明,不执行拦截")
public String explainRisk(RiskScoreDto score) { ... }
}
@Service
public class FraudReviewService {
public FraudReviewNote review(String orderId) {
var score = antiFraudTools.getRiskScore(orderId);
if (score.decision() == Decision.BLOCK) {
return FraudReviewNote.blocked(
chatClient.prompt()
.user("根据分数生成人审理由: " + score)
.call()
.content());
}
return FraudReviewNote.pass();
}
}
12.2 Staff 面试题
B23 · LLM 在风控链路中的正确位置?
| 段 | 要点 |
|---|---|
| 结论 | 毫秒级规则+ML 决策 ;LLM 仅解释 复杂案;不单独拒单。 |
| 验证 | 压测主路径无 LLM 调用。 |
| 风险 | LLM 拒单 → 延迟与不可解释。 |
B24 · 误杀申诉如何闭环?
| 段 | 要点 |
|---|---|
| 结论 | 申诉 → 人工 → 反馈入特征库;LLM 不参与改判自动生效。 |
| 指标 | 误杀率 <0.5%。 |
| 风险 | 无申诉 → 品牌舆情。 |
13. Carts 智能加车
完整代码见 08 §10.13。
13.1 Staff 面试题
B25 · 三 Tool 分步必要性? → 98 C.104。
B26 · Member/门店上下文如何注入?
| 段 | 要点 |
|---|---|
| 结论 | userId→MemberProfile Tool;storeId 默认最近门店或显式参数。 |
| 工程 | JWT 解析后注入 ToolContext,禁止用户伪造 storeId 越权。 |
| 验证 | 跨店库存测试。 |
| 风险 | 忽略门店 ATP → 下单失败。 |
14. Payment 智能推荐付款方式
完整代码见 08 §10.14。
14.1 Staff 面试题
B27 · rank Tool 与 list Tool 为何要拆开?
| 段 | 要点 |
|---|---|
| 结论 | list 返回 可用全集+维护态 ;rank 在子集上 规则排序;LLM 不合并以防编造不可用渠道。 |
| 验证 | KLARNA 地区不支持时必须在 unavailable。 |
| 风险 | 单 Tool 返回「推荐 PayPal」但已维护 → 结账失败。 |
B28 · Vault token 如何出现在 Tool 响应?
| 段 | 要点 |
|---|---|
| 结论 | 仅 VISA_TOKEN_***12 掩码;永不返回 PAN/CVV。 |
| 工程 | PaymentComplianceAdvisor 扫日志。 |
| 风险 | 调试日志打全卡号 → PCI 违规。 |
§99 全场景 Master Checklist + 面试索引
99.1 上线前 42 项(Buy 域)
| 域 | 检查项 |
|---|---|
| 模型 | LiteLLM 主路径 + Azure fallback 熔断演练 |
| 模型 | commerce-fast / commerce-smart 别名与 SLA 对齐 |
| 向量 | L1 Redis / L2 pgvector / L3 Milvus 职责清晰 |
| 向量 | embedding 版本 pin + 漂移 CI |
| 交易 | 金额/库存/券/价/支付 仅 Tool |
| 交易 | Carts addLineItem 幂等 |
| 交易 | Payment 无 PAN 出网 |
| 交易 | 满减 explanation 无裸数字 |
| 写操作 | 退款/调拨/定价 Draft + HITL |
| 写操作 | 所有写 Tool 带 idempotencyKey |
| Agent | maxIterations=5 |
| Agent | 抽签/风控 LLM 不决策 |
| 安全 | SafeGuard + Llama Guard |
| 安全 | 敏感词转人工 |
| 观测 | Langfuse trace + $/successful_task |
| 观测 | 分 scene 成本归因 |
| Eval | 每场景 ≥50 golden + 红队集 |
| 合规 | 审计 7 年;PII 脱敏 |
99.2 面试题速查(B01--B28 ↔ 98)
| 场景 | 本书 | 98 联动 |
|---|---|---|
| 导购 | B01--B02 | C.101 |
| 客服 | B03--B04 | C.99, C.103 |
| 商品分析 | B05--B06 | C.111--C.112 |
| 搭配 | B07--B08 | C.113--C.114 |
| 满减 | B09--B10 | C.100, C.106 |
| 发售故事 | B11--B12 | C.115--C.116 |
| 选品 | B13--B14 | C.117--C.118 |
| 调拨 | B15--B16 | C.119--C.120 |
| 定价 | B17--B18 | C.102 |
| 评价 | B19--B20 | C.121--C.122 |
| 营销 | B21--B22 | --- |
| 反欺诈 | B23--B24 | --- |
| Carts | B25--B26 | C.104--C.105 |
| Payment | B27--B28 | C.107 |
关联文件
| 文件 | 用途 |
|---|---|
| 08-架构-电商 | 场景总览 + 部分 Demo |
| 14-Spring-AI | 框架/MCP/多 VectorStore |
| 98-冲刺 | 口述题库 C.98--C.122 |
| 13-Playbook | 12 能力域生产规范 |
一句话 :Buy 域智能化 = LiteLLM + Spring AI Tool 真源 + 三层向量 + 写操作 HITL ;14 场景代码骨架在本文,考前 B01--B28 + 98 C 段 交替口述。
官方文档与源码(一级依据)
AI Engineering · 正文机制应来自下方 官方文档(L1) 与 官方源码仓库(L2) ;
禁止用教程站/博客充当机制依据。本章 QPS/延迟/STAR 为面试示意。
L1 · 官方文档
L2 · 官方源码
L3 · 论文 / 开放规范