内容
# Java AI 参考架构
用于在 Java 中构建和测试企业级智能 AI 应用的可复制、本地优先的 playground —— 包括 Spring Boot、Spring AI、MCP、PostgreSQL 和 Angular。
目标是建立一个低成本、自成体系的开发环境,用于智能 AI 应用。该环境可运行在本地 Docker 中,无需额外基础设施,也无需云端支出(仅限模型 API 调用)。它将数据库、示例业务数据、MCP 工具、启用 AI 的 Java 服务、REST API、健康检查和工程控制台组合成一个可复制的本地环境,以便在相同基础上构建新的代理想法和应用,而不是每次都从头开始。
首先在此基础上构建的应用是一个自然语言到 SQL 的代理。它不是该项目的重点,而是作为参考示例,以证明环境能够端到端运行。
## 一键本地环境
```bash
docker compose \
-f compose.yaml \
-f compose.openai.yaml \
up --build
```
此命令启动完整的环境:
- PostgreSQL
- Chinook 业务数据导入器
- Docker MCP 网关
- Spring Boot 和 Spring AI 应用
- Angular 工程控制台
## 当前成熟度
| 功能 | 状态 |
| -------------------------------------------- | ------------------------------------------ |
| 容器化本地环境 | ✅ 工作中 |
| 将 Chinook 数据导入 PostgreSQL | ✅ 工作中 |
| Spring AI 和 OpenAI 集成 | ✅ 工作中 |
| 对数据库的自然语言查询 | ✅ 工作中 |
| MCP 数据库工具调用 | ✅ 工作中 |
| Angular 工程控制台 | 🚧 仅限 Shell - 暂无 NL 查询 UI 或跟踪视图 |
| 生成 SQL 和工具跟踪可视化 | 🔭 待开始 |
| 重复运行一致性测试 | 🔭 待探索 |
| 多代理验证和编排 | 🔭 待探索 |
## 项目目的
许多 AI 示例展示隔离的提示或基于控制台的代理。本项目旨在提供可重复使用的本地环境,用于开发和验证 AI 驱动的企业应用 —— 该环境足够廉价,可重复运行,并可在其基础上构建多个无关的应用。
当前实现接受自然语言的业务问题,允许 Spring AI 选择并调用数据库工具,通过 MCP 实现动态查询 Chinook 数据库,并返回自然语言答案。
长期目标是探索企业团队如何使 AI 工作流更加确定、可观察、可测试,适合生产使用 —— 并使用相同的 Docker Compose 基础构建其他代理应用,而不仅仅是 NL-to-SQL(例如,文档或电子表格数据提取)。
`console/` 下的 Angular 应用旨在成为工程和验证控制台,而非终端用户聊天机器人。目前,它仅作为未修改的 Angular 脚手架。计划使用它来检查自然语言问题、生成的 SQL、工具调用、原始数据库结果、最终答案、重复运行一致性和验证结果 —— 但目前尚未实现。
## 灵感来源
该项目以 Docker Compose for Agents 仓库中的 LangGraph 自然语言到 SQL 示例为模型:
<https://github.com/docker/compose-for-agents/tree/main/langgraph>
原始示例演示了 LLM 如何解释问题、检查本地数据库、动态生成 SQL、执行查询并形成答案。
本项目将工作流适配到使用 Spring Boot 和 Spring AI 的 Java 企业应用中,并通过 REST API 公开。
## 当前功能
项目目前提供:
- 在 Docker 中运行的 PostgreSQL 数据库
- 自动将 Chinook SQLite 数据库导入 PostgreSQL
- 公开数据库工具的 MCP 网关
- Spring Boot 和 Spring AI 应用
- OpenAI 模型集成
- 用于提问自然语言问题的 REST 端点
- 在 Docker 中运行的 Angular 控制台(未修改的脚手架 - 暂无自定义 UI)
- 健康检查和启动依赖管理
- 从 DBeaver 等工具访问 PostgreSQL
## 架构
```
+-----------------------------+
| Angular 工程控制台 |
| http://localhost:4200 |
+--------------+--------------+
|
| REST/JSON
v
+--------------+--------------+
| Spring Boot REST API |
| Spring AI ChatClient |
| http://localhost:8080 |
+--------------+--------------+
|
| 模型上下文协议
v
+--------------+--------------+
| Docker MCP 网关 |
| 数据库工具公开 |
+--------------+--------------+
|
| list_tables
| describe_table
| execute_sql
v
+--------------+--------------+
| PostgreSQL |
| Chinook 业务数据 |
+-----------------------------+
```
当前通过 MCP 公开的主要数据库工具是:
- `list_tables`
- `describe_table`
- `execute_sql`
## 仓库结构
```
java-ai-reference-arch/
├── application/ Spring Boot 和 Spring AI 应用
├── console/ Angular 工程控制台(未修改的脚手架)
├── database/ Chinook 数据库和导入器镜像
├── docs/ 架构和开发文档
├── compose.yaml 基础基础设施和应用服务
├── compose.openai.yaml OpenAI 特定应用配置
├── mcp-config.yaml MCP 数据库服务器配置
└── README.md
```
## 示例业务数据
应用使用 Chinook 示例数据库,该数据库模拟具有员工、客户、艺术家、专辑、曲目、播放列表、发票和发票行的数字媒体商店。
捆绑的 SQLite 数据库在 Compose 环境启动时自动导入到 PostgreSQL。详细的来源、许可、行数、关系、模式注释和验证查询在 [`docs/sample-data.md`](https://github.com/pramalin/java-ai-reference-arch/blob/main/docs/sample-data.md) 中有记录。
## 最低要求
### 运行完整环境所需
- 一台可以运行 Docker 的机器
- 带有 Docker Compose 支持的 Docker 引擎
- Git
- OpenAI API 密钥
- 初始镜像和依赖下载期间的互联网访问
由于应用、数据库、导入器、MCP 网关和 Angular 控制台在容器内运行,因此 JDK、Maven、Node.js 和 Angular CLI 不需要仅用于运行项目。
### 可选开发工具
这些工具在修改或调试各个组件时很有用:
- JDK 26
- Maven 或包含的 Maven 包装器
- Node.js
- Angular CLI 22
- Visual Studio Code 或其他 IDE
- DBeaver 或其他 PostgreSQL 客户端
- `curl`
- Git
## 测试硬件
该项目已在经济型 Dell Latitude 5400 Chromebook 的 Linux 环境中成功开发和运行。
```
设备:Dell Latitude 5400 Chromebook
运行环境:ChromeOS Linux 开发环境
处理器:Intel(R) Core(TM) i5-8365U CPU @ 1.60GHz(8 线程,4.100GHz)
内存:16GB
存储:150GB SSD
```
该项目当前不运行本地 LLM - 模型推理通过 OpenAI API 执行,因此即使堆栈的其他部分免费且本地,但每次调用仍有费用。本地模型覆盖(例如 Ollama)是路线图上的内容,旨在使环境完全自给自足。
## 配置 OpenAI API 密钥
在仓库根目录创建名为 `.env` 的文件:
```
OPENAI_API_KEY=sk-proj-...
```
`.env` 文件不得提交。确认 `.gitignore` 包含:
```
.env
```
可以提交一个带有空值的 `.env.example` 安全文件:
```
OPENAI_API_KEY=
```
## 启动应用
克隆仓库并进入其中:
```
git clone https://github.com/pramalin/java-ai-reference-arch.git
cd java-ai-reference-arch
```
创建包含 OpenAI API 密钥的 `.env` 文件。
启动完整环境:
```bash
docker compose \
-f compose.yaml \
-f compose.openai.yaml \
up --build
```
重新创建配置更改后的所有容器:
```bash
docker compose \
-f compose.yaml \
-f compose.openai.yaml \
up --build --force-recreate
```
停止环境:
```bash
docker compose \
-f compose.yaml \
-f compose.openai.yaml \
down
```
停止环境并删除持久卷:
```bash
docker compose \
-f compose.yaml \
-f compose.openai.yaml \
down -v
```
删除卷会导致下次环境启动时重新导入 Chinook 数据库。
## 应用端点
启动完成后:
```
Angular 控制台: http://localhost:4200
Spring Boot API: http://localhost:8080
应用健康检查: http://localhost:8080/actuator/health
应用就绪检查: http://localhost:8080/actuator/health/readiness
PostgreSQL: localhost:5432
```
## 验证后端
应用信息:
```bash
curl http://localhost:8080/api/info
```
健康检查:
```bash
curl http://localhost:8080/actuator/health
```
## 提问自然语言问题
API 通过以下方式接受 JSON 请求:
```
POST /api/questions
```
### 2010 年哪位销售代理的销售额最高?
```bash
curl -X POST http://localhost:8080/api/questions \
-H 'Content-Type: application/json' \
-d '{
"question": "2010 年哪位销售代理的销售额最高?"
}'
```
示例响应:
```
{
"question": "2010 年哪位销售代理的销售额最高?",
"answer": "2010 年销售额最高的销售代理是 Jane Peacock,总销售额为 221.92。"
}
```
### 系统中有多少员工?
```bash
curl -X POST http://localhost:8080/api/questions \
-H 'Content-Type: application/json' \
-d '{
"question": "系统中有多少员工?"
}'
```
示例响应:
```
{
"question": "系统中有多少员工?",
"answer": "系统中有 8 名员工。"
}
```
### 哪些员工有经理职称?
```bash
curl -X POST http://localhost:8080/api/questions \
-H 'Content-Type: application/json' \
-d '{
"question": "哪些员工有经理职称?"
}'
```
示例响应:
```
{
"question": "哪些员工有经理职称?",
"answer": "有 3 名员工的职称包含\"经理\"。"
}
```
## 关于 AI 生成答案的重要说明
由于 SQL 在运行时由模型生成,而不是在代码中固定,因此系统可以为相同或类似的问题生成不同的解释或不同的 SQL。 例如,问题:
```
有多少名员工是经理?
```
可以意味着:
- 职称包含 `manager` 的员工
- 至少监督另一名员工的员工
- 没有汇报给另一名员工的员工
- 持有特定组织角色的员工
为了获得更可靠的结果,问题应明确定义预期的业务含义。
这种不确定性不仅是理论上的问题 - 相同销售总额问题的重复运行已经产生了不同的美元总额,这取决于模型生成的 SQL(例如,员工职称的匹配方式不同)。 目前,该项目中没有工具来自动捕获、比较或诊断这一点;这样做是近期工程控制台的主要目标。
工程控制台计划公开的内容包括:
- 模型选择的解释
- 调用的工具
- 生成的 SQL
- 原始数据库结果
- 最终自然语言答案
- 重复执行一致性
- 验证结果
以上皆尚未实现。 这是项目的核心近期目标 - 从“一个回答问题的代理”转变为“一个可以检查、信任和验证其答案的代理”。
## 使用 DBeaver 访问数据库
使用以下信息创建 PostgreSQL 连接:
```
主机:localhost
端口:5432
数据库:database
用户名:user
密码:password
```
DBeaver 可用于检查 Chinook 模式,直接运行 SQL,并验证 AI 应用返回的答案。
当前凭证是仅限开发的默认值,绝不能在生产部署中使用。
## Docker Compose 组件
### `database`
运行 PostgreSQL 并公开端口 `5432`。
它创建开发数据库并通过 `pg_isready` 报告就绪状态。
### `importer`
从 `database/Dockerfile.importer` 构建。
它等待 PostgreSQL 变得健康,然后使用 `pgloader` 将 Chinook SQLite 数据库复制到 PostgreSQL。
导入器在数据迁移完成后成功退出。
### `mcp-gateway`
运行 Docker 的 MCP 网关。
它等待导入器完成,并通过 Compose 网络上的端口 `8811` 公开配置的数据库工具,基于服务器发送的事件。
当前网关配置为仅限本地开发的无需身份验证的访问。
### `application`
构建并运行 Spring Boot 应用。
它通过以下方式连接到 MCP 网关:
```
http://mcp-gateway:8811
```
应用在主机端口 `8080` 上公开 REST API。
OpenAI API 密钥、模型名称和 MCP 网关 URL 通过 OpenAI Compose 叠加层提供。
### `console`
构建并运行 Angular 工程控制台。
它等待 Spring Boot 应用变得健康,并在端口 `4200` 上发布 Angular 开发服务器。 目前它是一个未修改的 Angular 脚手架,没有自定义功能。
## 配置文件
### `compose.yaml`
定义提供者独立的本地环境:
- PostgreSQL
- Chinook 导入器
- MCP 网关
- Spring Boot 应用
- Angular 控制台
- 服务健康检查
- 启动依赖
- 已发布的端口
### `compose.openai.yaml`
将 OpenAI 特定配置添加到应用服务:
```
OPENAI_MODEL_NAME
OPENAI_API_KEY
MCP_SERVER_URL
```
将此配置保留在 Compose 叠加层中,允许稍后添加其他模型提供商,而无需重新设计基础环境。 可能的未来叠加层包括:
```
compose.ollama.yaml
compose.bedrock.yaml
```
其中,本地模型叠加层(Ollama)是首要任务,因为它可以使环境完全自给自足,而不依赖付费 API。
### `mcp-config.yaml`
定义 MCP 数据库服务器并提供其 PostgreSQL 连接配置。
MCP 网关使用此文件启动数据库 MCP 服务器,并公开其工具以供 Spring AI 使用。
### `.env`
包含不提交的本地环境值,尤其是:
```
OPENAI_API_KEY=<your-key>
```
Docker Compose 在从仓库根目录调用时自动读取该文件。
## 当前开发状态
已完成:
- 容器化 PostgreSQL 数据库
- Chinook 数据库导入
- MCP 数据库工具
- Spring Boot REST 服务
- Spring AI 和 OpenAI 集成
- 自然语言数据库问题
- Docker 健康检查和启动排序
未启动:
- Angular 控制台 UI(目前是一个未修改的脚手架)
- 在控制台中显示生成的 SQL 和工具跟踪
- 在控制台中显示原始查询结果
- 重复运行一致性比较
- 答案验证
- 本地模型(Ollama)叠加层
- 其他代理 / 多代理编排
- 第二个参考应用(NL-to-SQL 之外)
## 项目方向
该项目正在演变为 Java 中可重复使用的、低成本的本地环境,用于构建和测试企业级智能 AI 应用 —— 当前的 NL-to-SQL 代理作为第一个验证点,而不是最终目标。 近期重点是使系统的行为可检查(工具跟踪、生成的 SQL、重复运行比较),然后再添加更多代理或提供商,因为可观察性使“一个回答问题的代理”变成企业团队可以信任和构建的东西。
计划的方向包括:
- 控制台中可见的每个工具调用和生成的 SQL 语句的可见轨迹
- 重复运行一致性检查,以捕获和诊断不确定性
- 本地模型(Ollama)叠加层,使环境无成本且完全离线可用
- 在相同的 Compose 基础上构建第二个参考应用(例如,电子表格或文档数据提取),以证明环境在 NL-to-SQL 之外的泛化能力
- 多代理编排,动机是具体的需要(例如,验证代理检查主代理的 SQL,然后再返回答案),而不是为了其本身而添加
- 生产部署模式,一旦上述可观察性和验证工作就位
## 愿景
目标不仅仅是构建 AI 驱动的应用。 为开发团队提供所需的工具和架构模式,以便在 AI 辅助工作流到达生产之前理解、验证、观察并获得对其的信心 - 在开发环境中,该环境足够廉价和简单,实际上可以迭代。
此仓库作为开发和架构参考,而不是当前形式的生产就绪系统。