项目固定技术口径:

前端:Vue
后端:Spring Boot + Spring AI
业务数据库:Oracle
向量数据库:PostgreSQL + PGVector
检索增强:RAG
Agent 编排:Spring AI Advisor + Prompt + Model + MCP Tool
权限入口:Spring Security + JWT + Nginx
动态数据源:ThreadLocal + AbstractRoutingDataSource + MyBatis

你的项目一句话总结:

这个项目不是简单“接入大模型问答”,而是把井场多源数据录入、字段补全、结构化抽取、知识检索和 Agent 工具调用整合到一个业务系统中。Oracle 存结构化生产数据,PGVector 存知识库向量,Spring AI 负责大模型调用、RAG 检索增强和 Agent 编排,最终提升录入效率和查询效率。


一、组件先讲清楚

Q1:这个项目里每个组件分别是干什么的?

这个项目里组件分工很明确。

Spring Boot:业务系统主体,负责接口、权限、业务流程、数据入库。
Spring AI:负责接入大模型,封装 Prompt、Model、Advisor、RAG、Tool 调用。
Oracle:存井场业务数据,比如生产日报、井号、井段、设备参数、录入记录。
PostgreSQL + PGVector:存知识库文本切片和向量,用来做相似度检索。
Nginx:统一入口,做反向代理、HTTPS、请求大小限制、基础限流。
Spring Security + JWT:做登录认证、接口权限、用户身份识别。
ThreadLocal 动态数据源:根据业务类型切换不同 Oracle 数据源。
MyBatis:访问 Oracle 业务表。
MCP Tool:把业务能力封装成大模型可调用的工具,比如查井号、查历史记录、查知识库。
Advisor:在大模型调用前后做上下文增强、记忆注入、RAG 检索、日志记录等横切处理。

一句话:

Oracle 存业务数据;
PGVector 存知识向量;
Spring AI 调模型和编排 Agent;
MCP 把业务接口包装成模型工具;
Advisor 负责给模型补上下文;
Nginx 和 Spring Security 管入口和权限。

二、项目整体架构 Q&A

Q2:你这个 AI 井场自动化数据录入检索系统整体是做什么的?

这个系统面向井场多源生产数据录入和查询场景,核心目标是减少人工录入成本,提高生产数据录入和检索效率。

传统流程里,井场数据来源比较分散,包括生产日报、设备记录、井况描述、历史文档、规程资料等。人工录入时需要反复查资料、对字段、复制粘贴,容易慢、漏、错。

这个项目引入大模型和 RAG,将系统做成三个能力:

第一,智能录入。用户输入一段自然语言描述或者上传一段生产记录,系统自动识别其中的井号、井段、日期、生产参数、异常描述等字段,并填充到表单中。

第二,语义补全。用户录入部分字段后,系统根据历史数据、字段规则和上下文给出补全建议。

第三,知识检索问答。用户可以用自然语言问井场制度、生产规范、历史记录相关问题,系统先从知识库检索相关片段,再让大模型基于检索内容回答。

整体架构是:Spring Boot 承载业务接口,Oracle 存结构化业务数据,PGVector 存知识库向量,Spring AI 负责大模型调用和 RAG 检索增强,Agent 负责把 Prompt、Advisor、Model、MCP 工具组合成可编排流程。


Q3:这个项目的完整链路是什么?

完整链路可以分成两条:智能录入链路和知识检索链路。

智能录入链路是:

用户输入井场生产描述
  ↓
Spring Boot 接收请求
  ↓
Spring Security 校验身份和权限
  ↓
根据业务类型选择 Oracle 数据源
  ↓
Spring AI 构造 Prompt
  ↓
大模型抽取结构化字段
  ↓
后端校验字段合法性
  ↓
低置信度字段标记人工确认
  ↓
写入 Oracle 业务表
  ↓
返回表单补全结果

知识检索链路是:

用户自然语言提问
  ↓
Spring Boot 接收问题
  ↓
查询重写,规范井号、字段别名、业务关键词
  ↓
对问题生成 embedding
  ↓
PGVector 做相似度检索
  ↓
返回 TopK 文档切片
  ↓
构造 RAG Prompt
  ↓
大模型基于检索片段生成答案
  ↓
返回答案、引用片段、来源文档

Agent 编排链路是:

用户提出复杂任务
  ↓
Agent 判断意图
  ↓
决定调用 RAG、Oracle 查询、字段抽取、规则校验等工具
  ↓
多个工具结果聚合
  ↓
大模型生成最终建议
  ↓
后端校验并返回

Q4:这个项目最复杂的模块是什么?

最复杂的是 RAG 检索增强和 Agent 编排这两块。

RAG 的难点不是“把文档向量化后查一下”,而是怎么让用户问题真正命中正确知识。井场文档里存在很多专业术语、字段别名、缩写、规程描述,如果直接拿用户问题做向量检索,容易召回不准。所以我做了查询重写、字段别名规范、按业务类型过滤、相似度阈值控制和 TopK 片段拼接。

Agent 的难点是把大模型从“聊天”变成“能调用业务工具完成任务”。比如用户说“帮我补一下这条井场生产记录,并检查有没有异常”,Agent 不能只回答文字,而要先抽取字段,再查 Oracle 历史记录,再查知识库规则,最后综合生成建议。

所以这个项目的难点不是接模型接口,而是如何把大模型、业务数据、知识库检索、工具调用和权限控制组合成一个稳定业务流程。


三、智能录入、语义补全、结构化抽取 Q&A

Q5:智能录入是怎么实现的?

智能录入的核心是把用户输入的自然语言或半结构化文本,转成系统表单需要的结构化字段。

流程是:

用户输入生产描述
  ↓
后端识别业务类型
  ↓
构造结构化抽取 Prompt
  ↓
调用大模型
  ↓
要求模型按 JSON Schema 输出
  ↓
后端解析 JSON
  ↓
字段合法性校验
  ↓
低置信度字段提示人工确认
  ↓
写入 Oracle

比如用户输入:

胜利井区 A12 井,今日泵压 12.5MPa,日产液 36 方,含水率 78%,设备运行正常。

模型需要输出:

{
  "wellNo": "A12",
  "pumpPressure": 12.5,
  "dailyLiquid": 36,
  "waterCut": 78,
  "equipmentStatus": "正常"
}

后端不会直接相信模型输出,而是会做字段校验,比如数值范围、单位、必填项、枚举值是否合法。如果字段缺失或不确定,就返回给前端让人工确认。


Q6:语义补全是怎么做的?

语义补全是基于当前录入上下文、历史记录和字段规则给出建议。

比如用户已经填了井号、日期和部分生产参数,系统会根据井号查询 Oracle 中该井的历史记录,再结合知识库中的字段规则,让模型生成可能的补全建议。

流程是:

用户填写部分字段
  ↓
后端拿到当前表单上下文
  ↓
查询 Oracle 历史记录
  ↓
检索 PGVector 中相关规则或模板
  ↓
构造补全 Prompt
  ↓
模型生成补全建议
  ↓
后端校验
  ↓
前端展示“建议填充值”

这里的关键是:模型只给建议,不直接强制覆盖用户输入。最终提交前仍然由用户确认。


Q7:结构化抽取时怎么保证模型输出格式稳定?

我主要做了四件事。

第一,在 Prompt 中明确要求模型只输出 JSON,不输出解释性文字。

第二,给出固定 JSON Schema,字段名、类型、单位、是否必填都写清楚。

第三,在后端用 JSON 解析器做强校验。如果解析失败、字段类型不对、缺少必填字段,就触发修复 Prompt 或返回人工确认。

第四,对关键字段做业务校验。比如日期格式、井号是否存在、数值范围是否合理、枚举值是否在允许范围内。

所以不是模型输出什么就直接入库,而是“模型抽取 + 后端校验 + 人工确认”三层控制。


Q8:如果模型抽取错了怎么办?

模型抽取结果不会直接作为最终数据入库。

系统会把模型抽取结果展示在前端表单中,用户可以修改确认。后端还会做字段合法性校验,比如井号是否存在、日期是否合理、数值是否越界、单位是否匹配。

对于低置信度字段,系统会标记为“需确认”。对于无法解析或明显异常的字段,直接不给自动填充,而是提示人工录入。

所以模型在这个场景里是辅助录入,不是替代业务校验。


Q9:如何防止大模型幻觉?

这个项目主要通过四种方式降低幻觉。

第一,RAG 检索增强。知识问答时要求模型必须基于检索到的文档片段回答,不能自由发挥。

第二,结构化输出约束。字段抽取时要求模型按固定 JSON Schema 输出,减少开放式生成。

第三,后端规则校验。数值范围、字段枚举、井号合法性、数据源权限都由后端校验,不能只信模型。

第四,答案引用来源。知识问答结果返回来源片段和文档标题,用户可以看到答案依据。

如果检索不到相关资料,系统提示“知识库中未检索到明确依据”,而不是让模型编答案。


四、Spring AI Q&A

Q10:Spring AI 在项目中具体用来做什么?

Spring AI 主要用来统一接入大模型能力,并把 Prompt、模型调用、RAG 检索、Advisor 和工具调用组合起来。

在项目中主要用在五个地方:

第一,调用大模型完成字段抽取、语义补全和辅助分析。

第二,管理 Prompt 模板,把不同业务场景的 Prompt 参数化。

第三,构建 RAG 检索问答链路,把 PGVector 检索结果注入模型上下文。

第四,使用 Advisor 在模型调用前后做上下文增强、日志记录和会话记忆处理。

第五,结合 MCP Tool,让大模型可以调用业务工具,比如查询井号、查询历史记录、检索知识库、校验字段规则。


Q11:Spring AI 里面 Prompt、Model、Advisor、MCP 分别是什么?

Prompt 是给大模型的指令模板。比如结构化抽取 Prompt、字段补全 Prompt、知识问答 Prompt。

Model 是具体的大模型调用接口,负责把 Prompt 发给模型并接收返回结果。

Advisor 是调用链上的增强器,可以在模型调用前后插入逻辑,比如注入历史上下文、追加 RAG 检索结果、记录日志、控制输出格式。

MCP Tool 是模型可以调用的外部工具。比如“查井号信息”“查历史生产记录”“查知识库片段”“校验字段是否合法”,这些都可以包装成工具供 Agent 调用。

你可以这样理解:

Prompt:告诉模型干什么;
Model:真正调用模型;
Advisor:给模型补上下文、做增强;
MCP Tool:让模型能调用业务系统能力。

Q12:为什么用 Spring AI,而不是自己直接调大模型 HTTP 接口?

直接调 HTTP 接口只能解决“把 Prompt 发给模型”这一步,但项目里不只是简单问答,还包括 Prompt 管理、结构化输出、RAG 检索、上下文注入、工具调用和日志治理。

Spring AI 的好处是可以把大模型调用变成标准化工程组件:

第一,统一模型调用入口,后续更换模型时改造成本低。

第二,Prompt 模板更容易管理,不会散落在业务代码里。

第三,RAG 和 VectorStore 集成更方便,可以直接和 PGVector 链接。

第四,Advisor 可以把检索增强、上下文记忆、日志记录做成统一链路。

第五,Tool/MCP 机制方便 Agent 调用业务能力。

所以 Spring AI 更适合 Java 业务系统落地 AI 应用。


Q13:Spring AI 和 LangChain、LlamaIndex 有什么区别?

LangChain 更偏通用 Agent 和链式编排生态,Python 生态成熟,适合快速做原型、多工具实验和复杂 Agent 流程。

LlamaIndex 更偏数据连接和知识库索引,适合围绕文档、索引、检索、数据连接构建 RAG 应用。

Spring AI 更适合 Java/Spring 体系里的企业应用落地。它和 Spring Boot、Spring Security、MyBatis、业务服务结合更自然,适合把大模型能力嵌入已有 Java 后端系统。

我们这个项目主体是 Spring Boot + Oracle + MyBatis,所以使用 Spring AI 能更好地和现有 Java 工程体系融合。


五、RAG 检索链路 Q&A

Q14:RAG 完整流程是什么?

这个项目的 RAG 流程是:

文档上传
  ↓
文档解析
  ↓
文本清洗
  ↓
文本切分
  ↓
生成 embedding
  ↓
写入 PGVector
  ↓
用户提问
  ↓
查询重写
  ↓
问题向量化
  ↓
PGVector 相似度检索
  ↓
返回 TopK 文档片段
  ↓
构造 RAG Prompt
  ↓
大模型生成答案
  ↓
返回答案和来源

RAG 的核心作用是:让模型基于企业内部知识库回答,而不是完全依赖模型自身记忆。


Q15:知识库里的文档支持什么类型?

项目里固定支持这几类:

PDF
Word
TXT
Markdown

解析后统一转换成纯文本,再做清洗和切分。文档元数据包括文档标题、业务类型、上传人、更新时间、来源路径和权限范围。


Q16:文档解析后怎么切分?

项目里采用“标题层级 + 固定长度 + 重叠窗口”的切分方式。

固定规则是:

优先按标题、段落、条款编号切分;
单个 chunk 控制在约 500 到 800 个中文字符;
相邻 chunk 保留约 100 字重叠;
每个 chunk 保留 docId、chunkIndex、标题、章节路径、业务类型等元数据。

这样做的原因是:完全按固定长度切分容易把一个完整规则切断;完全按标题切分又可能出现某些段落过长。所以采用标题优先、长度兜底、重叠保上下文。


Q17:为什么要做语义分块?

语义分块解决的是“文档侧”的问题。

如果切分太碎,模型拿到的片段缺少上下文,回答容易断章取义。

如果切分太大,向量语义会变得模糊,检索时不容易命中准确位置。

所以语义分块的目标是让一个 chunk 尽量表达一个完整语义单元,比如一个制度条款、一个操作步骤、一段字段说明。

在井场知识库里,很多文档是规程、制度、模板和字段说明,必须尽量保持条款完整性。否则用户问一个字段规则时,可能只召回半句话,模型回答就不稳定。


Q18:PGVector 里存什么?

PGVector 中存的是知识库文本切片和对应向量,不存 Oracle 业务表数据。

表结构大致包括:

id
doc_id
chunk_id
content
embedding
title
section_path
business_type
source_file
chunk_index
create_time
update_time
permission_scope

其中:

content:文本切片内容
embedding:content 对应的向量
doc_id:原始文档 ID
section_path:章节路径
business_type:业务类型
permission_scope:权限范围

用户提问时,系统把问题也转成向量,然后和 PGVector 中的 embedding 做相似度检索。


Q19:PGVector 相似度检索怎么做?

流程是:

用户问题
  ↓
查询重写
  ↓
生成问题 embedding
  ↓
PGVector 按 cosine similarity 检索
  ↓
按业务类型和权限范围过滤
  ↓
取 TopK
  ↓
低于阈值的结果丢弃

检索时不是只看向量相似度,还会结合元数据过滤,比如业务类型、用户权限、文档状态。这样可以避免用户检索到无权限或无关业务文档。


Q20:相似度阈值怎么确定?

相似度阈值不是拍脑袋定的,而是通过业务问答样本调出来的。

具体做法是整理一批典型问题,例如字段含义、录入规则、生产日报说明、异常处理规范等,每个问题人工标注正确文档片段。然后测试不同阈值下的召回效果。

一般会观察:

Recall@K:正确片段是否在 TopK 中
MRR:正确片段排名是否靠前
人工可接受率:回答是否能被业务人员接受
误召回率:无关片段是否过多

阈值太高会漏召回,阈值太低会召回很多无关片段。项目里可以把初始阈值设置在 0.72 左右,再根据业务测试集调整。

面试时可以这样说:我们不是只看单个相似度分数,而是结合 TopK、阈值、业务类型过滤和人工验证集来调参。


Q21:TopK 设置多少?

项目里初始 TopK 设置为 6 到 8 个片段。

原因是:TopK 太小,可能漏掉关键依据;TopK 太大,会把大量无关内容塞进上下文,增加 token 成本,还可能干扰模型判断。

最终传给模型前,还要做一次上下文预算控制。如果片段太长,会保留高分片段和标题路径,避免超过模型上下文窗口。


Q22:查询重写解决什么问题?

查询重写解决的是“用户问题侧”的问题。

用户提问往往不标准,比如:

“这个井今天数据异常吗?”
“泵压这个字段咋填?”
“日报里那个含水怎么算?”

这些问题可能缺少标准字段名、业务类型、井号或时间范围。查询重写会把口语化问题改写成更适合检索的形式。

比如:

用户问题:泵压这个字段咋填?
重写后:井场生产日报中泵压字段的录入规则、单位、取值范围

查询重写还会处理字段别名、缩写和业务术语,比如把“日产液”规范成“日液产量”,把“含水”规范成“含水率”。


Q23:查询重写和语义分块分别解决什么问题?为什么要一起用?

查询重写解决用户问题侧的问题,语义分块解决知识库文档侧的问题。

查询重写让用户的自然语言问题更接近知识库里的标准表达,提升召回准确率。

语义分块让知识库中的文本切片更完整,避免召回半句话或不完整条款。

二者叠加使用,是因为 RAG 的召回质量取决于“问题表达”和“文档切片”两端。只做查询重写,文档切得不好仍然会召回不完整内容;只做语义分块,用户问题太口语化也可能召回不到。

所以这两个策略是互补关系。


Q24:RAG 检索结果不准怎么办?

我会从四层优化。

第一,优化文档切分。把过长或过短的 chunk 调整到合适粒度,保留标题和章节路径。

第二,优化查询重写。补充字段别名、业务术语、井场常用缩写,让问题更接近知识库表达。

第三,增加元数据过滤。根据业务类型、文档状态、权限范围过滤无关文档。

第四,调整 TopK 和相似度阈值。阈值太低会召回噪声,阈值太高会漏召回。

如果仍然不准,再考虑引入 rerank,但本项目当前主线是 PGVector 向量检索 + 查询重写 + 元数据过滤。


Q25:没有检索到相关内容时怎么办?

不能让模型硬编答案。

如果 PGVector 检索结果低于相似度阈值,系统会返回“知识库中未检索到明确依据”,并提示用户换一种问法或补充业务条件。

对于必须回答的录入场景,系统会退回到字段规则校验和人工确认,不让模型凭空生成生产数据。


六、Agent 与 MCP 编排 Q&A

Q26:Agent 和普通大模型对话有什么区别?

普通大模型对话主要是用户问、模型答,模型只生成文本。

Agent 不只是回答文本,而是可以根据任务目标决定调用哪些工具、按什么顺序执行、如何聚合结果。

在这个项目里,用户说“帮我补全这条生产记录,并看看有没有异常”,普通对话只能给文字建议;Agent 会先抽取字段,再调用 Oracle 查询历史记录,再调用 RAG 查字段规则,最后综合判断并生成补全结果。

所以 Agent 的核心是“模型 + 工具 + 规划 + 执行 + 汇总”。


Q27:你项目里的 Agent 执行流程是什么?

项目里的 Agent 流程是:

用户输入任务
  ↓
意图识别
  ↓
选择执行计划
  ↓
调用 MCP 工具
  ↓
工具结果聚合
  ↓
大模型生成结果
  ↓
后端规则校验
  ↓
返回给用户

比如用户说:

帮我补全 A12 井今天的生产日报,并检查异常。

Agent 会执行:

1. 识别任务类型:生产日报补全 + 异常检查
2. 调用 Oracle 工具查询 A12 井历史记录
3. 调用 RAG 工具查询生产日报字段规则
4. 调用结构化抽取工具解析用户输入
5. 聚合历史数据、规则和当前输入
6. 生成补全建议
7. 后端校验数值范围和必填字段
8. 返回前端展示

Q28:MCP 在你项目里是什么?

MCP 可以理解成把业务系统能力标准化暴露给大模型调用的协议或工具接口。

在项目里,我把一些后端能力封装成 MCP Tool,例如:

查询井号基础信息
查询历史生产记录
查询知识库片段
校验字段规则
查询数据字典
生成结构化录入草稿

模型不直接访问数据库,而是通过受控工具访问业务能力。这样可以保证权限、安全和输出格式可控。


Q29:为什么不能让大模型直接查数据库?

不能让大模型直接查数据库,原因有三点。

第一,安全风险。大模型可能生成危险 SQL 或越权查询。

第二,权限不可控。不同用户只能访问不同井场、不同业务库,直接让模型查库会绕过权限控制。

第三,结果不可控。模型生成 SQL 的准确性不稳定,容易查错表、错字段或产生低效 SQL。

所以项目里采用 MCP Tool 封装查询能力,工具内部由后端控制 SQL、权限、参数校验和返回格式。模型只能调用工具,不能直接操作数据库。


Q30:Agent 怎么防止陷入死循环?

主要做四个限制。

第一,设置最大执行步数,比如 maxSteps = 5。超过步数直接停止,返回当前结果或提示人工处理。

第二,记录工具调用轨迹。如果同一个工具连续调用两次以上,且输入参数基本相同,就认为可能陷入循环,强制停止。

第三,工具调用失败后有限重试。比如同一工具最多重试一次,不能无限重试。

第四,规划结果后端校验。Agent 每一步执行前,后端判断工具是否允许调用、参数是否完整、用户是否有权限。


Q31:Agent 的短期记忆放在哪里?

短期记忆放 Redis,但不是把所有上下文都塞进去。

Redis 中按 sessionId 保存用户最近几轮对话摘要和关键变量,比如当前井号、当前业务类型、当前表单状态。TTL 设置为 30 分钟。

key 可以设计为:

agent:memory:{userId}:{sessionId}

为了避免 Redis 大 key,只保存最近 6 轮对话摘要,不保存完整文档片段和大模型完整回复。超过长度后,把历史对话压缩成摘要。

这样既能保持上下文,又不会让 Redis 存大对象。


Q32:上下文窗口有限,放不下怎么办?

不能把所有历史对话和文档片段都塞给模型。

处理策略是:

第一,只保留最近几轮对话和当前任务必要字段。

第二,历史对话超过长度后做摘要,只保留关键信息。

第三,RAG 只取 TopK 高相关片段,并控制总 token 预算。

第四,工具返回结果做裁剪,只保留模型需要判断的字段。

第五,最终 Prompt 中明确区分用户问题、已知上下文、检索依据和输出要求。

核心原则是:上下文不是越多越好,而是越相关越好。


七、动态数据源 + Oracle + MyBatis Q&A

Q33:为什么要做动态数据源?

井场业务数据来自多个业务库,不同业务系统或不同井场的数据可能存放在不同 Oracle 数据源中。

如果所有数据混在一个库里,耦合度高,权限隔离和维护都不方便。动态数据源可以根据业务类型、井场标识或租户标识选择对应 Oracle 数据源,实现多业务库隔离访问。

比如:

生产日报 → Oracle 数据源 A
设备运行记录 → Oracle 数据源 B
历史井况数据 → Oracle 数据源 C

用户请求进入后,系统根据业务上下文设置当前数据源,MyBatis 查询时自动路由到对应 Oracle。


Q34:ThreadLocal 动态数据源怎么实现?

实现流程是:

Controller 接收请求
  ↓
AOP 解析业务类型或 @DataSource 注解
  ↓
把数据源 key 放入 ThreadLocal
  ↓
AbstractRoutingDataSource 根据 ThreadLocal 返回真实 DataSource
  ↓
MyBatis 执行 SQL
  ↓
请求结束后 finally 清理 ThreadLocal

核心代码逻辑是:

DataSourceContextHolder.set("productionDS");

然后 AbstractRoutingDataSourcedetermineCurrentLookupKey() 返回当前线程的数据源 key。

最重要的是请求结束后必须清理:

finally {
    DataSourceContextHolder.clear();
}

否则线程池复用线程时,可能出现数据源污染,导致下一个请求查错库。


Q35:动态数据源和事务有什么注意点?

数据源必须在事务开启前确定。

如果事务已经开启,再切换 ThreadLocal 数据源,通常不会生效,因为数据库连接已经从某个数据源拿出来了。

所以动态数据源 AOP 的执行顺序要高于事务 AOP,保证进入事务前就设置好数据源。

另外,不建议在一个本地事务里跨多个数据源操作。如果确实涉及多个库,优先拆成多个步骤,通过业务状态和补偿保证一致性,而不是引入复杂分布式事务。


Q36:为什么用 Oracle 存业务数据,PGVector 存知识向量?

Oracle 用来存结构化业务数据,比如生产日报、井号、井段、设备参数、录入记录。这些数据有明确表结构、事务一致性和复杂 SQL 查询需求。

PGVector 用来存知识库文本切片和向量。它适合做 embedding 相似度检索,用于 RAG 知识问答。

所以二者分工不同:

Oracle:业务数据主库
PGVector:知识库向量检索库

不能把 PGVector 当业务数据库,也不能让 Oracle 承担向量检索任务。


八、安全、权限与 Nginx Q&A

Q37:Spring Security + JWT 在项目中怎么用?

用户登录后,后端校验用户名密码,校验成功后生成 JWT。JWT 中存 userId、username、role、过期时间等非敏感信息。

前端后续请求在 Header 中携带:

Authorization: Bearer token

后端 JWT 过滤器解析 token,验证签名和过期时间。校验通过后,根据 userId 查询权限,构造 Authentication 放入 SecurityContext。

后续接口通过权限点控制,例如:

record:create
record:update
rag:query
agent:execute
admin:kb:manage

Q38:数据权限怎么控制?

接口权限控制能不能访问接口,数据权限控制能访问哪些井场、哪些业务库、哪些文档。

业务数据查询时,根据用户所属部门、井场权限、角色范围,在 SQL 中追加过滤条件。

RAG 检索时,也要按文档权限过滤。PGVector 表里有 permissionScope,检索时先过滤用户可见文档,再做相似度排序。

所以用户不能通过自然语言问答绕过数据权限。大模型只能看到检索出来且用户有权限访问的内容。


Q39:Nginx 在这个项目里做什么?

Nginx 作为统一入口,主要做四件事。

第一,反向代理,把前端请求转发到 Spring Boot 服务。

第二,HTTPS 终止和证书管理。

第三,基础限流和请求大小控制,防止异常请求直接打到后端。

第四,统一入口治理,比如路径转发、超时配置、静态资源处理。

Nginx 不是业务权限核心,真正的用户认证和接口授权还是由 Spring Security 完成。


九、效果指标与压测 Q&A

Q40:上线后录入效率提升约 30%,单条记录平均录入耗时缩短约 40%,这个数据怎么来的?

这个数据不能说成主观感觉,是通过上线前后的录入日志和人工统计对比得到的。

统计口径是:选取同类井场生产记录录入任务,记录从用户开始录入到提交成功的耗时。上线前是纯人工录入,上线后是 AI 辅助录入。

指标包括:

单条记录平均录入耗时
单位时间完成记录数
字段自动填充率
人工修改率
提交失败率

录入效率提升约 30%,指单位时间内完成的有效录入记录数提升。单条记录耗时缩短约 40%,指同类记录从开始录入到提交成功的平均耗时下降。

同时排除明显异常样本,比如网络中断、用户长时间离开页面、非同类业务表单,避免统计失真。


Q41:如果面试官问“并发量支持多少”,怎么答?

这个项目不能直接说一个泛化数字,要先说明压测口径。

我会把压测拆成三类。

第一,普通业务接口压测,比如登录、查询、保存记录,主要看 Spring Boot、Oracle、Redis、Nginx 的承载能力。

第二,RAG 问答压测,主要看 PGVector 检索耗时、大模型响应时间、上下文构造耗时。

第三,Agent 任务压测,主要看工具调用次数、Oracle 查询耗时、模型调用耗时和整体链路耗时。

RAG 和 Agent 的瓶颈通常不在 Spring Boot 本身,而在大模型响应时间、PGVector 检索、Oracle 查询和外部工具调用。

所以如果说并发量,一定要区分:

普通接口 QPS
RAG 查询 QPS
Agent 任务并发
大模型调用并发

不能把普通接口压测结果说成 AI 全链路并发能力。


Q42:RAG 问答慢,瓶颈可能在哪里?

主要看四个环节。

第一,查询重写是否调用了模型。如果查询重写也走大模型,会增加一次模型调用耗时。

第二,PGVector 检索是否慢。要看向量索引、TopK、过滤条件和表数据量。

第三,Prompt 上下文是否太长。塞入过多 chunk 会增加模型响应时间。

第四,大模型本身响应慢。这通常是 RAG 链路最大的耗时来源。

优化方向是:减少不必要的模型调用,优化 PGVector 索引,控制 TopK 和上下文长度,对高频问题做缓存。


Q43:如果 AI 接口并发上来,怎么保护系统?

第一,对 RAG 查询和 Agent 执行接口做限流,避免大模型调用被打爆。

第二,对同一用户或同一 IP 设置请求频率限制。

第三,对大模型调用设置超时和熔断。

第四,对高频知识问答结果做短期缓存。

第五,Agent 设置最大执行步数和工具调用次数,避免一个请求占用过多资源。

第六,大模型调用失败时返回降级提示,不影响 Oracle 业务数据录入主流程。


十、AI Coding 与个人能力 Q&A

Q44:你平时用 AI Coding 工具吗?

我用过,但主要作为辅助工具,不会直接复制生成代码上线。

我主要用在三个方面。

第一,快速生成样板代码,比如 DTO、Mapper、简单 Controller、Prompt 模板初稿。

第二,辅助排查问题,比如根据异常栈分析可能原因。

第三,辅助优化表达,比如整理接口文档、测试用例和注释。

但核心业务逻辑,比如数据源切换、权限控制、RAG 检索链路、Agent 工具调用,我会自己理解后再改。AI 生成代码必须经过代码审查、单元测试和业务验证。


Q45:AI Coding 和传统开发有什么区别?

AI Coding 提高了样板代码和方案探索效率,但它不能替代工程判断。

传统开发强调需求理解、架构设计、边界条件、异常处理、数据一致性和可维护性。AI 可以辅助写代码,但无法完全保证业务正确性。

比如在这个项目里,AI 可以帮我生成 PGVector 查询代码或 Prompt 模板,但它不知道我们的井场字段规则、数据权限边界和 Oracle 表结构细节。这些必须由开发人员判断。

所以我把 AI Coding 当作效率工具,而不是决策工具。


十一、高频综合追问

Q46:这个项目和普通后台系统的区别是什么?

普通后台系统主要是 CRUD,用户填什么,系统存什么。

这个项目在传统后台系统上增加了 AI 能力:通过大模型理解自然语言,通过 RAG 查询内部知识库,通过 Agent 调用业务工具,通过结构化抽取辅助录入。

但它不是抛弃传统后台,而是把 AI 能力嵌入原有业务流程。最终数据仍然要经过权限控制、字段校验、人工确认和 Oracle 落库。

所以它的本质是 AI 增强型业务系统,不是单纯聊天机器人。


Q47:大模型输出不稳定,为什么还能用于业务系统?

因为项目没有让大模型直接决定最终业务数据,而是把它放在辅助层。

大模型负责生成建议、抽取字段、总结知识;后端负责校验、权限控制、规则判断和最终入库;用户负责确认关键字段。

也就是说,大模型输出必须经过:

结构化格式校验
业务规则校验
权限校验
人工确认

这样可以利用大模型的理解能力,同时控制它的不确定性风险。


Q48:这个项目如果让你继续优化,你会做什么?

我会从四个方向优化。

第一,优化 RAG 召回质量。继续完善字段别名库、业务术语库、语义分块策略和相似度阈值。

第二,增加 rerank。对 PGVector 召回结果进行二次排序,提高最终进入 Prompt 的片段质量。

第三,完善 Agent 工具链。把更多业务查询、规则校验、异常判断封装成 MCP Tool,让 Agent 能完成更复杂任务。

第四,加强评估体系。建立结构化抽取准确率、RAG 命中率、回答采纳率、人工修改率等指标,用数据驱动优化。

Logo

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

更多推荐