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.javaapi/domain/{field,request,response,simple}/rest/resource/XxxResource.javarest/convert/Xxx*Convert.javadata/repository/XxxRepository.javadata/mapper/XxxMapper.java+mapper/chatbi/XxxMapper.xml(禁止修改)- 自定义 SQL 另建
data/mapper/XxxMapperExt.java+mapper/chatbi/XxxMapperExt.xml(手写) gates/admin/controller/.../XxxController.javaext/apis/XxxExtApi.java(空壳,供扩展)ext/resource/XxxExtResource.java(空壳,供扩展)
重要 :以上生成文件均不可手动修改。需要定制 SQL 时,新建
XxxMapperExt,禁止 向生成的XxxMapper追加方法。
3.3 新增业务模块 Checklist
- 在
documents/整理需求文档 - 创建 Entity 类及数据库 DDL(
documents/sqls/或独立.sql) - 新增
code-generator/.../config/xxx.yml - 执行代码生成器
- 在
ext中实现特殊业务(如有) - 在
ext/resource/实现复杂业务 Resource,在gates/admin编写 Controller - 如需 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 不 直接调用
ai4jAgent - 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 新增「数据源配置」功能
- 编写需求 →
documents/需求文档/数据源配置.md - 创建实体
DataSourceConfig.java - 编写 DDL →
documents/sqls/data_source_config.sql - 新增
code-generator/.../config/datasource.yml - 运行
App.main生成基础代码 - 在
DataSourceConfigExtApi中声明ResponseObject<XxxResponse> testConnection(DataSourceTestRequest request) - 在
DataSourceConfigExtResource中实现,返回三件套包装类型 - 在
gates/admin/controller/chatbi/新增DataSourceController,仅调用 ExtApi - 复杂逻辑在
DataSourceConfigExtResource中实现,不在 gates 层建 Service
15.2 扩展已有实体的查询能力
- 不修改
ChatBiSessionResource、ChatBiSessionMapper - 新建
ChatBiSessionMapperExt.java,声明selectByXxx(...)等方法 - 新建
mapper/chatbi/ChatBiSessionMapperExt.xml编写 SQL - 在
ChatBiSessionExtResource中注入并调用ChatBiSessionMapperExt - 在
ChatBiSessionExtApi中声明新方法,入参XxxRequest、返回三件套之一 - Controller 注入
ChatBiSessionExtApi,原样返回 Api 结果
15.3 新增 Agent 功能
- 在
documents/整理 Agent 需求与 Pipeline 步骤 - 在
ai4j/agent/{scene}/创建XxxAgent+XxxPipelineFactory - 按 §7.5 实现 8 个标准 Step(至少含 VerifyStep、ReportStep)
- 在
ai4j/tool/注册 Tool;Tool 内通过 Api 访问数据,禁止直连数据库 - 在
apis/.../ext/apis/声明XxxAgentExtApi(单 Request、三件套返回) - 在
ext/resource/实现 ExtResource:Token/会话 + 启动 Pipeline + 封装结果 - 在
gates/admin/controller/agent/新增 Controller,仅调用 ExtApi