阅读视图

发现新文章,点击刷新页面。

给Javaer看的大模型开发指南|得物技术

一、概述

伴随着大模型的性能提升、成本下降,在Web在线对话场景以外,大模型也越来越多的被集成到传统业务场景。

在大模型API交互模式、业务集成模式经百家争鸣现已趋于稳定的背景下,Spring作为Java生态里的OSS巨头也下场为LLM提供生态支持,于近期释出 spring-ai 正式版。

需要说明的是,Spring-AI 所提供的能力并不神秘,业务上也并非必须用Spring-AI不可。但是,就像过去Spring对新的数据库、新的中间件提供生态支持一样,Spring-AI提供了一套和Spring全家桶兼容并且语义一致、良好设计、易拓展的大模型交互的Java API,可以极大的降低LLM集成和开发的成本。

从大模型的工程化、实用化角度来说,当你厘清Spring-AI这一套API设施的逻辑后,事情最后还是会回归到业务开发人最熟悉的CRUD领域。就像使用Mybatis操作MySQL一样,我们会用 spring-ai 来操作大模型。

那我们开始今天的讨论吧!

二、什么是大模型

大模型的舞台上,从来不缺新面孔。自ChatGPT开启AI新纪元后,各类大模型层出不穷。

但是我们不去考虑大模型的训练原理、推理/运算架构、参数调优等较为复杂的数学范畴的东西,就像我们很少关心MySQL是怎么用代码来实现效果的一样。

此处类比我们熟悉的知识,对大模型有一个盲人摸象式的基础且能够自洽的认识即可。

  1. 从某种意义上来说,模型训练就是通过分析海量文本(如维基百科、图书、网页等)寻找到人类语言的规律,再将这个规律固化成一个包含数十亿【参数】的超级【数学公式】。就像简单公式 y = 5x + 8 中的 5 和 8 ,这两个【参数】决定了将输入X如何转化为输出Y。 
  2. 训练好的【数学公式】就像代码,需要部署在算力平台上,借助【显卡】的并行运算能力来实现高效运算。
  3. 用户的输入作为这个【数学公式】的入参,经公式运算后,得到相关的【输出】。

图片

假设大模型是上述的数学公式,不同的大模型「ChatGPT/DeepSeek」是不同的架构、不同的公式,那么模型训练就是通过对海量文本的分析、学习,找到合适的参数值。 

三、大模型的特点

接下来我们关注在工程应用场景下,需要开发人关注的大模型特点。

就像MySQL,我们集成时也需要关注不同的存储引擎(InnoDB/MyISAM)的特点。

无状态

图片

大模型是没有记忆、没有状态的,它是一个纯函数。

它不知道之前跟你说过什么。所以每次进行大模型输入的时候,我们需要根据业务场景把之前的【输入】,【反馈】一并给它,避免大模型失忆导致的对话不流畅。

图片

结构化输出

大模型是具备结构化输出能力的,虽然有些模型支持的不够好,但是没关系,只是支持的程度不同,重要的是它们都支持!

所谓的结构化输出是指,大模型除了可以返回口语化、没有模式的自然语言文本外,还可以按你需求给你返回其他的文本格式,比如:JSON。

图片

你看,这像不像在调一个REST接口?甚至是一个万能接口,毕竟大模型什么都会,不会的也可以现编。

图片

函数调用

其实看到这里我们就可以实现一个大模型驱动的RPC调用引擎了!

图片

大模型帮你推理、规划得到了需要执行的函数和对应的函数参数,至于这个【函数名】对应的到底是一个进程内的方法、HTTP接口、Dubbo接口还是MCP接口都没有那么重要,这只是智能体实现的一个技术细节而已。

我们可以用自然语言表述需求,同时告诉大模型有哪些辅助【工具/函数】可以供它备用。它会推理、编排这些工具来达成需求。

图片

  1. 把用户输入和可用函数输入给大模型,大模型推理发现需要调用外部函数,于是返回函数名+函数调用参数。
  2. 智能体捕获输出,对指定函数发起调用,再将用户输入和函数结果一起输入到大模型,大模型基于这些上下文推理输出结果。

考虑到大模型发起函数调用的普遍需求,大模型供应商一般都在API层面提供了【function call】能力,用于将文本输出和函数调用输出区分开,明白了原理,我们知道这只是API抽象层次的问题。

四、大模型接口

考虑到大模型对硬件资源的特别需求(如显卡),所以大模型一般是独立部署,以SaaS模式提供能力。就像MySQL对资源有特别的需求(如大内存),所以一般也是进行独立部署。

图片

训练好的大模型就是一套二进制数据集,SaaS化需要做外围的服务化、产品化封装,同一套模型可以在不同的算力平台部署,提供截然不同的服务化API。

模型封装

示例伪代码如下:

图片

我们可以简单看下当下比较热门的几大供应商提供的API文档:

  1. OpenAI-会话补全

    openai.apifox.cn/api-6788398…

  2. DeepSeek-会话补全

    api-docs.deepseek.com/zh-cn/api/c…

  3. 硅基流动-会话补全

    docs.siliconflow.cn/cn/api-refe…

  4. Ollama-会话补全

    www.runoob.com/ollama/olla…

硅基流动和Ollama都属于大模型算力/治理平台。他们不研发大模型,只是大模型的搬运工。可以把大模型理解成微服务集群,把硅基流动和Ollama理解成微服务构建/发布平台即可。

大概浏览一下,会发现核心API都差不多,毕竟有OpenAI珠玉在前,许多系统都已对接了OpenAI的API。后发的大模型为了兼容,降低接入难度,基本上也都和OpenAI的API大差不差。

就像是MySQL,尽管数据库产品类型百花齐放,但都兼容SQL语法。

我们在此只讨论【会话补全】这一点,会发现会话补全接口的输入/输出大概都是以下情况:

接口输入

{  "stream": false, // 是否是流式输出(要不要SSE)  "model""deepseek-chat"//选用的哪个模型  "messages": [ // 历史对话消息,因为大模型无状态,所以按场景提供一定数量的历史消息    {      "content""You are a helpful assistant",      "role""system"    },    {      "content""Hi"//消息内容      "role""user" //消息类型    }  ],  "tools": null, //外部函数列表,【函数调用】能力在 API 层面的支持  "frequency_penalty"0,  //无关紧要的模型行为控制参数  "presence_penalty"0//无关紧要的模型行为控制参数  "temperature"1//无关紧要的模型行为控制参数  "top_p"1//无关紧要的模型行为控制参数  "logprobs": false, //无关紧要的模型行为控制参数  "top_logprobs": null //无关紧要的模型行为控制参数}

这里以目标达成作为要点,内容中部分不理解的参数可以忽略。

接口输出

{  "id""<string>"//无关紧要  "choices": [    {      "message": {        "role""assistant",        "content""<string>"// 大模型生成的内容        "reasoning_content""<string>",        "tool_calls": [  //需要发起的【函数调用】          {            "id""<string>",            "type""function",            "function": {              "name""<string>",              "arguments""<string>"            }          }        ]      },      "finish_reason""stop" //有点重要,但是我们先不管    }  ],  "usage": {  //token使用量 计数、计费    "prompt_tokens"123,    "completion_tokens"123,    "total_tokens"123  },  "created"123,  //无关紧要  "model""<string>",  //无关紧要  "object""chat.completion"  //无关紧要}

看到这里时,你是不是已经开始跃跃欲试了?是不是感觉打造一个垂直领域的智能体没有想象中那么困难了~

五、RAG架构

除非是围绕特定业务场景结合私域数据训练的专用大模型,否则涉及到一些企业内部的私域信息时,通用大模型也只能不懂装懂的现编。

例如:当你询问大模型【DJob如何接入与使用】,除非训练大模型时输入了相关资料,不然大模型只能现编了。

考虑到专用大模型的成本,工程上解决这个问题的方法一般是通过外挂知识库来实现:

  1. 结合具体业务场景,将相关的文档与资料提前录入到【知识库】中。
  2. 用户提交一个【输入】后,先使用 用户【输入】作为搜索条件,去【知识库】中搜索得到相关的【资料】。
  3. 将用户【输入】和【资料】一起提供给大模型。

此【知识库】组件的具体选型属于实现细节,简单的可以用MySQL、Elasticsearch,如果想提升【知识库搜索结果】的匹配度,也可以使用近期讨论度很高的【向量数据库】。

添加了RAG后,流程如下:

图片

详情可参考下文:

www.zhihu.com/tardis/zm/a…

六、MCP协议

可以看到,将大模型作为一个【函数调用】的规划引擎,借助它的推理与生成能力,可以实现复杂的业务流程。如果说大模型是【脑】,那提供给大模型规划、使用的【函数】就是它的【手】和【脚】。有脑有手的大模型,可以迸发出巨大的业务潜力。

那如何打通大模型和传统软件系统(如存量微服务)呢?

我们关注的问题,开源社区也在积极的关注,这就是MCP协议诞生的背景和目的。

图片

MCP协议介绍

mcp-docs.cn/introductio…

在这里我们不展开MCP协议的细节,仅作个人对MCP协议的思考,重点在于打破MCP协议的神秘感、破除MCP迷信。

  1. MCP协议本身并非高精尖的内容,简单来说,就是常用人群约定系统间调用的流程、格式。若不考虑通用,谁都可以设计符合自己需求的、领域特定的交互协议。
  2. MCP协议的优势在于,它出现的非常及时,且基本满足了常规交互需求,因此快速在社区达成了共识。
  3. 不管是MAP、MBP还是MCP,都没有那么重要,但是形成共识非常重要。协议达成了共识,开源社区才可以合力围绕协议进行生态建设。

七、Spring-AI

到了这一步,我们开始探讨Java代码,首先我们需要熟悉下 spring-ai 的整套代码架构,一步一步来,以整体到到细节的节奏进行讨论。

模型抽象

核心的API实体是 Model ,是一个带泛型的纯函数,提供了对大模型能力的顶层抽象:

图片

org.springframework.ai.model.Model

大模型的能力本质就是:输入一个( request ),返回一个输出。

至于输入/输出的具体类型,由细分的子类限定:

图片

不同模态的大模型支持不同类型的输入/输出,在此我们只讨论 ChatModel 。

图片

org.springframework.ai.chat.model.ChatModel

图片

 spring-ai 提供了不同平台、不同模型的API集成,开发者只需要提供接口地址、调用凭证即可开箱使用~

聊天会话

考虑到大模型对话是热点场景, spring-ai 针对性的提供了会话接口抽象。

图片

org.springframework.ai.chat.client.ChatClient

RAG拓展

类似Spring-AOP, spring-ai 基于请求横切提供了开箱即用的RAG能力抽象。

图片图片

org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor

代码示例

基于供应商构建ChatModel

图片

构建ChatClient发起会话

图片

八、智能体示例

到这里,我们已经自上而下的理解了大模型的工程化,现在我们来开发一个【DJob智能助手】吧!

接口骨架

图片

通过 POST 接口,响应 Content-Type 为 text/event-stream 。

构造外部函数定义

假设有以下几个函数可以给大模型提供能力:

图片

将上述3个本地方法封装成 ChatClient API 认识的【ToolCallback】:

图片

构建可用的 函数/工具 信息,这里用本地方法来mock。实际使用时可以利用MCP/HTTP/gRPC/Dubbod等实现跨系统调用。

系统提示词

由于不能让大模型自由发挥,因此需要在用户输入的内容外,给大模型一些定向信息补充或场景限定,帮助大模型更好地解决问题!

图片

发起调用

图片

  1. 考虑到大模型无状态,所以每次会话时历史消息也需要一并输入。
  2. 历史消息可以由前端收集、提交,也可以由后端每次会话存储、收集。

九、总结

综上所述,太阳底下没有新鲜事,工程领域所有的新生事物都可以暂时把它当做MySQL,没有人比Java工程师更懂MySQL了(开玩笑)。

以上,除Java代码外,都是经过盲人摸象的方法探索出的内容。如有错误,欢迎指正。

往期回顾

1.一致性框架:供应链分布式事务问题解决方案|得物技术

2.Redis 是单线程模型?|得物技术

3.得物社区活动:组件化的演进与实践

4.从CPU冒烟到丝滑体验:算法SRE性能优化实战全揭秘|得物技术

5.CSS闯关指南:从手写地狱到“类”积木之旅|得物技术

文 / 羊羽

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

Cursor Rules优化实战:构建高效稳定的AI代码生成规范体系|得物技术

一、背景

随着AI辅助编程工具的普及,Cursor IDE已经成为越来越多开发者的选择。然而,在实际使用过程中,我们发现了一个关键问题:如何让AI真正理解项目需求并生成高质量、一致性的代码?

答案在于构建一套系统化的AI协作规范。与传统的代码规范不同,AI协作规范需要考虑更多维度:

  • 如何让AI准确理解业务逻辑和技术要求
  • 如何确保生成代码的架构一致性和质量标准
  • 如何在团队中推广和维护统一的开发模式
  • 如何避免规范冲突和维护成本过高的问题

本文将分享我们在Cursor Rules优化过程中的实践经验,展示如何从混乱的规范体系演进到清晰、高效的AI协作规范架构。

二、旧版Rules痛点

在优化之前,团队已有的规范体系存在三个核心问题,这些问题影响了AI代码生成的质量和效率。

问题一:规则冗余与表述模糊

旧规范存在大量无效描述,包括模糊要求(如"确保高性能")、重复定义和基础能力提示。这些冗余信息不仅增加token消耗,更分散AI注意力,显著降低代码生成效率。

问题二:提示词冲突

规范中角色定义混乱,不同文档将AI指定为架构师、开发者等矛盾角色。同时缺乏规则优先级机制,导致多规则同时生效时产生行为矛盾,无法形成明确执行路径。

问题三:维护困境

文档职责边界不清,新增规则时难以定位归属文件。修改单一功能需跨多文件调整,且规则间依赖关系不透明,造成维护成本指数级增长。

三、新版Rules设计理念

基于已有问题的深入分析,提出了一套新的设计理念,核心是:分层架构 + 职责分离 + 按需调用。

三层结构设计

新版本采用清晰的三层架构,每层都有明确的职责和边界:

图片

标准化规则格式

为了确保规范的一致性和可维护性,我们定义了统一的规则格式:

# 规则名称
## 基础规范- 明确的技术要求和实现标准
## 强制行为- 必须执行的具体操作和约束
## 禁止行为  - 严格禁止的操作和做法,需要避免的常见错误
## 示例代码- 具体的代码示例和最佳实践- 也通过 [文件名](mdc:路径) 引用外部示例

※  该格式优势

  • 结构清晰:每个部分的职责明确,便于AI理解。
  • 可执行性:强制/禁止行为都有明确的操作指导。
  • 示例驱动:用实际代码代替抽象描述。

AI协作执行协议

为了确保AI能够正确理解和执行规范,我们设计了一个明确的AI协作协议提示词:

图片

# AI协作执行规则
## 规则分类- basic/下的通用规则: 必须调用,通用基础规范- modules/下的模块规则: 按需调用,架构分层规范  - workflow/下的流程规则: 按需调用,业务场景规范
## 执行流程1. 识别场景 → 调用相关规则2. 读取示例代码 → 作为生成参考3. 执行强制/禁止行为 → 确保代码质量4. 应用设计原则 → 组件化、单一职责、分层设计
## 质量保障- 所有规则必须100%执行,重点关注强制行为和禁止行为

四、三层结构深度剖析

接下来我们详细分析新版本架构的设计特点和技术实现。

基础层的精细化设计

基础层是整个规范体系的根基,我们将原来混乱的MDC文件,精确拆分为7个职责单一的规范文件:

文件名 职责 核心内容
basic.mdc 项目基础规范 目录结构、技术栈、开发流程
code-quality.mdc 代码质量控制 复杂度限制、安全性要求
ts.mdc TypeScript规范 类型定义、严格模式配置
comment.mdc 注释规范 JSDoc格式、文件头注释
code-names.mdc 命名规范 变量、函数、组件命名约定
style.mdc 样式规范 CSS/Less编写标准
lint.mdc 代码检查 ESLint、Prettier配置

※  此拆分好处

  • 职责明确: 每个文件只关注一个特定领域。
  • 维护便利 修改某个规范不会影响其他领域。
  • 学习友好: 新人可以逐个理解每个规范的要求。

示例:code-quality.mdc定义了代码质量分规范:

# 代码质量分规范(通用规则)
## 强制行为
- 所有请求必须采用 HTTPS 协议- 确保第三方库安全可靠
## 禁止行为
- 代码复杂度限制  - 单个文件不得超过 500 行  - 条件复杂度不得超过 10  - 单个函数不得超过 199 行  - 超过限制时,应优先按功能模块拆分为多个函数或文件- 禁止使用非得物域名的外部 CDN 资源- 禁止在代码中包含明文密码或硬编码 token- 禁止出现敏感词- 避免重复代码块- 不允许单词拼写错误或不符合命名规范- 避免在前端直接进行金额计算(导致精度丢失)- 禁止使用魔数(如 a === '3'),应使用常量(如 a === statusMap.login)

模块层的分层设计

模块层的设计遵循前端分层架构思想,将复杂的应用拆分为职责明确的模块:

  • 表现层: components.mdc(组件规范)、pages.mdc(页面规范)
  • 业务逻辑层: hooks.mdc(状态管理)、utils.mdc(工具函数)
  • 数据服务层 service.mdc(API接口**)、constants.mdc(配置管理)
  • 路由层 route.mdc(路由配置和导航)

示例:服务层规范(service.mdc)规范定义了API接口的标准化开发流程:

# API接口生成规范(模块规则)
## 存放位置规范(按优先级)- [p0] 页面级API:src/pages/{pageName}/services/{modules}.ts- [p1] 全局API:src/services/{modules}.ts- 类型文件:对应的 .interface.ts 文件
## 标准代码模板```import { request } from '@/utils/request';import { UniversalResp } from '@/utils/request-operation';import { IUserListReq, IUserListDataRes } from './interface';
/** * 获取用户列表 * @param data 请求参数 */export const fetchUserListApi = async (data: IUserListReq) => {  return request.post<UniversalResp<IUserListDataRes>>(    '/api/user/list',    data  );};```## 强制行为- 使用MCP Server的mooncake_get_api_details工具获取接口详情- 响应数据必须使用UniversalResp<T>泛型包装- 接口命名采用fetch{ApiFileName}Api格式- 类型定义必须完整,包含完整字段注释

流程层的场景化设计

流程层是当前架构的创新点,针对具体业务场景定制化规范,将复杂的业务场景标准化。

流程文件 业务场景 核心功能
curd-page.mdc curd页面开发 curd页面完整使用流程
log.mdc 错误监控 APM监控和错误日志处理流程
sendBuried.mdc 数据埋点 用户行为埋点的标准流程
......

示例: curd-page.mdc 定义了完整的表格页面开发流程:

图片

※  该流程确保

  • 开发效率: 标准化流程减少决策时间。
  • 质量一致性: 所有表格页面都遵循相同的标准。
  • 维护性: 统一的结构便于后期维护。
# pro-table生成新页面(流程规则)深入研究代码并理解[insert feature]是如何工作的。一旦你明白了,让我知道,我将提供我的任务给你。
##  工作流程按以下流程进行任务执行,如果评估存在非必须流程,可跳过。- MCP读取接口信息- 从用户输入中提取以下信息:   - 列表名称   - 筛选项(需标记hideInTable)   - 展示项(需标记hideInSearch)   - 操作项   - 工具栏按钮- 评估完整的需求内容复杂度,考虑未来的扩展性,合理设计分层目录结构    - 各个模块保持单一职责,考虑合理的业务组件拆分,避免大量代码都在页面主入口文件    - 使用命令行批量创建目录文件(包含各类文件ts、tsx、less等)    - 文件暂不生成代码- 配置页面的路由信息- 生成类型文件,确保所有类型定义清晰- 生成constants文件,定义所需常量- 生成services文件,实现数据服务- 生成所需的 hooks 文件- 生成页面(必需)和components(如需)文件 完成UI层
## 强制行为- 使用pro-table进行开发,包括筛选表单,符合最佳实践- 筛选项和列表项配置创建useColumns.tsx声明,筛选项(需标记hideInTable)、展示项(需标记hideInSearch)- 左侧字段按需固定,操作项右侧固定,最多显示两个,超出折叠显示- 文本左对齐,数字右对齐,状态枚举居中显示- 分页设置支持10、20、50、100- .....
# 禁止行为.....

五、最佳实践

快速开始

第一步:创建基础架构

.cursor/rules/├── ai.mdc              # AI协作总纲├── basic/              # 基础规范目录│   ├── basic.mdc│   ├── code-quality.mdc│   ├── ts.mdc│   ├── style.mdc│   ├── comment.mdc│   ├── code-names.mdc│   └── lint.mdc├── modules/            # 模块规范目录│   ├── components.mdc│   ├── pages.mdc│   ├── hooks.mdc│   ├── service.mdc│   ├── constants.mdc│   ├── utils.mdc│   └── route.mdc└── workflow/           # 流程规范目录    ├── curd-page.mdc    ├── log.mdc    └── send-buried.mdc    └── ......

第二步:配置AI协作协议

在 ai.mdc 中定义核心协作规则:

# AI协作执行规则
## 规则分类- basic/下的通用规则: 必须调用,通用基础规范- modules/下的模块规则: 按需调用,架构分层规范  - workflow/下的流程规则: 按需调用,业务场景规范
## 执行流程1. 识别场景 → 调用相关规则2. 读取示例代码 → 作为生成参考3. 执行强制/禁止行为 → 确保代码质量4. 应用设计原则 → 组件化、单一职责、分层设计
## 质量保障所有规则必须100%执行,重点关注强制行为和禁止行为

分阶段实施计划

阶段 目标 关键活动
试点阶段 验证规范有效性 选择1-2个项目试点,收集反馈
优化阶段 完善规范内容 根据试点反馈优化规范,开发工具
标准化阶段 形成团队标准 制定团队级标准,持续改进机制

六、总结

基于以下设计思路,并通过构建三层架构的AI协作规范体系:

  • 单一职责:每个规范文件只负责一个功能领域,规则维护简单,冲突减少。
  • 分层架构:基础→模块→流程的清晰层级,规则依赖明确,扩展容易。
  • 按需调用:根据开发场景智能调用相关规范,使得上下文信息精准,效率提升。
  • 示例驱动:用代码示例代替抽象描述,AI理解准确,执行到位。
  • 持续进化:支持规范的迭代优化和扩展,研发适应变化,持续改进。

我们成功缓解了AI辅助编程中的核心问题,这套方法论不仅适用于Cursor Rules,更可以推广到其他AI协作工具的规范设计中。在AI辅助编程快速发展的今天,构建一套清晰、系统化的协作规范,将是每个开发团队的核心竞争力。

往期回顾

1.一致性框架:供应链分布式事务问题解决方案|得物技术

2.Redis 是单线程模型?|得物技术

3.得物社区活动:组件化的演进与实践

4.得物研发自测 & 前端自动化测试体系建设

5.从CPU冒烟到丝滑体验:算法SRE性能优化实战全揭秘|得物技术

文 / 阳凯

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

❌