news 2026/11/2 17:03:44

FEL 响应式大模型编程范式:从零接入 DeepSeek 的完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FEL 响应式大模型编程范式:从零接入 DeepSeek 的完整实战指南
  • 人工智能
  • 大模型
  • AI 应用
  • 后端
  • AI Agent
  • RAG
  • 流程编排
  • 微服务

【免费下载链接】fit-framework

FIT: 企业级AI开发框架,提供多语言函数引擎(FIT)、流式编排引擎(WaterFlow)及Java生态的LangChain替代方案(FEL)。原生/Spring双模运行,支持插件热插拔与智能聚散部署,无缝统一大模型与业务系统。

项目地址:https://gitcode.com/ModelEngine/fit-framework
点击查看免费下载

导读:本文以 FIT 开源框架中为大模型量身定制的 Java 响应式编程范式 FEL 为主线,从环境准备、依赖引入、application.yml配置到普通调用与流式调用的完整代码实现,带你一步步接入 DeepSeek(以及任何兼容 OpenAI API 的大模型)。读完本文,你将掌握 FEL 聊天模型(ChatModel)的核心用法、ChatOption全部参数语义、底层 OpenAI 适配器的实现原理,并了解基于AiFlows的智能应用编排方式,为后续构建 RAG、Agent 等复杂应用打下基础。

什么是 FEL:为 Java 量身定制的响应式大模型编程范式

FEL(Full-stack Easy-coded LLM framework)是 FIT 框架中面向 Java 生态的大模型应用开发套件。如果你熟悉 LangChain,可以把 FEL 看作是 Java 版本的 LangChain:它围绕大模型应用开发中反复出现的共性需求——模型接入、提示词模板、RAG 检索、记忆、输出解析、Agent——沉淀出一套响应式、可编排的编程范式。

与大多数"回调式"或"阻塞式"的大模型 SDK 不同,FEL 的每一次模型调用都返回一个响应式流对象Choir<T>(位于 Choir.java,表示拥有 0 到 N 个数据的发布者),调用方既可以阻塞式地取出最终结果,也可以让数据像流水一样持续流转,天然支撑流式输出、多轮会话与复杂流程编排。

本篇文章将从一个最小可运行的示例入手:接入当下热门的 DeepSeek 模型,完成普通调用与流式调用两种体验。

快速上手:在 FIT 工程中接入 DeepSeek

1. 准备环境与获取示例

  1. 获取 FIT-Framework 项目代码,参照项目中的入门指南部署 FIT 环境(FIT 的启动器、IoC 容器与 Web 服务能力是 FEL 示例的运行底座)。
  2. 本文配套的完整可运行示例位于 examples/fel-example/01-model,示例工程通过DemoApplication.main调用FitStarter.start启动(见 DemoApplication.java)。
  3. FEL 模块不仅支持 DeepSeek,还支持任何符合 OpenAI API 标准的模型服务,并在此基础上提供丰富的工具与大模型操作原语。

2. 在 pom.xml 中加入 FEL 依赖

在示例工程的 pom.xml 中,需要引入以下五类依赖:FIT 启动器、Web 插件启动器、HTTP 客户端、FEL 核心包以及 OpenAI 模型插件:

<dependencies> <dependency> <groupId>org.fitframework</groupId> <artifactId>fit-starter</artifactId> <version>${fit.version}</version> </dependency> <dependency> <groupId>org.fitframework</groupId> <artifactId>fit-plugins-starter-web</artifactId> <version>${fit.version}</version> </dependency> <dependency> <groupId>org.fitframework.plugin</groupId> <artifactId>fit-http-client-okhttp</artifactId> <version>${fit.version}</version> </dependency> <dependency> <groupId>org.fitframework.fel</groupId> <artifactId>fel-core</artifactId> <version>${fel.version}</version> </dependency> <dependency> <groupId>org.fitframework.fel</groupId> <artifactId>fel-model-openai-plugin</artifactId> <version>${fel.version}</version> </dependency> </dependencies>

其中fel-model-openai-plugin是 OpenAI 协议模型服务的适配实现(对应 fel-community 模块下的 model-openai),正是它让 FEL 能够对接 DeepSeek 以及硅基流动等兼容 OpenAI API 的平台。

3. 在 application.yml 中配置 DeepSeek 接入信息

在示例工程的resources/application.yml中配置 API 密钥、API 地址与模型名称:

fel: openai: api-base: 'https://api.siliconflow.cn/v1' api-key: 'your-api-key' example: model: 'deepseek-ai/DeepSeek-R1'

配置项说明:

  • fel.openai.api-base:大模型服务地址。示例使用的是硅基流动(SiliconFlow)平台地址,该平台提供一定免费额度,注册账号后创建API 密钥即可使用;如果你直接使用 OpenAI 官方服务,可替换为https://api.openai.com/v1/。
  • fel.openai.api-key:你的 API 密钥,将占位值your-api-key替换为真实密钥即可。
  • example.model:要调用的模型名称,示例中为硅基流动平台上的deepseek-ai/DeepSeek-R1。

从源码角度看,这些配置由 OpenAiConfig.java 通过@AcceptConfigValues("fel.openai")注解接收,其默认值为https://api.openai.com/v1/;同时支持自定义连接超时(connectTimeout,默认 30000ms)与读取超时(readTimeout,默认 30000ms),可用于调优请求慢场景下的超时表现。

4. 编写接入代码:普通调用与流式调用

示例控制器 ChatModelExampleController.java 展示了 FEL 最基础的两种大模型调用方式。

普通调用(一次性返回完整结果):

@Component @RequestMapping("/ai/example") public class ChatModelExampleController { private final ChatModel chatModel; @Value("${example.model}") private String modelName; public ChatModelExampleController(ChatModel chatModel) { this.chatModel = chatModel; } @GetMapping("/chat") public ChatMessage chat(@RequestParam("query") String query) { ChatOption option = ChatOption.custom().model(this.modelName).stream(false).build(); return this.chatModel.generate(ChatMessages.from(new HumanMessage(query)), option).first().block().get(); } }

流式调用(以 SSE 流形式逐步返回结果):

@GetMapping("/chat-stream") public Choir<ChatMessage> chatStream(@RequestParam("query") String query) { ChatOption option = ChatOption.custom().model(this.modelName).stream(true).build(); return this.chatModel.generate(ChatMessages.from(new HumanMessage(query)), option); }

理解这段代码的三个关键点:

  1. ChatOption指定调用参数:通过ChatOption.custom()...build()构建,其中.model(...)指定模型名称,.stream(true)表示以流式方式获取结果(见 ChatOption.java 的构建器入口)。
  2. generate发起一次模型调用:返回结果是一个响应式流对象Choir<ChatMessage>。普通调用时通过.first().block().get()阻塞取回第一条消息;流式调用时直接将Choir返回,FIT 框架会自动以 SSE 格式输出。
  3. ChatMessages.from(...)构造提示词:ChatMessages是Prompt接口的默认实现(见 ChatMessages.java),HumanMessage则封装用户输入的文本消息(支持携带多媒体Media列表,见 HumanMessage.java)。

ChatModel接口本身非常简洁——接收提示词与参数,返回聊天消息流,根据stream参数决定返回一条还是多条消息(见 ChatModel.java):

public interface ChatModel { Choir<ChatMessage> generate(Prompt prompt, ChatOption chatOption); }

5. 启动程序并验证

  1. 配置完成后,通过 IDEA 直接启动DemoApplication。
  2. 当控制台出现如下日志时,表示启动成功:
Start netty http server successfully.
体验普通调用

在浏览器输入示例请求地址:

http://localhost:8080/ai/example/chat?query=你好,DeepSeek

可以看到类似如下的 JSON 响应(toolCalls为空表示本次未触发工具调用):

{ "content": "<think>\n\n</think>\n\n你好!我是DeepSeek-R1,一个由深度求索公司开发的智能助手,我会尽我所能为你提供帮助。请问有什么可以为你服务的?", "toolCalls": [] }

注意响应中的<think>与</think>标签:DeepSeek-R1 这类推理模型会先输出"思考过程"再输出正式回答。FEL 的 OpenAI 适配器在 OpenAiModel.java 中专门对reasoning_content做了适配:非流式场景下将推理内容与最终回答拼装为<think>{0}</think>{1}格式返回。

体验流式调用

在浏览器输入示例请求地址:

http://localhost:8080/ai/example/chat-stream?query=你好,DeepSeek

浏览器会收到类似如下的 SSE 流式数据,内容逐段到达:

data:{"content":"<think>","toolCalls":[]} data:{"content":"\n\n","toolCalls":[]} data:{"content":"</think>","toolCalls":[]} data:{"content":"\n\n","toolCalls":[]} data:{"content":"你好","toolCalls":[]} data:{"content":"!","toolCalls":[]} data:{"content":"我是","toolCalls":[]} data:{"content":"Deep","toolCalls":[]} data:{"content":"Se","toolCalls":[]} data:{"content":"ek","toolCalls":[]} ...

流式模式下,FEL 的 OpenAI 适配器会读取服务端返回的每个 chunk,过滤掉结束标记[DONE],逐条反序列化为聊天消息后以响应式流逐段推送(见 OpenAiModel.java);对于推理模型,还会在第一个reasoning_contentchunk 前插入<think>标签、在第一个正式内容 chunk 前插入</think>标签(见 OpenAiModel.java),保证思考过程与回答的边界清晰可读。

深入解析 ChatOption:完整的模型调用参数

ChatOption是 FEL 中定义模型调用参数的统一入口(见 ChatOption.java)。除示例中已使用的model与stream外,它还提供了以下常用参数:

参数类型说明
modelString要调用的模型名称
streamBoolean是否使用流式接口;true为流式,false为普通接口
baseUrlString大模型服务端地址,可覆盖配置文件中的fel.openai.api-base
apiKeyString模型接口密钥,可覆盖配置文件中的fel.openai.api-key
maxTokensInteger生成文本的最大长度
frequencyPenaltyDouble频率惩罚系数,取值范围-2.0 ~ 2.0;正值惩罚已频繁出现的词以降低重复,抑制重复的合理取值约为0.1 ~ 1,最大可到2(可能影响输出质量),负值则会增加重复可能性
presencePenaltyDouble出现惩罚系数,取值范围-2.0 ~ 2.0;正值鼓励模型谈论新主题,默认0。与frequencyPenalty的区别在于:前者惩罚随 token 出现次数增加而不断加强,后者只区分"是否出现过"
stopList<String>停止字符串列表,模型输出中出现其中任一字符串即停止生成
temperatureDouble采样温度,取值范围0.0 ~ 2.0;值越高输出越随机多样,值越低输出越确定可预测
topPDouble采样率,取值范围0.0 ~ 1.0;例如0.1表示只考虑概率质量前 10% 的 token,与temperature不建议同时设置
toolsList<ToolInfo>模型可以使用的工具列表,用于支持 Function Calling / 工具调用
secureConfigSecureConfig调用大模型服务的 HTTPS 安全配置
extensionsMap<String, Object>扩展信息,用于透传额外参数

以baseUrl与apiKey为例,在 OpenAiModel.java 的generate实现中:若ChatOption显式指定了baseUrl/apiKey,则优先使用选项中的值,否则回退到配置文件中OpenAiConfig提供的默认值(StringUtils.blankIf(chatOption.apiKey(), this.defaultApiKey)),最终通过Authorization: Bearer <key>请求头发送密钥(见HttpUtils.setBearerAuth)。

底层原理:FEL 如何与 OpenAI 兼容服务交互

FEL 的模型接入遵循"接口定义 + 插件适配"的架构:核心层只定义抽象接口,具体模型服务由插件实现。

  • 接口层:ChatModel、ChatOption、Prompt、ChatMessage、MessageType等全部位于 fel-core 模块。其中ChatMessage定义了消息的type()、text()、medias()、toolCalls()等能力(见 ChatMessage.java),MessageType枚举覆盖SYSTEM、HUMAN、AI、TOOL四种角色(见 MessageType.java)。
  • 适配层:OpenAiModel.java 是一个@Component,同时实现了EmbedModel、ChatModel、ImageModel、RerankModel四个接口。聊天请求通过 FIT 的HttpClassicClient发送到{baseUrl}/chat/completions端点(见 OpenAiApi.java),请求体为OpenAiChatCompletionRequest,响应体反序列化为OpenAiChatCompletionResponse。
  • 流式处理:stream=true时通过request.exchangeStream(String.class)逐行读取 SSE 数据,过滤[DONE]标记后逐条反序列化并映射为Choir<ChatMessage>输出。

因此,只要目标平台(DeepSeek、Qwen、硅基流动等)提供兼容 OpenAI Chat Completions 协议的接口,都可以通过fel-model-openai-plugin无缝接入,这也是"一个适配器,处处可接入"的设计价值。

进阶视野:用 AiFlows 编排完整的智能应用

普通调用只是 FEL 的起点。FEL 真正的核心能力在于直观的编排方式——通过AiFlows以链式 API 组装"检索 → 生成 → 格式化"的完整 AI 流程。例如,一个包含知识库检索与大模型的智能助手编排代码如下:

AiProcessFlow<String, String> smartAssistantFlow = AiFlows.<String>create() .map(query -> Tip.from("query", query)) // 将用户输入转换为内部格式 .retrieve(new DefaultVectorRetriever(vectorStore)) // 检索相关信息 .generate(new ChatFlowModel(chatModel, chatOption)) // 调用大模型生成回答 .format(new JsonOutputParser(serializer, Response.class)) // 格式化输出 .close();

从源码看,AiFlows.create()会创建一个水流(WaterFlow)流程的头结点并包装为AiProcessFlow(见 AiFlows.java);AiProcessFlow在底层AiFlow之上增加了流程间数据流转能力,并对外提供对话语义(见 AiProcessFlow.java)。

其中每一步操作都是一个"原语"(operator):

  • retrieve:RAG 检索。DefaultVectorRetriever封装了VectorStore.search(query, searchOption)(见 DefaultVectorRetriever.java),从向量库中提取相关信息。
  • generate:大模型接入。ChatFlowModel把ChatModel与ChatOption包装为流程内可调用的模型节点(见 ChatFlowModel.java),调用时仍返回Choir<ChatMessage>响应式流。
  • format:输出解析。OutputParser<O>接口同时承担"给出格式化指令"(FormatProvider.instruction())与"把字符串解析为对象"(Parser<String, O>)两个职责(见 OutputParser.java),JsonOutputParser即其 JSON 实现。

FEL 提供的大模型操作原语

FEL 框架内置了丰富的大模型操作原语,覆盖智能应用的常见场景:

  • RAG 检索(retrieve):从海量数据中快速提取相关信息;
  • 提示词模板(prompt):通过预定义模板快速生成结构化输入;
  • 大模型接入(generate):无缝接入 DeepSeek 等大模型,实现智能对话与生成;
  • 记忆(memory):支持多轮对话记忆,提升对话体验;
  • Agent(delegate):通过智能体实现复杂任务的分解与执行。

这些原语之上还有通用的流操作原语,配合 FIT 框架"基于接口设计"的核心思想(多种原语操作均基于接口抽象),如果你有自定义功能,可以轻松集成自定义原语,打造专属智能应用。相关使用细节可继续阅读 FEL 指导手册中的 聊天模型使用 等章节。

小结

本文从 FEL 的定位讲起,完整演示了在 FIT 工程中接入 DeepSeek 的五个步骤:准备环境、引入依赖、配置application.yml、编写普通/流式调用代码、启动验证;随后深入ChatOption全部参数语义与OpenAiModel底层实现,最后展望了基于AiFlows的智能应用编排范式。从一次最简单的模型调用出发,你已经掌握了 FEL 响应式编程范式的核心脉络——后续文章将围绕 RAG、Agent、记忆等原语,继续展开这一"为大模型量身定制的响应式编程范式"的更多能力。

  • 人工智能
  • 大模型
  • AI 应用
  • 后端
  • AI Agent
  • RAG
  • 流程编排
  • 微服务

【免费下载链接】fit-framework

FIT: 企业级AI开发框架,提供多语言函数引擎(FIT)、流式编排引擎(WaterFlow)及Java生态的LangChain替代方案(FEL)。原生/Spring双模运行,支持插件热插拔与智能聚散部署,无缝统一大模型与业务系统。

项目地址:https://gitcode.com/ModelEngine/fit-framework
点击查看免费下载

相关推荐

上一篇:终极Draw.io ECE自定义形状库使用指南:快速上手电子工程绘图
下一篇:TotalSegmentator快速入门:医学图像分割的完整安装配置指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 15:49:33

OpenClaw 进阶调优实战:从部署完成到人剑合一的使用习惯养成

1. 从“能跑起来”到“用得顺手”的进阶思路1.1 为什么部署完成只是起点很多人把 OpenClaw 跑起来之后&#xff0c;第一反应是“终于搞定了”&#xff0c;然后就没有然后了。我见过太多这样的情况&#xff1a;环境装好了&#xff0c;服务也起来了&#xff0c;但真正要用的时候发…

作者头像 李华
网站建设 2026/10/25 12:10:40

Matplotlib数据可视化:从基础到高级的完整指南

1. 为什么Matplotlib是数据可视化的首选工具第一次接触数据可视化时&#xff0c;我被各种图表工具搞得眼花缭乱。直到一位资深数据科学家告诉我&#xff1a;"如果你只想学一个Python绘图库&#xff0c;那就选Matplotlib。"十年过去了&#xff0c;我依然认为这是最明智…

作者头像 李华
网站建设 2026/10/21 13:57:22

电商用户行为分析实战:从埋点采集到复购预测的源码骨架

简介&#xff1a;这是一份面向大数据分析与电商方向毕业设计的学习资源包&#xff0c;围绕淘宝用户行为数据展开&#xff0c;时间跨度为2017年11月25日至12月3日&#xff0c;记录量超过1亿条。内容涵盖数据导入、清洗、异常值处理&#xff0c;并借助Hive完成用户流量与购物情况…

作者头像 李华
网站建设 2026/10/23 12:41:38

ARM架构CentOS 7.6网口bond配置实战与避坑指南

1. 为什么在ARM架构的CentOS 7.6上做网口bond值得单独聊在x86服务器上配bond&#xff0c;很多人闭着眼睛都能敲完nmcli那几行命令。但一旦把同样的操作搬到ARM架构的CentOS 7.6上&#xff0c;事情就变得没那么顺滑了。我自己第一次在ARM机器上做网口聚合时&#xff0c;就遇到了…

作者头像 李华
网站建设 2026/10/23 10:20:39

多智能体编程实战:从单兵作战到团队协作的AI开发范式

1. 从"单兵作战"到"团队协作"&#xff1a;AI编程范式的拐点已经到来如果你最近半年一直在用AI辅助写代码&#xff0c;大概率会有一种微妙的感觉&#xff1a;工具越来越强&#xff0c;但瓶颈也越来越明显。单次对话能处理的上下文有限&#xff0c;复杂任务需…

作者头像 李华
网站建设 2026/10/22 6:43:47

AnyPS5跨平台串流方案:从原理到实操的完整技术解析

1. 从“AnyPS5”这个标题说起&#xff1a;它到底想解决什么问题第一次看到“AnyPS5”这个标题&#xff0c;我脑子里蹦出来的第一个念头是&#xff1a;这大概率是一个围绕“跨平台运行”“兼容层”“模拟环境”或者“远程串流”方向的项目。为什么这么判断&#xff1f;因为“Any…

作者头像 李华