nb-chatbi 后端开发规范

nb-chatbi 后端开发规范

版本 : 1.0

更新日期 : 2026-06-25

适用范围 : apis、resources、gates、techs、code-generator 模块

技术栈: Java 21 · Spring Boot 3 · nbsaas-boot 4.0.5 · LangChain4j 1.16.3 · MySQL / PostgreSQL


1. 总则

1.1 设计原则

  • 分层清晰:API 定义、业务实现、HTTP 入口、AI 能力分别放在独立模块,禁止跨层直接访问数据库。
  • Resource 唯一 :禁止使用 Service 概念 (不得新建 XxxService 类或 service/ 包)。所有业务实现统一为 XxxResource / XxxExtResource,Controller 只注入 Api 接口。
  • 统一接口契约 :所有 Api / ExtApi / Controller 对外方法仅允许一个入参 ,类型必须以 Request 结尾;返回值只能是 ListResponse<T>、ResponseObject<T>、PageResponse<T> 三者之一。
  • Agent Pipeline 优先 :复杂 AI 流程在 ai4j 中通过 Pipeline 编排,Agent 不直连数据库,详见 §7。
  • 生成优先 :标准 CRUD 走代码生成器,手写代码只放在 ext 包的 ExtResource 中。
  • 不可篡改生成物 :代码生成器产出的文件会被重复覆盖,禁止手动修改。
  • 扩展走 Ext :超出 CRUD 的业务逻辑,通过 ExtApi + ExtResource 扩展,不在基础层追加代码。
  • 最小改动:新增功能优先复用已有 Api、MapperExt、Resource,保持与现有代码风格一致。

1.2 开发流程(标准业务)

复制代码
需求整理(documents/)
    ↓
设计实体类(resources/.../data/entity/)
    ↓
编写/更新 code-generator 配置(config/*.yml)
    ↓
运行代码生成器(App.main)
    ↓
如有特殊逻辑 → 编写 ExtApi / ExtResource / XxxMapperExt
    ↓
在 gates/admin 编写 Controller(仅 HTTP 入口,调用 Api / ExtApi)
    ↓
联调 & 提交

2. 项目结构

2.1 模块总览

复制代码
nb-chatbi/
├── apis/                          # API 契约层(接口 + DTO)
│   └── business-api/
├── resources/                     # 业务实现层(Entity / Repository / Resource / Mapper)
│   └── business-resource/
├── gates/                         # 应用入口 & HTTP 层
│   └── admin/                     # Spring Boot 启动模块(AdminApplication)
├── techs/                         # 技术能力模块(与业务解耦)
│   └── ai4j/                      # LangChain4j AI 集成
├── code-generator/                # 代码生成器
└── documents/                     # 需求、SQL、设计文档

2.2 模块依赖关系

复制代码
gates/admin
    ├── business-resource
    │       └── business-api
    └── ai4j
            └── pipeline / langchain4j

规则:

模块 允许依赖 禁止依赖
business-api nbsaas-boot rest business-resource、gates、ai4j
business-resource business-api、JPA、MyBatis gates
gates/admin business-resource、ai4j、Shiro 等 不应直接操作 Entity / Repository
ai4j LangChain4j、pipeline gates、business-resource(保持技术层独立)

2.3 包结构约定

以业务域 chatbi 为例:

复制代码
com.nbsaas.boot.chatbi
├── api/                           # 【生成】基础 API 契约
│   ├── apis/                      # XxxApi 接口(extends BaseApi)
│   └── domain/
│       ├── field/                 # XxxField 字段常量
│       ├── request/               # 均以 Request 结尾
│       ├── response/              # XxxResponse(作为泛型 T,不直接作 Api 返回值)
│       └── simple/                # XxxSimple(列表/搜索轻量对象)
├── ext/                           # 【手写】扩展 API
│   ├── apis/                      # XxxExtApi
│   └── domain/
│       ├── request/               # XxxXxxRequest(扩展请求)
│       └── response/              # XxxXxxResponse(扩展响应)
├── data/                          # 【生成 + 手写 MapperExt】
│   ├── entity/                    # JPA 实体(手写,供生成器读取)
│   ├── repository/                # JPA Repository(生成)
│   └── mapper/                    # XxxMapper(生成,禁止修改)/ XxxMapperExt(手写)
└── rest/                          # 【生成】基础 Resource 实现
    ├── resource/                  # XxxResource implements XxxApi
    └── convert/                   # EntityConvert / ResponseConvert / SimpleConvert

gates/admin 中的包结构(仅 HTTP 入口,不含业务实现):

复制代码
com.nbsaas.boot
├── AdminApplication.java          # 启动类
├── config/                        # Spring / Shiro / MyBatis 配置
├── controller/
│   ├── chatbi/                    # 业务 Controller
│   ├── agent/                     # AI Agent HTTP 入口
│   ├── user/                      # 用户相关
│   └── system/                    # 系统配置
├── interceptor/                   # 拦截器
├── advice/                        # 请求体解密等 Advice
└── utils/                         # 工具类

注意 :gates/admin 中历史遗留的 service/ 包(如 ChatAiService)不符合本规范,新功能不得沿用该模式;复杂编排应下沉到 business-resource 的 ext/resource/。


3. 实体与代码生成

3.1 实体类规范

实体类位于 resources/business-resource/.../data/entity/,是唯一允许手写的持久层定义。

java 复制代码
@Data
@FormAnnotation(title = "ChatBI会话", model = "ChatBI会话")
@Entity
@Table(name = "chat_bi_session", comment = "ChatBI会话")
public class ChatBiSession extends AbstractEntity {

    @FormField(title = "会话Key", sortNum = "1", grid = true)
    @Column(length = 64, unique = true, nullable = false)
    private String sessionKey;

    // ...
}

命名与注解要求:

项 规范
类名 大驼峰,与表名语义对应,如 ChatBiSession
表名 小写下划线,如 chat_bi_session
基类 继承 AbstractEntity(含 id、addDate、lastDate 等公共字段)
注解 必须加 @FormAnnotation、@FormField 供生成器与后台表单使用
布尔字段 使用 Boolean,命名如 deletedFlag、archived
大文本 使用 @Lob,必要时 @Basic(fetch = LAZY)

3.2 代码生成器配置

配置文件位于 code-generator/src/main/resources/config/,示例:

yaml 复制代码
projectName: business
moduleName: chatbi
multiple: true
templateDir: /template/jpa
entityPackage: com.nbsaas.boot.chatbi.data.entity
entities:
  - ChatBiSession
  - ChatBiMessage
outputPath: E:\codes\nb\nb-chatbi    # 改为本机项目根路径
basePackage: com.nbsaas.boot

运行方式:

bash 复制代码
# 在 code-generator 模块下运行 App.main
# 默认读取 config/chatbi.yml,也可传入参数指定配置文件
java com.nbsaas.boot.App config/customer.yml

生成产物清单(每个 Entity 一套):

  • api/apis/XxxApi.java
  • api/domain/{field,request,response,simple}/
  • rest/resource/XxxResource.java
  • rest/convert/Xxx*Convert.java
  • data/repository/XxxRepository.java
  • data/mapper/XxxMapper.java + mapper/chatbi/XxxMapper.xml(禁止修改)
  • 自定义 SQL 另建 data/mapper/XxxMapperExt.java + mapper/chatbi/XxxMapperExt.xml(手写)
  • gates/admin/controller/.../XxxController.java
  • ext/apis/XxxExtApi.java(空壳,供扩展)
  • ext/resource/XxxExtResource.java(空壳,供扩展)

重要 :以上生成文件均不可手动修改。需要定制 SQL 时,新建 XxxMapperExt,禁止 向生成的 XxxMapper 追加方法。

3.3 新增业务模块 Checklist

  1. 在 documents/ 整理需求文档
  2. 创建 Entity 类及数据库 DDL(documents/sqls/ 或独立 .sql)
  3. 新增 code-generator/.../config/xxx.yml
  4. 执行代码生成器
  5. 在 ext 中实现特殊业务(如有)
  6. 在 ext/resource/ 实现复杂业务 Resource,在 gates/admin 编写 Controller
  7. 如需 Vue 页面,使用 VueApp + vue/xxx.yml 生成前端代码

4. API 层规范(apis/business-api)

4.0 统一接口契约(强制)

适用于 BaseApi、ExtApi、Resource、ExtResource、Controller 对外暴露的所有方法。

入参
规则 说明
参数个数 仅允许 1 个
命名 必须以 Request 结尾,如 ChatBiSessionListRequest
禁止 多参数、@PathVariable / @RequestParam 传递业务字段(见下方例外)
GET 无参 使用空 Request 或 XxxQueryRequest / XxxMetaRequest

常见 Request 命名:

场景 命名示例
创建/更新/删除/详情 XxxRequest
不分页列表 XxxListRequest
分页查询 XxxSearchRequest 或 XxxPageRequest
扩展业务动作 XxxAccessRequest、XxxAnalyzeRequest

代码生成器历史产物中的 XxxSearch 不符合 本规范;新接口不得再使用 XxxSearch 命名 ,应改为 XxxSearchRequest 或 XxxListRequest。

返回值

只允许 以下三种包装类型,业务数据放在泛型 T 中:

返回类型 用途
ResponseObject<T> 单对象:create / view / update / 业务动作
ListResponse<T> 不分页列表
PageResponse<T> 分页列表

禁止 直接返回 XxxResponse、List<T>、Map、void、Boolean 等裸类型。

错误示例与正确写法:

java 复制代码
// ❌ 禁止
ChatBiSessionResponse view(Long id);
List<ChatBiSessionSimple> sessions(ChatBiSessionListRequest request);
MetaResponse meta();

// ✅ 正确
ResponseObject<ChatBiSessionResponse> view(ChatBiSessionViewRequest request);
ListResponse<ChatBiSessionSimple> sessions(ChatBiSessionListRequest request);
ResponseObject<ChatBiMetaResponse> meta(ChatBiMetaRequest request);

错误时统一使用:

java 复制代码
return ResponseObject.error(401, "未登录");
return ResponseObject.error(403, "权限不足");
return ResponseObject.error(404, "会话不存在");
return ResponseObject.error(406, "参数不合法");
return ResponseObject.error(500, "Token 预扣失败");   // 业务异常码从 500 起

错误码分段:

码段 含义
200 成功
401 未认证(未登录、Token 失效)
403 无权限(鉴权失败、越权访问)
404 资源不存在
406 参数不合法(校验失败、缺少必填项)
500+ 业务/系统异常码 ,从 500 开始递增,由模块统一定义

401 / 403 通常由 Shiro 或全局异常处理器(ExceptionHandle)统一返回;业务代码中主动返回时须与上表语义一致。禁止 占用 500 以下码段表示业务失败。

流式接口例外

SSE / WebSocket 推送 endpoint 可返回 SseEmitter 等 Spring 流式类型,但准备数据的 Api / ExtApi 仍必须遵守单 Request 入参与三件套返回值。

4.1 基础 API

基础 API 由生成器产出,继承 BaseApi<Response, Simple, Request>:

java 复制代码
public interface ChatBiSessionApi extends BaseApi<
        ChatBiSessionResponse,
        ChatBiSessionSimple,
        ChatBiSessionRequest> {
}

内置能力:create、update、delete、view、list、search(均由 BaseResource 实现,返回三件套包装类型)。

生成器产出的 list / search 入参为 XxxSearch,属历史命名;ExtApi 及手写接口不得沿用 ,查询类入参一律以 Request 结尾。

4.2 扩展 API(ExtApi)

扩展接口手写 于 ext/apis/,必须完整遵守 4.0 统一接口契约:

  • 每个方法仅 1 个 以 Request 结尾的入参对象
  • 返回值只能是 ResponseObject<T>、ListResponse<T> 或 PageResponse<T>
  • 接口定义在 apis 模块,实现在 resources/.../ext/resource/
java 复制代码
public interface ChatBiSessionExtApi {

    ListResponse<ChatBiSessionSimple> sessions(ChatBiSessionListRequest request);

    ResponseObject<ChatBiSessionDetailResponse> session(ChatBiSessionAccessRequest request);

    ResponseObject<ChatBiSessionResponse> ensureSession(ChatBiConversationRequest request);
}

4.3 DTO 命名

类型 命名 用途
Request XxxRequest 增删改查、详情查询(含 id 等条件)
ListRequest XxxListRequest 不分页列表查询条件
SearchRequest XxxSearchRequest 分页 / 高级搜索条件(禁止 使用 XxxSearch)
Response XxxResponse 业务数据体,作为 ResponseObject<T> 的 T
Simple XxxSimple 列表项,作为 ListResponse<T> / PageResponse<T> 的 T
Field XxxField 字段名常量,供 Filter 使用
Ext Request XxxXxxRequest 扩展场景专用请求(必须以 Request 结尾)
Ext Response XxxXxxResponse 扩展场景专用响应体(作为泛型 T,不直接作 Api 返回值)

5. 资源层规范(resources/business-resource)

5.1 基础 Resource

生成类继承 BaseResource,实现对应 XxxApi:

java 复制代码
@Transactional
@Service
public class ChatBiMessageResource
        extends BaseResource<ChatBiMessage, ChatBiMessageResponse, ChatBiMessageSimple, ChatBiMessageRequest>
        implements ChatBiMessageApi {

    @Resource
    private ChatBiMessageRepository chatBiMessageRepository;

    @Override
    public JpaRepositoryImplementation<ChatBiMessage, Serializable> getJpaRepository() {
        return chatBiMessageRepository;
    }
    // getConvertSimple / getConvertForm / getConvertResponse ...
}

基础 Resource 只做标准 CRUD;复杂业务编排一律放在 ExtResource,不得 在 gates 层新建 Service 类。

5.2 扩展 Resource(ExtResource)

  • 使用 @Service + @Transactional
  • 通过 @Resource 注入基础 XxxApi,而非直接操作 Repository(除非有性能原因需自定义 SQL)
  • 复杂查询通过 XxxMapperExt 实现,禁止 修改生成的 XxxMapper
java 复制代码
@Service
@Transactional
public class ChatBiSessionExtResource implements ChatBiSessionExtApi {

    @Resource
    private ChatBiSessionApi chatBiSessionApi;

    @Resource
    private ChatBiSessionMapperExt chatBiSessionMapperExt;

    @Override
    public ListResponse<ChatBiSessionSimple> sessions(ChatBiSessionListRequest request) {
        // 参数校验 → 调用 MapperExt / Api → 封装 ListResponse
    }
}

5.3 MyBatis Mapper

生成 Mapper(禁止修改)
项 规范
接口 data/mapper/XxxMapper.java
XML resources/mapper/{module}/XxxMapper.xml
来源 代码生成器产出
约束 禁止手动增删改
自定义 MapperExt(手写)

超出生成能力的复杂查询、批量更新,必须新建 Ext 接口,命名规则:

复制代码
<实体类名>MapperExt

示例:ChatBiSession → ChatBiSessionMapperExt

项 规范
接口 data/mapper/XxxMapperExt.java
XML resources/mapper/{module}/XxxMapperExt.xml
注解 @Mapper
方法命名 selectXxx、updateXxx、insertXxx、deleteXxx
参数 使用 @Param 注解
返回 优先返回 Simple 或基础类型,避免直接返回 Entity
调用方 仅在 ExtResource 中注入使用
java 复制代码
@Mapper
public interface ChatBiSessionMapperExt {

    List<ChatBiSessionSimple> selectBasicList(@Param("userId") Long userId,
                                              @Param("includeArchived") Boolean includeArchived,
                                              @Param("limit") Integer limit);
}

6. 网关层规范(gates/admin)

6.1 Controller 分类

类型 位置 职责
生成 Controller controller/{module}/XxxController 标准 CRUD,带 Shiro 权限
业务 Controller controller/chatbi/ChatBiController 面向产品的复合 API
Agent Controller controller/agent/* AI 能力 HTTP 入口

6.2 生成 Controller 规范

java 复制代码
@RequiresAuthentication
@RestController
@RequestMapping("/chatBiMessage")
public class ChatBiMessageController {

    @Resource
    private ChatBiMessageApi chatBiMessageApi;

    @RequiresPermissions("chatBiMessage:search")
    @SearchData
    @PostMapping("/search")
    public PageResponse<ChatBiMessageSimple> search(@RequestBody ChatBiMessageSearchRequest request) {
        return chatBiMessageApi.search(request);
    }

    @RequiresPermissions("chatBiMessage:view")
    @PostMapping("/view")
    public ResponseObject<ChatBiMessageResponse> view(@RequestBody @Validated(ViewOperator.class) ChatBiMessageRequest request) {
        return chatBiMessageApi.view(request);
    }
}

约定:

  • 路径:小驼峰实体名,如 /chatBiMessage
  • 方法:统一 POST(/create、/update、/delete、/view、/list、/search)
  • 入参 :每个接口仅 @RequestBody 一个 XxxRequest,禁止多参数
  • 返回值 :仅 ResponseObject<T> / ListResponse<T> / PageResponse<T>
  • 权限:{entityName}:{action},如 chatBiMessage:create
  • 校验:@Validated(AddOperator.class) 等分组校验

6.3 业务 Controller 规范

面向 ChatBI、AI Chat 等复合场景:

  • 路径使用业务语义,如 /chatbi、/aichat
  • 只注入 Api / ExtApi ,禁止注入 Resource 实现类,禁止注入 Service
  • 复杂编排逻辑放在 business-resource/.../ext/resource/ 的 ExtResource 中
  • Controller 仅做参数接收、权限校验、调用 Api、原样返回三件套;禁止在 Controller 内拆解包装类型后再裸返回
  • 入参/返回值遵守 4.0 统一接口契约
  • 权限使用 @RequiresUser 或细粒度 @RequiresPermissions
java 复制代码
@RequiresUser
@RestController
@RequestMapping("/chatbi")
public class ChatBiController {

    @Resource
    private ChatBiSessionExtApi chatBiSessionExtApi;

    @Resource
    private ChatBiAnalyzeExtApi chatBiAnalyzeExtApi;

    @PostMapping("/sessions")
    public ListResponse<ChatBiSessionSimple> sessions(@RequestBody ChatBiSessionListRequest request) {
        return chatBiSessionExtApi.sessions(request);
    }

    @PostMapping("/analyze")
    public ResponseObject<ChatBiAnalyzeResponse> analyze(@RequestBody ChatBiAnalyzeRequest request) {
        return chatBiAnalyzeExtApi.analyze(request);
    }
}

6.4 业务 Resource(ExtResource)

所有非 CRUD 业务逻辑均在 business-resource 的 ext/resource/ 中实现,命名 XxxExtResource:

  • 多 Api 编排
  • AI 调用封装:在 ExtResource 中启动 Pipeline(ai4j),禁止在 ExtResource 内手写多步 Agent 逻辑
  • 流式 SSE 所需的业务数据准备
  • Token 预扣/结算、会话持久化等复合操作

规则:

  • 实现对应 XxxExtApi 接口,方法签名与 ExtApi 一致(单 Request 入参、三件套返回)
  • 使用 @Service(Spring 注解)+ @Transactional 注册 Bean
  • 通过 @Resource 注入其他 XxxApi / XxxExtApi;需自定义 SQL 时注入 XxxMapperExt,禁止 注入或修改生成的 XxxMapper
  • 禁止 新建 XxxService 或在 gates 下建 service/ 包

7. Agent 规范(techs/ai4j)

底层统一采用 Pipeline 模式。所有复杂 Agent 流程必须通过 Pipeline 编排,禁止在 Controller / Resource 中手写多步 LLM 调用链。

7.1 模块定位

ai4j 是纯技术层,封装 LangChain4j、Pipeline、Agent 能力:

  • 不依赖 gates 或 business-resource
  • 不直接访问 数据库;持久化、Token、会话等通过 Tool → Api / ExtApi → Resource 间接完成
  • 需要 Spring 编排时,由 business-resource/ext/resource/ 中的 ExtResource 调用 Pipeline,自身不含 Agent 逻辑

7.2 核心原则

原则 说明
Pipeline 优先 所有复杂 Agent 流程必须通过 Pipeline 编排
Agent 不直接操作数据库 只能通过 Tool / Api / Resource 间接访问
每一步可观测 Pipeline Step 必须记录输入、输出、耗时、状态
每一步可恢复 长流程支持中断恢复、失败重试
计划与执行分离 Planner 只生成计划,Executor 只执行动作
执行后必须校验 关键动作必须经过 Verifier 校验
最终统一报告 Reporter 负责生成用户可读结果

7.3 目录结构

目标包结构(新 Agent 必须 按此组织;历史包如 agentos/ 逐步迁移):

复制代码
techs/ai4j
└── com.nbsaas.boot.ai
    ├── agent/                 # Agent 定义(按场景分子包)
    ├── pipeline/              # Pipeline 引擎与 Step 编排
    ├── planner/               # 计划生成(Planner / PlanValidator)
    ├── executor/              # 执行器(PipelineExecutor / ToolExecutor)
    ├── verifier/              # 结果校验
    ├── memory/                # 记忆读写(MemoryWriter / MemoryReader)
    ├── tool/                  # 工具定义与注册
    ├── skill/                 # 技能封装
    ├── report/                # 报告生成(Reporter)
    ├── context/               # 上下文(ContextBuilder / SharedContext)
    └── schema/                # JSON Schema / Prompt Schema
包 职责
agent/ 场景 Agent 入口,组装 Pipeline,不含数据库代码
pipeline/ Pipeline 定义、Step 接口、运行器、Step 注册
planner/ 根据意图与上下文生成 Plan,PlanValidator 校验计划合法性
executor/ 按计划逐步执行 Tool / 子 Pipeline
verifier/ 校验 SQL、DSL、Tool 输出、业务规则
memory/ Session / 长期记忆读写
tool/ LangChain4j Tool 或自定义 Tool,内部调用 Api
skill/ 可复用技能单元,供 Planner 选用
report/ 汇总 Pipeline 结果,生成用户可读回复
context/ AgentContext、上下文键、ContextBuilder
schema/ Prompt 模板、JSON Schema、结构化输出约束

7.4 标准 Agent 流程

所有 Agent 统一采用以下逻辑链路(对应组件职责,非替代 Pipeline Step):

复制代码
UserRequest
    ↓
IntentRouter          意图识别
    ↓
ContextBuilder        构造上下文(历史、记忆、租户、权限)
    ↓
Planner               生成计划(Plan)
    ↓
PlanValidator         校验计划(权限、工具白名单、SQL 安全)
    ↓
PipelineExecutor      执行 Pipeline
    ↓
ToolExecutor          调用工具(Api / SQL / 搜索等)
    ↓
Verifier              结果校验
    ↓
MemoryWriter          写入记忆
    ↓
Reporter              生成用户可读回复

职责边界:

组件 可做 不可做
IntentRouter 分类意图、路由到 Agent 执行 Tool、写库
Planner 输出结构化 Plan 调用 LLM 以外的副作用
PlanValidator 拦截非法计划 修改 Plan 内容(应拒绝并返回错误)
PipelineExecutor 按序调度 Step 绕过 Verifier 直接返回
ToolExecutor 调用已注册 Tool 直接注入 Repository / Mapper
Verifier 校验输出是否符合规则 生成最终用户文案
Reporter 格式化最终回复 执行业务副作用

7.5 标准 Pipeline 步骤

每个 Agent 的 Pipeline 至少包含以下 Step(可按场景增删,但不可跳过 Verifier / Report):

复制代码
Pipeline
├── Step 1: IntentStep           # 意图识别
├── Step 2: ContextStep          # 构造上下文
├── Step 3: PlanStep             # 生成计划
├── Step 4: ValidatePlanStep     # 校验计划
├── Step 5: ExecuteStep          # 执行 Tool / 子任务
├── Step 6: VerifyStep           # 结果校验
├── Step 7: MemoryStep           # 写入记忆
└── Step 8: ReportStep           # 生成回复

Step 实现要求:

java 复制代码
// 每个 Step 必须产出可观测记录
public interface PipelineStep {
    StepResult execute(AgentContext context);
}

// StepResult 至少包含
// - stepName、status(SUCCESS / FAILED / SKIPPED)
// - inputSnapshot、outputSnapshot(可序列化摘要)
// - startTime、endTime、durationMs
// - errorMessage(失败时)
  • 可恢复 :ExecuteStep 及之后的 Step 应支持从 checkpoint 恢复;checkpoint 写入 context 或 Memory
  • 可重试:Tool 调用失败时按策略重试,重试次数与间隔可配置
  • 可跳过 :PlanValidator 判定无需执行时,后续 Step 标记 SKIPPED 并记录原因

7.6 Tool 与数据访问

Tool 是 Agent 访问外部能力的唯一入口:

复制代码
Agent / Pipeline
    ↓ ToolExecutor
Tool(ai4j/tool/)
    ↓ 调用 Api 接口(由 gates 注入或 ApiExecutor 桥接)
ExtApi / Api(business-api)
    ↓
ExtResource / Resource(business-resource)
    ↓
MapperExt / Repository

规则:

  • Tool 内禁止 import ...data.repository、禁止 import ...data.mapper
  • 需要持久化时,Tool 调用 XxxExtApi 方法(单 Request 入参、三件套返回)
  • SQL 类 Tool 必须经过 Verifier + SqlValidator,仅允许 SELECT
  • Prompt 独立为 XxxPromptBuilder,放在 schema/ 或场景子包

7.7 开发约定

项 规范
Agent 入口 XxxAgent 或 XxxPipelineFactory,只负责组装 Pipeline
结果类型 使用 XxxResult / XxxSpec 强类型,避免 Map<String, Object>
流式输出 Pipeline 通过 StepNotifier / StageNotifier 推送进度;SSE 由 ExtResource 转发
新模式 参考 documents/AI-Agent-开发模式.md;落地时仍须落入 Pipeline
ChatBI 自然语言分析链路:Intent → Plan → DSL → SQL(Tool) → Verify → Report

禁止:

  • 在 Agent 类中连续多次裸调用 LLM 而不经 Pipeline
  • 在 ai4j 中引入 business-resource 依赖
  • Planner 与 Executor 混写在同一个类中
  • 跳过 VerifyStep 直接 ReportStep

7.8 gates 与 ai4j 的协作

复制代码
Controller(gates/admin)
    ↓ 单 Request 入参,三件套返回
ExtResource(business-resource)
    ↓ 调用 XxxAgent / PipelineRunner
Pipeline(ai4j)
    ↓ ToolExecutor
Tool → ExtApi / Api → Resource → 数据库
    ↓
Reporter 输出 → 封装为 ResponseObject<T>
  • Controller 不 直接调用 ai4j Agent
  • ExtResource 负责:Token 预扣/结算、会话持久化、Pipeline 启动与结果封装
  • Pipeline 运行日志 / Step 快照可经 ExtApi 写入审计表(通过 Tool 或 ExtResource 回调)

8. 接口与响应规范

统一契约详见 §4.0。本节补充平台内置接口说明。

8.1 统一响应结构(强制)

类型 用途
ResponseObject<T> 单对象操作(create / view / 业务动作)
ListResponse<T> 不分页列表
PageResponse<T> 分页列表
  • T 为业务 DTO,如 XxxResponse、XxxSimple
  • Api、ExtApi、Controller 不得返回 T 本身,必须包在上述三者之一内
  • 无业务体时可返回 ResponseObject<?> 或 new ResponseObject<>()

错误返回:

java 复制代码
return ResponseObject.error(401, "未登录");
return ResponseObject.error(403, "权限不足");
return ResponseObject.error(404, "会话不存在");
return ResponseObject.error(406, "消息内容不能为空");
return ResponseObject.error(500, "Token 预扣失败");

错误码规范:

码 含义 典型场景
200 成功 正常返回
401 未认证 未登录、UnauthenticatedException
403 无权限 Shiro 鉴权失败、UnauthorizedException、越权访问
404 资源不存在 会话/记录找不到
406 参数不合法 @Validated 校验失败、业务参数缺失
500+ 业务/系统异常 从 500 起 ;500 为默认未知错误,具体业务码如 501 余额不足

约定:

  • 401--406:通用语义码,全项目含义一致
  • 500 及以上 :业务异常与系统错误,异常码从 500 开始 ;各模块在 documents/ 或模块 README 中维护码表
  • 同一业务失败场景使用固定码,禁止随意更换;禁止 用 500 以下码表示业务失败

8.2 nbsaas-boot 通用数据接口

平台内置模型查询,命名规则 front_{业务}_{操作}:

接口 方法 说明
/data/list POST 列表
/data/search POST 分页
/data/batch POST 批量
/data/data/{model} GET 无条件列表

8.3 ChatBI 业务接口

接口 方法 说明
/chatbi/meta GET 元数据(指标/维度/图表类型)
/chatbi/analyze POST 自然语言分析

9. 安全与权限

9.1 认证

  • 使用 Apache Shiro,@RequiresAuthentication / @RequiresUser
  • 当前用户通过 UserUtils.user() 获取

9.2 授权

  • 生成 Controller:@RequiresPermissions("entityName:action")
  • 权限数据由 MenuExtApi.permissions(roleId) 加载

9.3 SQL 安全(ChatBI 特有)

  • 禁止 AI 直接生成 SQL ,必须走 自然语言 → DSL → SQL 链路
  • 仅允许 SELECT,拦截 DELETE/UPDATE/DROP/INSERT/ALTER/TRUNCATE/UNION
  • 强制 LIMIT 与查询超时
  • 自动注入租户过滤条件

10. 数据库规范

10.1 脚本管理

  • DDL 脚本放在 documents/ 或 documents/sqls/
  • 命名:{业务}-{描述}.sql,如 chatbi-session.sql
  • 表名:小写下划线
  • 字符集:MySQL 使用 utf8mb4

10.2 字段约定

字段 说明
id 主键,继承自 AbstractEntity
add_date 创建时间
last_date 最后修改时间
deleted_flag 逻辑删除标记
archived 归档标记(如适用)

10.3 双持久化策略

  • JPA :标准 CRUD,通过 BaseResource + Repository
  • MyBatis :复杂查询、批量更新,通过 XxxMapperExt + XML

新增复杂查询在 XxxMapperExt 中实现,禁止 修改生成的 XxxMapper 与 XxxResource。


11. 配置与环境

11.1 配置文件

复制代码
gates/admin/src/main/resources/
├── application.yml          # 公共配置
├── application-dev.yml      # 开发环境(MySQL)
├── application-pg.yml         # PostgreSQL 环境
└── application-pro.yml        # 生产环境

11.2 关键配置项

配置 说明
server.port 默认 1818
spring.profiles.active 环境切换:dev / pg / pro
spring.cache.type Caffeine 本地缓存
mybatis-plus.mapper-locations classpath*:mapper/**/*.xml
shiro.enabled 权限开关

11.3 本地启动

bash 复制代码
# 1. 导入 documents/ 下 SQL
# 2. 修改 application-dev.yml 数据库连接
# 3. 构建并启动
mvn clean install
# 运行 AdminApplication,默认 http://localhost:1818

12. 编码规范

12.1 通用

  • JDK 21,启用 --release 21
  • 使用 Lombok @Data,实体与 DTO 不手写 getter/setter
  • 依赖注入使用 @Resource(项目惯例)
  • 事务:Resource / ExtResource 类级别 @Transactional
  • Spring 注册:Resource 类使用 @Service 注解(这是 Spring Bean 注解,不是 Service 分层概念)
  • 时间:GMT+8,格式 yyyy-MM-dd HH:mm:ss

12.2 命名

类别 风格 示例
业务实现类 大驼峰 + Resource 后缀 ChatBiSessionExtResource(禁止 XxxService)
自定义 Mapper 实体类名 + MapperExt ChatBiSessionMapperExt
Api 接口 大驼峰 + Api / ExtApi 后缀 ChatBiSessionExtApi
入参对象 以 Request 结尾 ChatBiSessionListRequest
方法名 小驼峰 ensureSession
常量 全大写下划线 FORBIDDEN_SQL_KEYWORDS
数据库表/列 小写下划线 chat_bi_session
URL 路径 小驼峰或短横线 /chatbi、/chatBiMessage

12.3 注释

  • 类和方法使用 JavaDoc,说明业务含义
  • 不在代码中写「修改了 xxx」类注释
  • 非显而易见的业务规则需注释(如 Token 预扣/结算逻辑)

12.4 异常处理

  • Controller 层不做大范围 try-catch;认证/权限异常由 Shiro + ExceptionHandle 映射为 401 / 403
  • ExtResource 中捕获 AI 调用异常,提供规则回退
  • 参数校验失败返回 406;资源不存在返回 404
  • 业务失败返回 500 及以上 ;未预期异常由全局处理器返回 500
  • 业务错误通过 ResponseObject.error(code, message) 返回,不抛未处理异常到前端

13. 禁止事项

序号 禁止行为
1 修改代码生成器产出的任何文件(含 XxxMapper / XxxMapper.xml)
2 在 api/domain/ 基础层追加 Ext 专用 DTO(应放 ext/domain/)
3 在 gates 中直接注入 Repository、XxxMapper 或 XxxMapperExt
4 在 ai4j 中依赖 business-resource 或 gates
5 让 AI 直接生成可执行 SQL(绕过 DSL 与安全校验)
6 Api / ExtApi / Controller 返回裸类型或非三件套(ListResponse / ResponseObject / PageResponse 以外)
7 接口使用多个入参,或入参类型不以 Request 结尾
8 跳过 Shiro 权限注解暴露敏感接口
9 使用 Service 概念 :禁止新建 XxxService 类、service/ 包;业务实现一律为 Resource
10 在 Controller 中编写复杂业务逻辑(应下沉到 ExtResource)
11 向生成的 XxxMapper 追加自定义 SQL(应新建 XxxMapperExt)
12 新接口使用 XxxSearch 命名(应改为 XxxSearchRequest / XxxListRequest)
13 Agent 绕过 Pipeline 手写多步 LLM / Tool 调用链
14 在 ai4j 中直接访问 Repository、Mapper 或数据库
15 Planner 与 Executor 混写,或跳过 Verifier / ReportStep

14. 参考文档

文档 路径
项目 README /README.md
需求文档 documents/需求文档/
AI Agent 开发模式 documents/AI-Agent-开发模式.md
发散型 Agent 方案 documents/多思维发散型AI-Agent技术方案.md
实体与 Ext 约定 documents/chatgpt/entity.md
开发流程说明 documents/chatgpt/开发.md
数据库脚本 documents/sqls/、documents/*.sql

15. 附录:典型开发示例

15.1 新增「数据源配置」功能

  1. 编写需求 → documents/需求文档/数据源配置.md
  2. 创建实体 DataSourceConfig.java
  3. 编写 DDL → documents/sqls/data_source_config.sql
  4. 新增 code-generator/.../config/datasource.yml
  5. 运行 App.main 生成基础代码
  6. 在 DataSourceConfigExtApi 中声明 ResponseObject<XxxResponse> testConnection(DataSourceTestRequest request)
  7. 在 DataSourceConfigExtResource 中实现,返回三件套包装类型
  8. 在 gates/admin/controller/chatbi/ 新增 DataSourceController,仅调用 ExtApi
  9. 复杂逻辑在 DataSourceConfigExtResource 中实现,不在 gates 层建 Service

15.2 扩展已有实体的查询能力

  1. 不修改 ChatBiSessionResource、ChatBiSessionMapper
  2. 新建 ChatBiSessionMapperExt.java,声明 selectByXxx(...) 等方法
  3. 新建 mapper/chatbi/ChatBiSessionMapperExt.xml 编写 SQL
  4. 在 ChatBiSessionExtResource 中注入并调用 ChatBiSessionMapperExt
  5. 在 ChatBiSessionExtApi 中声明新方法,入参 XxxRequest、返回三件套之一
  6. Controller 注入 ChatBiSessionExtApi,原样返回 Api 结果

15.3 新增 Agent 功能

  1. 在 documents/ 整理 Agent 需求与 Pipeline 步骤
  2. 在 ai4j/agent/{scene}/ 创建 XxxAgent + XxxPipelineFactory
  3. 按 §7.5 实现 8 个标准 Step(至少含 VerifyStep、ReportStep)
  4. 在 ai4j/tool/ 注册 Tool;Tool 内通过 Api 访问数据,禁止直连数据库
  5. 在 apis/.../ext/apis/ 声明 XxxAgentExtApi(单 Request、三件套返回)
  6. 在 ext/resource/ 实现 ExtResource:Token/会话 + 启动 Pipeline + 封装结果
  7. 在 gates/admin/controller/agent/ 新增 Controller,仅调用 ExtApi