16 changed files with 267 additions and 121 deletions
@ -0,0 +1,19 @@
|
||||
# Maven |
||||
target/ |
||||
pom.xml.tag |
||||
pom.xml.releaseBackup |
||||
pom.xml.versionsBackup |
||||
pom.xml.restore |
||||
release.properties |
||||
dependency-reduced-pom.xml |
||||
buildNumber.properties |
||||
.mvn/timing.properties |
||||
# https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore |
||||
.idea/ |
||||
*.iml |
||||
*.iws |
||||
.idea_modules/ |
||||
|
||||
# OS |
||||
.DS_Store |
||||
Thumbs.db |
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="VcsDirectoryMappings"> |
||||
<mapping directory="" vcs="Git" /> |
||||
</component> |
||||
</project> |
||||
@ -0,0 +1,49 @@
|
||||
# AI-Native CRM 系统开发手册 |
||||
|
||||
## 🎯 系统定位 (Core Vision) |
||||
本系统是一款 **AI-Native (原生 AI)** 的声明式 CRM。与传统 CRM 的本质区别在于: |
||||
* **非硬编码业务逻辑**:业务模块、字段定义和 UI 呈现均由 AI 动态生成并持久化。 |
||||
* **零研发排期**:业务专家通过自然语言描述需求,即可立刻生成生产可用的功能模块。 |
||||
|
||||
--- |
||||
|
||||
## 🚀 核心特性 (Key Features) |
||||
|
||||
### 1. 生成式 UI (Generative UI) |
||||
* 集成 **CopilotKit**,在前端实现 AI 对应用的深度操控。 |
||||
* 支持通过自然语言一键渲染(Render)基于 JSON Schema 的复杂表单。 |
||||
* **UniversalModuleRenderer**:万能组件渲染引擎,适配多种动态业务场景。 |
||||
|
||||
### 2. 动态多租户架构 |
||||
* 后端使用 `SysEntity` (元数据) 和 `SysDynamicData` (实例数据) 支撑无限扩展。 |
||||
* 支持不同租户、不同模块的字段在运行时动态注入,无需繁琐的数据库迁移动作。 |
||||
|
||||
### 3. AI 交互中枢 (AI Hub) |
||||
* **后端驱动**:基于 **LangChain4j** 构建 Java 原生 AI 逻辑,支持 RAG 及复杂工作流。 |
||||
* **会话持久化**:原生支持 AI 会话的数据库存储,重启不丢失交互上下文。 |
||||
|
||||
--- |
||||
|
||||
## 📋 技术基准 (Benchmarks & Tech Stack) |
||||
|
||||
### Backend (Java Ecosystem) |
||||
* **Runner**: OpenJDK 19 |
||||
* **Framework**: Spring Boot 3.2.4 (Latest Stable) |
||||
* **Persistence**: Spring Data JPA + Hibernate 6.x |
||||
* **Database**: PostgreSQL (Support JSONB for Dynamic Data) |
||||
* **AI SDK**: LangChain4j 0.30.0 |
||||
* **Build Tool**: Maven |
||||
|
||||
### Frontend (Modern Web) |
||||
* **Framework**: Next.js (App Router) |
||||
* **Language**: TypeScript |
||||
* **Styling**: Tailwind CSS + Shadcn UI (Visual Esthetics) |
||||
* **Copilot**: CopilotKit (React SDK + Popup UI) |
||||
* **Font**: Geist (Advanced Typography) |
||||
|
||||
--- |
||||
|
||||
## 🛠 开发规范 |
||||
1. **动态性优先**:任何新功能应考虑是否可通过配置或 AI 生成,而非硬编码 Controller。 |
||||
2. **Schema 为王**:业务定义必须严格遵循 JSON Schema 标准,以保证前后端渲染的一致性。 |
||||
3. **Prompt 工程**:系统 Prompt 存储于前端 `page.tsx` 或后端专用 AI 服务类中,需定期维护。 |
||||
@ -1,54 +1,99 @@
|
||||
package com.example.ainative.ai; |
||||
|
||||
import com.example.ainative.config.UserContextHolder; |
||||
|
||||
import com.example.ainative.entity.SysDynamicData; |
||||
import com.example.ainative.entity.SysEntity; |
||||
import com.example.ainative.repository.SysDynamicDataRepository; |
||||
import com.example.ainative.repository.SysEntityRepository; |
||||
import dev.langchain4j.agent.tool.Tool; |
||||
import lombok.RequiredArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.UUID; |
||||
import org.springframework.transaction.annotation.Transactional; |
||||
|
||||
@Slf4j |
||||
@Component |
||||
@Component("crmTools") |
||||
@RequiredArgsConstructor |
||||
public class CrmTools { |
||||
|
||||
private final SysEntityRepository sysEntityRepository; |
||||
private final SysDynamicDataRepository sysDynamicDataRepository; |
||||
|
||||
/** |
||||
* AI 工具:用于定义新的动态业务对象(Entity)。 |
||||
* 当用户试图创建新表单、新模块(比如“线索管理”、“合同管理”)时,大模型会自动决定调用本工具, |
||||
* 并将它根据系统指令生成的参数传入进来。 |
||||
* |
||||
* @param entityCode 模块唯一标识符,英文,比如 crm_lead (便于后期通过接口精确操作某模块) |
||||
* @param entityName 模块中文名称跨,比如 销售线索 |
||||
* @param jsonSchema 这里是大模型输出的最核心数据:一个合规的 JSON Schema (如属性定义、校验规则),由前端随后解析渲染 |
||||
* @return 返回一段让 AI 知道是否成功的指令结果,这个结果大模型能看到并进一步回答用户。 |
||||
*/ |
||||
@Tool("创建一个新的业务表单模块,当你确定了用户创建新功能的意图后调用。参数包括:entityCode (英文唯一标识), entityName (中文名称), jsonSchema。") |
||||
@Transactional |
||||
@Tool("核心业务处理:根据消息意图定义或执行模型变更 (Schema)。支持以下高级能力:\n" + |
||||
"1. [实体关联]:若字段需要关联其他实体,需在 Schema 属性中加入 `x-link-entity: '目标实体Code'`。\n" + |
||||
"2. [值约束]:支持标准 JSON Schema 的 `enum` (下拉选择)、`pattern` (正则校验)、`format` (如 date, email)、`minLength` 等约束。\n" + |
||||
"3. [示例]:商品关联分类,分类字段可定义为 { 'type': 'string', 'x-link-entity': 'category' }") |
||||
public String defineDynamicModule(String entityCode, String entityName, String jsonSchema) { |
||||
log.info("Agent 正在调用工具执行创建新模块: Code={}, Name={}", entityCode, entityName); |
||||
|
||||
// 1. 业务校验:防重和容错
|
||||
log.info("Agent Tool 正在处理消息:定义模块: Code={}, Name={}", entityCode, entityName); |
||||
try { |
||||
SysEntity existing = sysEntityRepository.findByEntityCode(entityCode); |
||||
if (existing != null) { |
||||
return "模块代码 [" + entityCode + "] 已存在,创建失败,请让用户考虑使用其他代码名称。"; |
||||
existing.setSchemaDefinition(jsonSchema); |
||||
existing.setEntityName(entityName); |
||||
existing.setCreatorId(UserContextHolder.getCurrentUser()); |
||||
sysEntityRepository.save(existing); |
||||
return "AI 已更新现有模块 [" + entityName + "]。"; |
||||
} |
||||
|
||||
// 2. 实体赋值与入库
|
||||
try { |
||||
SysEntity entity = new SysEntity(); |
||||
entity.setEntityCode(entityCode); |
||||
entity.setEntityName(entityName); |
||||
// 此处直接存储大模型生成的 JSON 字符串(PostgreSQL 的 Hibernate 驱动会将其封装为 JSONB)
|
||||
entity.setSchemaDefinition(jsonSchema); |
||||
|
||||
entity.setCreatorId(UserContextHolder.getCurrentUser()); |
||||
SysEntity saved = sysEntityRepository.save(entity); |
||||
return "核心模块 [" + entityName + "] 已成功持久化并部署到系统中。后台对应的 Entity ID (UUID) 为: " + saved.getId(); |
||||
return "AI 已成功解析并持久化业务模块 [" + entityName + " (" + entityCode + ")],ID: " + saved.getId(); |
||||
} catch (Exception e) { |
||||
log.error("保存 Schema 时出现异常", e); |
||||
return "数据库保存异常,请检查 JSON 结构是否合规。"; |
||||
log.error("AI 处理定义请求失败: {}", e.getMessage()); |
||||
return "处理失败: " + e.getMessage(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* AI 工具封装:直接处理业务数据入库意图。 |
||||
*/ |
||||
@Transactional |
||||
@Tool("核心业务处理:将业务消息中的动态数据持久化到指定模块。参数:entityCode (模块代码), jsonData (JSON 数据)。") |
||||
public String insertDynamicData(String entityCode, String jsonData) { |
||||
log.info("Agent Tool 正在处理消息:将数据保存至模块: Code={}", entityCode); |
||||
try { |
||||
SysEntity entity = sysEntityRepository.findByEntityCode(entityCode); |
||||
if (entity == null) { |
||||
return "AI 无法找到模块 [" + entityCode + "],请先下达创建模块的指令。"; |
||||
} |
||||
|
||||
SysDynamicData record = new SysDynamicData(); |
||||
record.setEntityId(entity.getId()); |
||||
record.setData(jsonData); |
||||
record.setCreatorId(UserContextHolder.getCurrentUser()); |
||||
SysDynamicData saved = sysDynamicDataRepository.save(record); |
||||
return "AI 已自动完成数据入库,记录主键 ID: " + saved.getId(); |
||||
} catch (Exception e) { |
||||
log.error("AI 自动化入库失败: {}", e.getMessage()); |
||||
return "入库失败: " + e.getMessage(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* AI 工具封装:删除指定的业务数据。 |
||||
*/ |
||||
@Transactional |
||||
@Tool("核心业务处理:根据 ID 物理删除指定的业务记录。参数:id (记录的唯一 UUID)。") |
||||
public String deleteDynamicData(String id) { |
||||
log.info("Agent Tool 正在处理消息:删除记录 ID: {}", id); |
||||
try { |
||||
java.util.UUID uuid = java.util.UUID.fromString(id); |
||||
if (!sysDynamicDataRepository.existsById(uuid)) { |
||||
return "AI 无法找到 ID 为 [" + id + "] 的记录,可能已被删除。"; |
||||
} |
||||
sysDynamicDataRepository.deleteById(uuid); |
||||
return "AI 已成功从系统中移除该条记录 (ID: " + id + ")。"; |
||||
} catch (Exception e) { |
||||
log.error("AI 物理删除失败: {}", e.getMessage()); |
||||
return "删除操作遇到技术故障: " + e.getMessage(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
Loading…
Reference in new issue