首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【Java·AI】后端接 AI 的三层边界:从 RAG 召回到工具调用校验的追问链

【Java·AI】后端接 AI 的三层边界:从 RAG 召回到工具调用校验的追问链

原创
作者头像
爪哇碎碎念
发布于 2026-11-12 12:40:46
发布于 2026-11-12 12:40:46
50
举报

这是一篇按「面试追问链」组织的轻内容。先给结论:Java 后端接 AI,难点不在选框架,而在把三层边界分清楚——检索链路是数据层、协议与编排是调用层、参数校验与幂等是业务层。模型输出是概率性的,确定性必须留在服务端。本文用一组站点实测和两组 JDK 17 最小实验把这三层钉住,所有代码可直接运行。版本前提:JDK 侧为 OpenJDK 17.0.20.1(Temurin / Windows,单文件源码模式);站点为 Spring Boot 3.2.11 + 原生 HTML/CSS/JS,AI 侧只写稳定概念;未搭建真实模型服务与向量库做端到端验证。

开场:这题为什么高频

近半年后端面试里,「你们系统怎么接的大模型」已经快追上「事务为什么不生效」了。它高频不是因为考 API 背诵,而是因为一问就能分清两类人:一类把接 AI 说成「引入某个框架」,另一类能说清哪一层归谁管、失效时先查哪一段。

有个类比很好用:接 AI 很像当年接 Spring,都是先分清配置注入、代理拦截、事务边界各自归谁,再挑具体组件。这个类比不准确的地方也恰恰是关键:Spring 的调用是确定性的,同样入参同样结果;模型输出是概率性的,不能把事务、幂等那套确定性假设照搬过来。后面所有追问,几乎都从这个差异长出来。

第一轮:基础题

面试官:说说 RAG 是什么。 候选人:三步——先把资料切成片段并向量化,检索时把问题也向量化、取回候选片段,最后把片段作为给定材料交给模型生成。 面试官:就这?中间哪一段最容易坏?

这里要补的是分段:切分 → 向量化 → 召回 → 重排 → 生成,每段有各自的失败特征。切分粒度决定信息是否被拆散;向量化要求入库与查询用同一个 embedding 模型版本;召回是候选集合,不是答案;重排做二次排序;生成阶段要约束「只用给定材料」。

候选人在白板上写下的是这条链路,而不是某个框架的类名:

代码语言:mermaid
复制
graph TD
    A[Java 后端接 AI] -->|前置| B[Token 与上下文窗口]
    A -->|前置| C[Embedding 与向量空间]
    C -->|因果| D[相似度不等于事实]
    A -->|组合| E[RAG 检索链路]
    E -->|进阶| F[向量库与召回]
    F -->|因果| G[混合检索与元数据过滤]
    A -->|组合| H[Function Calling]
    H -->|因果| I[服务端参数校验与幂等]
    A -->|对比| J[MCP 接口协议]
    A -->|对比| K[Agent 编排循环]
    A -->|进阶| L[推理可观测与评测回归]

面试官点评:把 RAG 说成「查向量库」只答了第三段。真正的考点是「按段定位」——用户说答得不对时,你能不能把问题落到具体某一段上。

第二轮:往深了问

追问一:召回为空,怎么定位

先看三类成因:入库侧(切分后片段没写进索引、增量没重建)、查询侧(查询向量与入库向量用的不是同一 embedding 模型版本)、闸门侧(topK 太小或相似度阈值设太高)。工程上再加两道:混合检索(字面 + 语义)兜住专有名词,元数据过滤把权限与时效挡在召回之前。

陷阱在哪:一上来就调 topK。阈值和索引都可能是好的,问题在「这段资料根本没入库」。定位顺序应该是「索引里有没有 → 查询向量对不对 → 闸门是不是过紧」。

追问二:相似度近,就一定是对的吗

候选人容易把余弦相似度当成语义真值。下面这段 JDK 17 单文件实验要证明的是:几何距离只说明两个坐标挨得近,不说明内容正确或有效。向量是手工构造的示意值,第三条文本标注的是「已作废的旧规则」。

代码语言:java
复制
// JDK 17.0.20.1 单文件源码模式:java CosineLab.java
import java.util.List;
public class CosineLab {
    record Doc(double x, double y) {}
    static double cos(Doc a, Doc b) {
        return (a.x()*b.x() + a.y()*b.y()) / (Math.hypot(a.x(),a.y()) * Math.hypot(b.x(),b.y()));
    }
    public static void main(String[] args) {
        var d = List.of(new Doc(1.00,0.20), new Doc(0.98,0.25), new Doc(0.96,0.22));
        for (int i = 1; i < d.size(); i++) System.out.printf("cos(0,%d) = %.4f%n", i, cos(d.get(0), d.get(i)));
    }
}
代码语言:bash
复制
# 实测输出(OpenJDK 17.0.20.1 / Windows)
# cos(0,1) = 0.9986
# cos(0,2) = 0.9996

作废的旧规则反而离得更近。陷阱在哪:召回阶段追求「相关」,事实性与时效性是评测集、引用溯源和元数据过滤的责任,不能指望一个距离分数全包。

追问三:模型给的工具参数能直接执行吗

这是 Java 工程师最该加分的一问。工具描述本质上是写给模型看的接口契约,模型返回的参数仍然只是一段文本,属于不可信输入。

代码语言:java
复制
// JDK 17.0.20.1 单文件源码模式:java ToolCallLab.java
import java.util.Map;
public class ToolCallLab {
    record Args(Map<String, String> p) {}
    static String checked(Args a) {
        String s = a.p().get("amount");
        if (s == null) return "REJECT missing amount";
        try {
            int v = Integer.parseInt(s);
            return (v > 0 && v <= 10_000) ? "TRANSFERRED " + v + " CNY" : "REJECT amount out of range";
        } catch (NumberFormatException e) { return "REJECT amount not an integer"; }
    }
    static String unchecked(Args a) { return "TRANSFERRED " + a.p().get("amount") + " CNY"; }
    public static void main(String[] args) {
        System.out.println("unchecked : " + unchecked(new Args(Map.of("amount", "-500"))));
        System.out.println("checked   : " + checked(new Args(Map.of("amount", "-500"))));
        System.out.println("checked   : " + checked(new Args(Map.of("amount", "abc"))));
    }
}
代码语言:bash
复制
# 实测输出(OpenJDK 17.0.20.1 / Windows)
# unchecked : TRANSFERRED -500 CNY
# checked   : REJECT amount out of range
# checked   : REJECT amount not an integer

不校验就执行,负数金额直接落到业务里:unchecked 那一路把 amount = -500 原样带进了业务,而 checked 那一路用范围与类型两道校验挡住了它。陷阱在哪:把校验放进「提示词里再强调一遍」。提示词是概率层的约束,参数校验、幂等键、失败回传、重试上限必须放在服务端确定层。

第三轮:场景题

面试官:做一个订单查询助手,用户可以问「我上周那笔单到哪了」,系统要调内部订单接口。给你 10 秒,说下你会切几层。

先想 10 秒,再看参考切法:

  1. 数据层:历史规则、FAQ 走 RAG,切分 + 向量化 + 召回 + 重排,元数据按租户与生效时间过滤。
  2. 调用层:工具注册只暴露「按订单号查状态」这类窄接口,描述写清参数与返回;固定流程能走完就不引入 Agent 编排循环。
  3. 业务层:用户身份、订单归属、金额范围一律服务端重校验;工具调用带幂等键,超时与失败按可降级路径回传。
  4. 观测层:每段留痕——首 token 延迟、总 token、召回命中数、工具调用成功率;日志脱敏,上线前跑评测回归。

面试官真正想听的是第 3 层。把「模型说了」当成「用户有权」,是这类系统最典型的越权入口。

面试官视角:这题到底在考什么

考点拆解成三句:能不能分层、能不能定位失效、能不能把确定性留在服务端。下面把关联知识点逐个补上关系说明,避免对话体把关系冲淡:

  • Token 与分词:它是理解上下文窗口与计费的地基——窗口按 token 计,中文同语义通常更贵,数字与代码的切分边界也会变。
  • Embedding 与向量空间:它是召回的前置——维度、归一化、模型版本任一不一致,相似度就失去可比性。
  • 幻觉与评估:它是「相似度不等于事实」的解药——用事实性评测集做回归,答案带出处,工程侧再叠检索与规则兜底。
  • RAG 检索链路:它与 Java 后端是组合依赖——Java 负责切分、入库、权限与重排调度,模型只负责在给定材料内生成。
  • 向量库与召回:它是 RAG 的进阶——近似索引、双重闸门、混合检索、索引增量维护都在这里落地。
  • Function Calling:它与业务层是组合依赖——工具描述是契约,参数校验归服务端,两者不能合并。
  • MCP 与 Agent:它们与框架选型是同级对比关系——一个是接口协议,一个是编排循环,不是同一个东西;固定流程优先于 Agent。
  • Spring AI / LangChain4j 抽象层:它们与核心知识点是同一道题的两种解法——把模型调用收进统一客户端或链式编排,选型看团队对可观测与状态管理的需求,抽象层不包办业务。
  • 推理参数:它是可复现性的进阶延伸——贪心解码优先于花式采样,别假设逐字一致。
  • 推理部署与可观测:它是所有优化的因果前提——没有延迟、token、链路追踪的维度归因,就谈不上优化。

答不上来怎么办:前置知识补课

我把这套关系整理进了站内的知识地图。下面这组数字是本机直接请求 /api/health 与 /api/catalog 实跑出来的,不是估的:

代码语言:bash
复制
# 站点健康接口与目录统计(2026-11-12 实测)
curl -s https://zhuawassn.xyz/api/health
# {"status":"UP","scenes":95,"domains":14,"linkReachable":95,"linkDead":0}
# /api/catalog -> 14 域 / 95 场景 / 546 节点
# ai-basics: 7 图 / 37 节点;ai-eng: 7 图 / 39 节点;合计 14 图 / 76 节点
# 95 张图的原文入口 95/95 可达,死链 0

新增的 ai-basics / ai-eng 两域正好对应三条补课路径:

  1. 先补基础:Token 与分词 → Embedding → 注意力机制 → Transformer → 预训练/微调/对齐 → 幻觉与评估 → 推理参数。
  2. 再补工程:Spring AI 抽象层 → LangChain4j 编排 → RAG 检索链路 → 向量库与召回 → Function Calling → MCP 与 Agent → 推理部署与可观测。
  3. 最后补边界:每条链路都标了「什么时候不该用它」,比如召回为空的三类成因、固定流程优先于 Agent、什么时候不该微调(先试检索)。

这 14 张图不配独立成稿,原文入口统一由站内要点讲义即时生成,所以 95 张图的原文才都是 200。

加分项:Java 已有能力怎么迁移

跨语言对照在这里最有杀伤力:Python 生态习惯把模型调用写在脚本里,Java 生态更习惯把外部依赖收进一个可注入、可拦截、可观测的客户端。后者在 AI 场景反而占便宜——

已有能力

迁移到 AI 工程

不迁移的代价

配置注入 / 统一客户端

模型调用收口,切供应商不改业务

密钥与参数散落在各业务类

参数校验 / 幂等键

工具调用的参数与副作用管控

负数金额、重复下单直接落到库里

事务边界意识

明确「模型输出不受事务保护」

把概率结果当确定性状态写入

链路追踪 / 日志脱敏

token、延迟、召回命中按维度归因

出问题只能靠人肉串日志

结论:Java 工程师不需要重新学一套工程观,只需要承认一件事——模型那一层不提供确定性,确定性仍由服务端提供。

对比速查表

层

归谁管

典型失效特征

数据层(检索链路)

切分、向量化、召回、重排

召回为空、命中作废规则

调用层(协议与编排)

工具注册、接口协议、编排循环

把 MCP 当 Agent、固定流程被绕成循环

业务层(确定性兜底)

校验、幂等、权限、失败回传

负数金额、越权查询、重复副作用

观测层(可观测)

token、延迟、链路、评测回归

只能凭感觉调参

收尾:一句话答案模板

我按三层切:检索链路管数据,工具协议与编排管调用,参数校验、幂等、权限和失败回传留在 Java 服务端,因为模型输出是概率性的;再用 token、延迟、召回命中和评测回归做观测。选型放到最后,先定边界再挑框架,固定流程能走完就不上 Agent。

三句话带走:先分层再选框架;模型参数一律不可信;没有观测就没有优化。

延伸阅读

  • JDK 动态代理与反射 → Spring AOP 代理创建流程(对照「确定性拦截」)
  • 事务传播行为与 TransactionSynchronizationManager(对照「上下文绑定」)
  • 接口幂等与重试的副作用管控
  • 链路追踪在线程池与消息队列里的断点
  • 向量检索的近似索引与混合检索
  • 事实性评测集与引用溯源

以上是一组最小复现与机制推演,不是真实生产事故记录。评论区交流,发现错误欢迎指正。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 开场:这题为什么高频
  • 第一轮:基础题
  • 第二轮:往深了问
    • 追问一:召回为空,怎么定位
    • 追问二:相似度近,就一定是对的吗
    • 追问三:模型给的工具参数能直接执行吗
  • 第三轮:场景题
  • 面试官视角:这题到底在考什么
  • 答不上来怎么办:前置知识补课
  • 加分项:Java 已有能力怎么迁移
  • 对比速查表
  • 收尾:一句话答案模板
    • 延伸阅读
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档