Spring-AI 基础知识

Spring-AI 基础知识
mengnankkzhou普通概念
Model
- ChatModel: 基于自回归语言模型,其核心是 Transformer Decoder 架构。它通过“逐字生成”的方式工作:接收一段文本(Prompt),预测下一个最可能的词(Token),然后将新生成的词加入输入,再次预测下一个,如此循环,直到生成完整的回答。这种机制保证了生成文本的上下文连贯性和逻辑性。
- EmbeddingModel:
EmbeddingModel
(如text-embedding-ada-002、text2vec-chinese)基于双向编码器,其核心是 Transformer Encoder 架构。与ChatModel不同,它会同时分析整个输入文本的上下文,然后将文本的深层语义信息映射到一个高维、密集的数字向量(Vector)中。在这个向量空间里,语义上相似的文本在空间距离上会更接近。
EmbeddingModel负责检索阶段:就是我们常说的嵌入模型
- 将查询和文档转换为向量表示
- 通过余弦相似度计算相关性
- 检索最相关的K个文档片段
ChatModel负责生成阶段:就是我们常用的聊天的那种模型
- 接收检索到的上下文+用户查询
- 基于上下文生成回答
- 保证回答的连贯性和准确性
那么我们如何选择模型呢?
维度大小:向量的维度。维度越高,通常能编码更丰富的语义信息,但也会增加存储和计算开销。
- 示例:
BERT-base
通常是768维,而OpenAI的text-embedding-ada-002
是1536维。
- 示例:
语言支持:模型是否针对特定语言(如中文)进行过优化。对于中文场景,使用专门的中文Embedding模型(如
text2vec-chinese
)效果远超通用模型。领域适配:通用模型在开放域表现良好,但在专业领域(如法律、医疗),使用经过该领域数据微调过的模型能显著提升准确性。
性能指标:
检索准确率 (Recall/Precision):衡量Embedding模型检索到的相关文档的准确度。
推理延迟 (Latency):模型处理一次请求所需的时间,直接影响用户体验。
比如我自定义知识库使用的就是Embedding v2 ada
重排模型:
VectorStore
VectorStore
负责存储EmbeddingModel
生成的向量,并提供高效的相似度检索能力。
特性 | Redis Vector | Pinecone | Weaviate |
---|---|---|---|
架构 | 内存+持久化 | 云原生分布式 | 图数据库+向量 |
索引算法 | HNSW/IVF | 专有优化算法 | HNSW |
存储成本 | 中等(内存占用高) | 高(按量计费) | 低(开源版免费) |
检索延迟 | <10ms | 10-50ms | 20-100ms |
扩展性 | 水平扩展复杂 | 自动扩缩容 | 手动扩展 |
- 小规模验证 (<10万文档):Redis Vector 是绝佳选择。部署简单,延迟极低,与现有Java生态无缝集成。
- 中等规模生产 (10万-1000万):Pinecone 提供完全托管的服务,免去运维烦恼,让你专注于业务逻辑。
- 大规模或定制化场景 (>1000万):Weaviate 的开源和分布式特性提供了极高的灵活性和成本优势,但需要投入运维资源。
- 成本敏感场景:Weaviate 开源版 自建部署是理想选择。
RAG
RAG就是检索增强,是一种让LLM访问外部知识库以回答问题的框架,极大地减少了模型幻觉,提高了回答的准确性。
我们使用嵌入模型的时候是需要对我们传入的文档进行切分的
切分策略:
一般的切分策略就是按照大小进行切分的,一般就是多少个字就切分。这样的话比较简答,但是可能破坏语句的完整性。适用于API,代码等
还有就是按照语义进行切分,这样就是按照句子边界,标点符号进行切分。这样保证了语句的完整性,但是我们切分的效率比较慢。适用于文章报告等
我们切分的时候要去按照场景进行选择
检索准确率:语义切分通常能确保每个Chunk包含完整的答案片段,从而提升准确率。
上下文利用率:合适的Chunk大小可以最大化利用模型的上下文窗口,不多也不少。
重叠比例 (Overlap):设置一部分重叠内容(如10%)可以防止重要信息在切分边界处丢失。
在Spring AI中,通常通过实现
DocumentTransformer
接口来定义切分逻辑。
检索策略:
密集检索,就是使用模型调用embed方法,然后调用向量库进行密集搜索。这样的话语义理解强,但是对罕见词汇搜索较差
bm25检索,传统的关键词匹配算法,对罕见词、专业术语友好,但缺乏语义理解。
混合检索,就待用密集检索和bm25检索,然后分析文档。结合了两种检索,但是复杂度增加了
上下文构建
检索到的文档片段不能直接丢给LLM,需要精心组织成“上下文”(Context),以避免噪声干扰。
1.如何避免上下文噪声干扰?
- 重排序 (Reranking):使用更轻量、但更精确的模型(如Cross-Encoder)对初步检索到的Top-K结果进行二次排序,将最相关的文档排在最前面。
- 上下文压缩 (Context Compression):从检索到的文档中提取与用户问题最相关的句子或摘要,丢弃无关信息,减少噪声。
- 分层检索 (Hierarchical Retrieval):对于结构化的长文档,可以先检索到相关的章节标题,再在章节内部进行精确检索。
- 动态上下文长度 (Dynamic Context Length):根据问题的复杂度和模型上下文窗口的限制,动态调整送入模型的文档数量。
在Spring AI中,这些策略通常在调用ChatModel
之前,通过自定义逻辑实现。
Function Calling
函数调用允许LLM将自然语言指令转化为对外部工具(API、数据库查询等)的结构化调用。
参数校验:这是安全的第一道防线。可以使用JSON Schema来定义函数期望的参数格式、类型和范围,在执行前进行严格校验。
安全机制
- 参数沙箱:绝不直接将用户输入用于代码执行或数据库查询,进行严格的无害化处理。
- 权限控制:根据用户身份,限制其能调用的函数集合。
- 执行隔离/超时:在独立、受限的环境中执行函数,并设置超时,防止恶意调用消耗系统资源。
- 审计日志:记录所有函数调用,便于追踪和分析。
错误处理:健壮的错误处理至关重要。需要明确处理参数验证失败(
ParameterValidationException
)、执行超时(ExecutionTimeoutException
)、资源超限(ResourceLimitException
)等情况,并设计合理的重试策略(如使用@Retryable
)先捕捉ParameterValidationException,参数验证
再捕捉ExecutionTimeoutException,执行超时
再捕捉ResourceLimitException,资源限制
然后再执行重试策略,加上重试注解
1
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
在Spring AI中,你可以定义一个@Bean
,通过@Description
注解描述其功能,Spring AI会自动将其注册为可供LLM调用的函数。
1 |
|
Agent
Agent是什么,是一个自主决策的智能体
如何设计多Agent协作的通信机制?
消息总线模式:
- 使用Redis/RabbitMQ作为消息中介
- Agent间异步通信
- 支持广播和点对点通信
协调者模式:
- 中央协调器管理任务分配
- Agent向协调器汇报状态
- 协调器负责冲突解决
契约式协作:
- 定义Agent间的服务契约
- 使用OpenAPI规范描述接口
- 支持版本管理和向后兼容
状态同步机制:
- 共享状态存储(Redis Cluster)
- 乐观锁处理并发冲突
- 事件溯源记录状态变更
决策树/状态机实现:
- 可以使用状态机来定义Agent的行为逻辑。例如,一个Agent的状态可以流转于:
IDLE
->PLANNING
->EXECUTING_TOOL
->WAITING_FOR_RESULT
->COMPLETED/ERROR
。每个状态转移都由特定的事件触发。这种方式使得Agent的行为清晰、可控、易于调试。
1 |
|
MCP
MCP是一个由Anthropic、OpenAI、Google等行业巨头共同支持的开放标准。你可以把它理解为AI世界的JDBC或JMS——它旨在标准化AI模型与外部工具、数据源进行交互的方式。
- MCP服务器 (MCP Server):任何外部工具、API或数据源(比如你的Spring Boot应用提供的服务)都可以通过实现MCP协议,将自己暴露为一个MCP服务器。它会“宣告”自己能提供哪些能力(如
查询订单
、读取文件
)。 - MCP客户端 (MCP Client):AI模型或代理(Agent)作为客户端,可以发现并连接到这些MCP服务器,使用标准化的请求/响应格式与之交互,而无需关心服务器底层的具体实现。
特性 | 传统函数调用 (Function Calling) | 模型上下文协议 (MCP) |
---|---|---|
本质 | 模型特定的API | 开放的、通用的通信协议 |
耦合度 | 高度耦合(与特定LLM提供商绑定) | 松耦合(与任何支持MCP的LLM兼容) |
互操作性 | 弱(切换模型成本高) | 强(工具可被不同模型复用) |
生态 | 封闭(各厂商各自为政) | 开放(促进工具和服务的生态系统) |
作为MCP客户端(消费工具)
- 在
application.yml
中配置需要连接的外部MCP服务器的地址。 - Spring AI将提供一个统一的
McpTemplate
或类似的客户端Bean。 - 我们的Agent通过这个
McpTemplate
来发现并调用外部工具。 McpTemplate
会将调用转化为标准的MCP请求,并发送给目标服务器。
我们如何去导入一个mcp呢在我的项目中?
如果是内部的,我直接写一个mcp工具即可,实现mcptool接口,继承抽象mcp基类
外部的我先导入依赖,中添加spring-ai-mistralai-spring-boot-starter
依赖
然后配置mcp服务器,在里面指定mcp的json配置
然后再spring ai中配置我们chatmodel的apikey
然后我们就可以使用注册好mcp的chatmodel,来完成使用mcp完成
Dify
Dify是一个开源的、一站式的LLM应用开发平台,极大降低构建和管理生产级生成式AI应用的门槛,让开发者可以更专注于业务逻辑,而不是费力地搭建和维护复杂的AI基础设施。
过去我们需要自己手动管理Prompt、对接不同的大模型、搭建RAG(检索增强生成)流程、处理对话历史等,而Dify将这些复杂繁琐的工作产品化、可视化了。
核心能力:
- 可视化的提示词编排 (Prompt Studio):提供一个图形界面,让开发者可以像填表格一样设计和调试Prompt,管理变量、上下文和模型输出。
- 内置的RAG引擎:允许用户直接上传文档(PDF, TXT, Markdown等),Dify会自动处理数据清洗、分块、向量化和索引,快速构建起一个可供检索的知识库。
- Agent能力:支持应用集成“工具 (Tools)”,让大模型可以调用外部API(如查询天气、搜索、计算等),完成更复杂的任务,而不仅仅是文本生成。
- 统一的API服务:一旦你在Dify上构建好应用,它会自动生成一套标准的API。你的前端或业务后端可以直接调用这个API,无需关心背后的大模型是哪个、RAG流程如何运作。
- 监控与分析:内置日志和数据分析功能,可以让你监控应用的调用情况、用户反馈、Token消耗等,方便持续运营和优化。
那么我们怎么构建一个dify,比如n8n工作流
1.创建新的应用
2.编排提示词,加入变量
3.构建RAG知识库,选择嵌入模型
4.调试程序问题
5.发布