Spring-AI 面试题目

model类型面试题目

1.如何实现大模型的连续对话?

所有的大模型本身是不进行信息存储的,也不提供连续对话功能,所以想要实现连续对话功能需要开发者自己写代码才能实现

所以呢我们需要将当前用户的提问与经过管理的对话历史一同作为输入,提交给模型。

我们需要维护一个session,

通常是List<Message>结构。Message对象至少包含两个关键字段:

  • role: 角色(systemuserassistant
  • content: 消息内容

然后进入交互循环

  • 用户输入:接收用户的新消息(user role)。
  • 上下文构建:从存储中获取该会话的历史消息列表,并将新消息追加到列表末尾。
  • API调用:将完整的消息列表提交给大模型。
  • 获取响应:接收模型的回复(assistant role)。
  • 上下文持久化:将模型的回复也追加到历史消息列表中,并更新存储(如Redis、数据库等),为下一次交互做准备。

在这里面最重要的就是上下文是有窗口限制的,超出模型的Token限制(如4K, 8K, 32K, 128K)。这不仅会导致API调用失败,还会增加成本和响应延迟。

1.截断策略:

  • 简单滑动窗口:只保留最近的 N 轮对话。实现最简单,但会丢失早期的重要信息。
  • 保留首轮+滑动窗口:保留系统提示(system prompt)和第一轮对话,然后截取最近的 N-2 轮对话。适用于需要固定初始设定的场景。

2.摘要策略:

  • 滚动摘要:当对话长度达到一定阈值时,使用另一个LLM调用将较早的对话内容进行总结,用这个摘要替换掉原始的多轮对话。
  • 优点:保留了长期记忆的精华。
  • 缺点:摘要过程会丢失细节,并产生额外的API开销和延迟。

3.RAG策略:

  1. 存储:将每一轮完整的对话历史(或其要点)向量化后存入向量数据库 (VectorDB)。
  2. 检索:当用户提出新问题时,先将问题向量化,然后去向量数据库中检索最相关的 N 条历史对话记录。
  3. 注入:将这些检索出的、最相关的历史记录,连同当前问题,一起注入到提示词中,提交给大模型。
    • 突破长度限制:理论上可以维护无限的对话历史。
    • 高相关性:只提供与当前问题最相关的上下文,效率高。
  • 挑战:需要引入向量数据库(如Milvus, Pinecone)和embedding模型,系统复杂度更高。

这是我们自己需要配置的,但是Spring AI Alibaba 因为内置了连续对话的多种实现,比如mysql,redis

只需要简单配置就ok,我们注入注入 RedisChatMemoryRepository 对象。

然后配置 ChatClient 实现连续对话。

直接调用先prompt,然后advisors,最好call.context发送给模型

2.AI项目的执行流程

我习惯上分为离线数据处理(Data Preparation)在线请求处理(Real-time Inference)

1.离线数据处理:

这个阶段的目标是将原始、异构的数据处理成AI模型可以高效检索的结构化知识库。它是一次性的或周期性执行的。

  1. 多源数据抽取 (Extraction)
    • 首先,需要从多个来源抽取数据,这些数据就是我们常说的“知识”。来源可能包括:
      • 结构化数据:如MySQL, PostgreSQL里的业务数据。
      • 半结构化数据:如网页HTML, Markdown文档。
      • 非结构化数据:如PDF, Word文档, 纯文本。
      • API数据:通过调用内部或外部API获取的动态信息。
  2. 数据清洗与分块 (Cleaning & Chunking)
    • 原始数据是“脏”的,必须清洗。这包括去除无关信息(如HTML标签、广告、页眉页脚)、处理格式错误、统一编码等。
    • 清洗后,将长文本(如一篇长文档)切分成有意义的、大小适中的“文本块 (Chunks)”。这一步至关重要,因为文本块是后续向量检索的基本单位。分块的好坏直接影响检索质量。
  3. 向量化与索引 (Embedding & Indexing)
    • 这是将文本语言转换为数学语言的核心步骤。
    • 我们使用一个特定的Embedding模型,将每一个“文本块”计算成一个高维向量(Embedding)。这个向量可以被认为是该文本块在语义空间中的“坐标”。
    • 然后,将这些文本块原文连同它们的向量索引,存入一个或多个向量数据库(如Milvus, Pinecone)中。同时,也可能将关键词、元数据等存入传统检索引擎(如Elasticsearch)。

2.在线请求处理:

这个阶段是用户与系统实时交互的过程,追求低延迟和高精度。

  1. 意图分析 (Intention Analysis)
    • 请求的入口。当用户输入一句话,系统首先要理解“他想干什么”。
    • 这不仅仅是关键词识别,更深层次会判断用户意图,例如:是闲聊(Chitchat)?是问答(FAQ)?还是需要执行一个任务(Task-oriented)?
    • 意图分析的结果会决定后续调用哪些检索路径。比如,闲聊意图可能直接交给大语言模型,而问答意图则会触发后续的召回和排序流程。
  2. 多路召回 (Multi-path Recall)
    • 这是为了“宁可错杀,不可放过”,尽可能多地从不同渠道找回所有相关的候选答案。各路召回并行执行,以保证效率。
    • 向量召回(语义召回):将用户的查询也进行向量化,然后去向量数据库里进行相似度检索,找出语义上最接近的N个文本块。这是您提到的“向量检索”的应用环节。
    • 关键词召回(词法召回):使用传统搜索引擎(如Elasticsearch)根据关键词匹配,找出包含查询词的文本块。这能弥补向量召回在精确匹配上的不足。
    • 其他召回:还可能包括基于知识图谱的召回、基于数据库精确查询的召回等。
  3. 混合排序 (Hybrid Ranking/Re-ranking)
    • 多路召回会返回大量候选结果,质量良莠不齐,甚至有重复。排序阶段就是优中选优的过程。
    • 粗排 (Coarse Ranking):首先,通过一些简单的规则和模型,对召回的上百个结果进行快速排序和去重,筛选出Top K(比如Top 50)个候选结果。
    • 精排 (Fine-grained Ranking / Re-ranking):然后,使用一个更复杂、更强大的排序模型(通常是Cross-Encoder或专门的排序大模型),对这Top K个结果进行精准打分。这个模型会综合考虑查询与候选答案的语义相关性、业务重要性、时效性等多种特征,给出最终的、最合理的排序。
  4. 答案生成与整合 (Answer Generation & Synthesis)
    • 最后,系统会将排序最高的一个或几个结果,作为核心上下文,连同用户的原始问题,一起组织成一个精炼的提示词(Prompt)。
    • 将这个Prompt提交给一个强大的生成式大语言模型(如GPT-4),由它基于给定的上下文,生成最终的、通顺自然的回答,并呈现给用户。

3.Dify是什么?怎么使用?

Dify是一个开源的、一站式的LLM应用开发平台极大降低构建和管理生产级生成式AI应用的门槛,让开发者可以更专注于业务逻辑,而不是费力地搭建和维护复杂的AI基础设施。

过去我们需要自己手动管理Prompt、对接不同的大模型、搭建RAG(检索增强生成)流程、处理对话历史等,而Dify将这些复杂繁琐的工作产品化、可视化了。

1.为什么选择Dify?

  • 从效率和速度角度看: 对于需要快速验证原型(MVP)或业务逻辑不那么极端的项目,我会首选Dify。因为它将RAG、多模型支持、API封装等通用能力产品化了,可以让我们在几天甚至几小时内就搭建起一个可用的AI应用,极大地缩短了Time-to-Market(产品上市时间)。
  • 从维护成本角度看: Dify提供了一个完整的后台管理界面,包括日志、监控和用户反馈。这意味着运营人员或产品经理也可以参与到应用的优化中来,例如更新知识库、标注数据等。如果自研,这部分工作都需要开发人员投入精力去构建和维护,长期成本更高。
  • 对于自定义和灵活性: 当然,如果项目需求非常特殊,比如需要一个高度定制化的RAG策略(例如复杂的混合检索和重排逻辑),或者对系统性能有极致要求,那么基于LangChain或LlamaIndex自研会提供更高的灵活性和控制力。

2.Dify的Agent和Tool(工具)能力是如何工作的?它与传统的API调用有什么不同?

Dify的Agent和Tool能力,是实现Language Model as a Reasoning Engine(将语言模型作为推理引擎)的关键。它和传统API调用的核心区别在于‘决策者’不同

  • 传统API调用:是我们开发者在代码里提前写好逻辑。比如,if用户想查天气,then调用天气API。这个决策逻辑是由人预先编码的。
  • Dify中的Agent/Tool工作流:
  1. 工具注册:我们首先向Dify注册一个或多个工具,比如“天气查询API”、“计算器API”。关键在于,我们需要用自然语言向模型清晰地描述这个工具是做什么的、需要哪些参数(比如,天气查询API需要一个city参数)。
  2. 模型决策 (Reasoning):当用户提出一个模糊的需求,比如“帮我查查明天北京会不会下雨,适合穿什么?”,Agent接收到请求后,大模型会进行“思考”。
  3. 工具选择与调用:模型会分析用户的意图,并根据我们提供的工具描述,自主决定需要使用“天气查询API”。然后,它会从用户问题中提取出参数city: "北京",并生成一个调用该API的请求。
  4. 结果整合与响应:模型获取到API返回的天气数据后(比如“晴天”),会将其作为新的信息,结合它自己的知识(晴天适合穿什么),最终生成一段通顺的、完整的回答给用户。

Dify的Agent模式,把‘决定调用哪个API’以及‘如何组织参数’的权力,从开发者交给了大模型,实现了更高层次的自动化和智能化。”

3.如果让你来设计一个类似Dify的平台,你会如何规划它的技术架构?

设计一个类似Dify的平台,我会将其拆分为几个核心模块,并采用微服务的思想来构建,确保可扩展性和可维护性

  1. 前端 (Frontend)
    • 使用React或Vue等现代前端框架,负责提供所有可视化的操作界面,包括应用管理、Prompt Studio、知识库上传和运营后台等。
  2. API网关 (API Gateway)
    • 作为所有服务的统一入口,处理用户认证、请求路由、速率限制等。这是外部应用(比如用户的前端)与我们平台交互的门户。
  3. 应用编排服务 (Orchestration Service)
    • 这是平台的大脑。它负责解释在Studio中保存的应用配置。当一个API请求进来时,这个服务会根据应用定义,决定是走简单的LLM对话流程,还是需要执行RAG或Agent流程。它会编排并调用下游的各个服务。
  4. 模型管理服务 (Model Management Service)
    • 用于统一管理和对接不同的大模型提供商(OpenAI, Anthropic, Google Gemini, 以及开源模型)。它会封装好各家API的差异,对上层提供一个统一的调用接口。
  5. RAG服务 (RAG Service)
    • 这是一个独立的模块,负责知识库的全生命周期管理。
    • 写入路径:接收文档 -> 文本解析 -> 分块 (Chunking) -> 调用Embedding模型 -> 存入向量数据库。
    • 读取路径:接收查询 -> 向量化 -> 在向量数据库中进行相似性搜索 -> 返回相关文本块。
    • 技术选型:会用到向量数据库(如Milvus/Weaviate)和Embedding模型。
  6. 日志与监控服务 (Logging & Monitoring Service)
    • 专门收集所有API调用的日志、Token消耗、用户反馈等数据。
    • 将数据存入专门的数据库(如ClickHouse或Elasticsearch),并提供数据可视化界面,用于运营分析和应用优化。

4.那么怎么区分使用简单模型还是使用agent呢?

可以使用前置规则与关键词匹配 ,比如系统会维护一个“触发词”列表。当用户的输入包含这些特定的动词或名词时,系统会绕过复杂的判断,直接将其路由到Agent流程。

或者是利用大语言模型进行意图分类 ,我们设计一个专门用于“路由”的元提示 (Meta-Prompt)。这个Prompt会包含以下内容:

  1. 用户的原始问题
  2. 一个“选项列表”,这个列表描述了所有可用的“路径”。每个路径就是一个Agent或工具,外加一个“默认闲聊”的选项。
  3. 一个明确的指令,要求LLM根据用户问题,从列表中选择一个最合适的路径。

非常智能和灵活,能理解深层语义。这是目前最主流和最有效的方法。现代LLM的“Function Calling”或“Tool Use”功能,本质上就是这种机制的高度优化和内置实现。

或者是结合上下文进行动态判断,系统在做意图判断时,不仅考虑当前这一句,还会附加上下文(最近的几轮对话历史)

我在这个项目中主要用的是,分层漏斗模型

  1. 首先,通过一个‘快速通道’进行前置判断。我们会用关键词和规则匹配,快速识别出那些意图非常明确的请求,比如包含‘查询’、‘计算’、‘预订’等词语的指令,直接将它们路由给相应的Agent。这能覆盖掉一部分简单明确的任务,且成本最低。
  2. 其次,对于无法被快速通道处理的请求,我们会启用一个‘智能路由’层。这一层的核心是利用大语言模型自身的理解能力。我们会设计一个专门的‘路由Prompt’,把用户的请求和所有可用的‘工具’(Agents)以及一个‘闲聊’选项一起发给LLM,让模型来判断用户最可能的意图是什么。比如,模型需要从‘查询天气’、‘检查订单’和‘普通聊天’这几个选项里做出选择。这是目前最主流也最可靠的方式。
  3. 最后,在多轮对话中,我们会引入上下文进行动态判断。用户的意图可能不会在第一句话就完全暴露。因此,在做意图识别时,系统会结合最近的对话历史。比如用户先说了‘我想去北京’,接着问‘那边天气如何?’,系统就能结合上下文,准确地将这个模糊的问题路由到‘天气查询Agent’。