mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-09-13 08:25:00 +00:00
Compare commits
10 Commits
fd044a4752
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d439d1dcf | ||
|
|
0a08c489be | ||
|
|
038e7725f9 | ||
|
|
4ccf249663 | ||
|
|
1d5b01f77f | ||
|
|
538dac3a46 | ||
|
|
6c383dd9f5 | ||
|
|
9ae49f8797 | ||
|
|
3c175ba28d | ||
|
|
e34592c3d4 |
133
.github/workflows/publish-images.yml
vendored
Normal file
133
.github/workflows/publish-images.yml
vendored
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
name: Publish Docker Images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*.*.*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
description: Release tag to rebuild
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: publish-images-${{ inputs.release_tag || github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_OWNER: ${{ github.repository_owner }}
|
||||||
|
RELEASE_TAG: ${{ inputs.release_tag || github.ref_name }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
name: Publish ${{ matrix.image }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- image: ruoyi-ai-backend
|
||||||
|
source: local
|
||||||
|
context: .
|
||||||
|
dockerfile: docs/docker/ruoyi-ai/Dockerfile.backend
|
||||||
|
- image: ruoyi-ai-mysql
|
||||||
|
source: local
|
||||||
|
context: .
|
||||||
|
dockerfile: docs/docker/ruoyi-ai/Dockerfile.mysql
|
||||||
|
- image: ruoyi-ai-admin
|
||||||
|
source: admin
|
||||||
|
context: build/ruoyi-admin
|
||||||
|
dockerfile: build/ruoyi-admin/apps/web-antd/Dockerfile
|
||||||
|
- image: ruoyi-ai-web
|
||||||
|
source: web
|
||||||
|
context: build/ruoyi-web
|
||||||
|
dockerfile: build/ruoyi-web/Dockerfile.frontend
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout backend repository
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: ${{ env.RELEASE_TAG }}
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Checkout admin repository
|
||||||
|
if: matrix.source == 'admin'
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: ${{ github.repository_owner }}/ruoyi-admin
|
||||||
|
ref: ${{ env.RELEASE_TAG }}
|
||||||
|
path: build/ruoyi-admin
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Checkout web repository
|
||||||
|
if: matrix.source == 'web'
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
repository: ${{ github.repository_owner }}/ruoyi-web
|
||||||
|
ref: ${{ env.RELEASE_TAG }}
|
||||||
|
path: build/ruoyi-web
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- name: Configure frontend dependency builds
|
||||||
|
if: matrix.source == 'admin' || matrix.source == 'web'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
python3 - "${{ matrix.dockerfile }}" <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
dockerfile = Path(sys.argv[1])
|
||||||
|
content = dockerfile.read_text()
|
||||||
|
marker = "pnpm install --frozen-lockfile"
|
||||||
|
replacement = (
|
||||||
|
"pnpm install --frozen-lockfile "
|
||||||
|
"--config.dangerously-allow-all-builds=true"
|
||||||
|
)
|
||||||
|
if marker not in content:
|
||||||
|
raise SystemExit(f"pnpm install command not found in {dockerfile}")
|
||||||
|
dockerfile.write_text(content.replace(marker, replacement, 1))
|
||||||
|
PY
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ matrix.image }}
|
||||||
|
tags: |
|
||||||
|
type=raw,value=${{ env.RELEASE_TAG }}
|
||||||
|
type=raw,value=latest
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||||
|
org.opencontainers.image.version=${{ env.RELEASE_TAG }}
|
||||||
|
|
||||||
|
- name: Build and push image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: ${{ matrix.context }}
|
||||||
|
file: ${{ matrix.dockerfile }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha,scope=${{ matrix.image }}
|
||||||
|
cache-to: type=gha,mode=max,scope=${{ matrix.image }}
|
||||||
|
provenance: true
|
||||||
|
sbom: true
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,6 +23,9 @@ target/
|
|||||||
.idea
|
.idea
|
||||||
.claude
|
.claude
|
||||||
.github
|
.github
|
||||||
|
!.github/
|
||||||
|
!.github/workflows/
|
||||||
|
!.github/workflows/**
|
||||||
*.iws
|
*.iws
|
||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
|
|||||||
80
README.md
80
README.md
@@ -23,7 +23,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## 🚀 Live Demo
|
||||||
|
|
||||||
|
| Service | URL | Default Account |
|
||||||
|
|---|---|---|
|
||||||
|
| Admin Panel | http://129.226.199.247:25666 | admin / admin123 |
|
||||||
|
| User Frontend | http://129.226.199.247:25137 | admin / admin123 |
|
||||||
|
| Commercial Edition | https://web.ruoyiai.chat | WeChat QR code login |
|
||||||
|
|
||||||
## ✨ Core Features
|
## ✨ Core Features
|
||||||
|
|
||||||
@@ -71,22 +77,42 @@ This project provides two Docker deployment methods:
|
|||||||
Use `docker-compose-all.yaml` to start all services at once (including backend, admin panel, user frontend, and dependencies):
|
Use `docker-compose-all.yaml` to start all services at once (including backend, admin panel, user frontend, and dependencies):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Requirements: Docker Engine and Docker Compose V2
|
||||||
git clone https://github.com/ageerle/ruoyi-ai.git
|
|
||||||
|
# Clone the v3.1.0 release
|
||||||
|
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
|
||||||
cd ruoyi-ai
|
cd ruoyi-ai
|
||||||
|
|
||||||
# Start all services (pull pre-built images from registry)
|
# Pin the image version. Public GHCR images do not require docker login.
|
||||||
docker-compose -f docker-compose-all.yaml up -d
|
cp docs/docker/ruoyi-ai/.env.example docs/docker/ruoyi-ai/.env
|
||||||
|
sed -i 's/^RUIYI_VERSION=.*/RUIYI_VERSION=v3.1.0/' docs/docker/ruoyi-ai/.env
|
||||||
|
|
||||||
|
# Pull pre-built images from GHCR and start all services
|
||||||
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml pull
|
||||||
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml up -d
|
||||||
|
|
||||||
# Check service status
|
# Check service status
|
||||||
docker-compose -f docker-compose-all.yaml ps
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml ps
|
||||||
|
|
||||||
# Access services
|
# Access services (replace SERVER_IP with the server address)
|
||||||
# Admin Panel: http://localhost:25666 (admin / admin123)
|
# Admin Panel: http://SERVER_IP:25666 (admin / admin123)
|
||||||
# User Frontend: http://localhost:25137
|
# User Frontend: http://SERVER_IP:25137
|
||||||
# Backend API: http://localhost:26039
|
# Backend API: http://SERVER_IP:26039
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The default Compose file also publishes MySQL (`23306`), Redis (`26379`),
|
||||||
|
Weaviate (`28080`), and MinIO (`29000`/`29090`). For production deployments,
|
||||||
|
change the default MySQL and MinIO passwords and expose only the application
|
||||||
|
ports through the firewall or a reverse proxy.
|
||||||
|
|
||||||
|
To upgrade to another published release, update `RUIYI_VERSION` in
|
||||||
|
`docs/docker/ruoyi-ai/.env`, then run `docker compose pull` and
|
||||||
|
`docker compose up -d` with the same `--env-file` and `-f` options. Do not use
|
||||||
|
`docker compose down -v` unless you intend to delete persistent data volumes.
|
||||||
|
|
||||||
### Method 2: Step-by-step Deployment (Source Build)
|
### Method 2: Step-by-step Deployment (Source Build)
|
||||||
|
|
||||||
If you need to build backend services from source, follow these steps:
|
If you need to build backend services from source, follow these steps:
|
||||||
@@ -143,36 +169,6 @@ docker-compose up -d --build
|
|||||||
| MinIO API | 29000 | 9000 | Object storage API |
|
| MinIO API | 29000 | 9000 | Object storage API |
|
||||||
| MinIO Console | 29090 | 9090 | Object storage console |
|
| MinIO Console | 29090 | 9090 | Object storage console |
|
||||||
|
|
||||||
### Image Registry
|
|
||||||
|
|
||||||
All images are hosted on Alibaba Cloud Container Registry:
|
|
||||||
|
|
||||||
```
|
|
||||||
crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
|
|
||||||
```
|
|
||||||
|
|
||||||
Available images:
|
|
||||||
- `mysql:v3` - MySQL database (includes initialization SQL)
|
|
||||||
- `redis:6.2` - Redis cache
|
|
||||||
- `weaviate:1.30.0` - Vector database
|
|
||||||
- `minio:latest` - Object storage
|
|
||||||
- `ruoyi-ai-backend:latest` - Backend service
|
|
||||||
- `ruoyi-ai-admin:latest` - Admin frontend
|
|
||||||
- `ruoyi-ai-web:latest` - User frontend
|
|
||||||
|
|
||||||
### Common Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Stop all services
|
|
||||||
docker-compose -f docker-compose-all.yaml down
|
|
||||||
|
|
||||||
# View service logs
|
|
||||||
docker-compose -f docker-compose-all.yaml logs -f [service-name]
|
|
||||||
|
|
||||||
# Restart a service
|
|
||||||
docker-compose -f docker-compose-all.yaml restart [service-name]
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📚 Documentation
|
## 📚 Documentation
|
||||||
|
|
||||||
Want to learn more about installation, deployment, configuration, and secondary development?
|
Want to learn more about installation, deployment, configuration, and secondary development?
|
||||||
@@ -234,9 +230,9 @@ Enjoy ByteDance's in-house Doubao models plus full-power open-source SOTA models
|
|||||||
<em>Join group for learning</em>
|
<em>Join group for learning</em>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="docs/image/wx06.png" alt="WeChat QR Code" width="200" height="200"><br>
|
<img src="docs/image/douyin.png" alt="Douyin QR Code" width="200" height="200"><br>
|
||||||
<strong>WeChat Tech Exchange Group</strong><br>
|
<strong>Douyin Video Tutorials</strong><br>
|
||||||
<em>Technical discussion</em>
|
<em>Open Douyin, scan & follow to watch video tutorials</em>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="docs/image/qq.png" alt="QQ Group QR Code" width="200" height="200"><br>
|
<img src="docs/image/qq.png" alt="QQ Group QR Code" width="200" height="200"><br>
|
||||||
|
|||||||
79
README_ZH.md
79
README_ZH.md
@@ -23,6 +23,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
## 🚀 演示地址
|
||||||
|
|
||||||
|
| 服务 | 访问地址 | 默认账号 |
|
||||||
|
|---|---|---|
|
||||||
|
| 管理端 | http://129.226.199.247:25666 | admin / admin123 |
|
||||||
|
| 用户端 | http://129.226.199.247:25137 | admin / admin123 |
|
||||||
|
| 商业版 | https://web.ruoyiai.chat | 微信扫码登录 |
|
||||||
|
|
||||||
## ✨ 核心亮点
|
## ✨ 核心亮点
|
||||||
|
|
||||||
| 模块 | 现有能力
|
| 模块 | 现有能力
|
||||||
@@ -70,22 +78,39 @@
|
|||||||
使用 `docker-compose-all.yaml` 可以一键启动所有服务(包括后端、管理端、用户端及依赖服务):
|
使用 `docker-compose-all.yaml` 可以一键启动所有服务(包括后端、管理端、用户端及依赖服务):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 克隆仓库
|
# 环境要求:Docker Engine 和 Docker Compose V2
|
||||||
git clone https://github.com/ageerle/ruoyi-ai.git
|
|
||||||
|
# 克隆 v3.1.0 版本
|
||||||
|
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
|
||||||
cd ruoyi-ai
|
cd ruoyi-ai
|
||||||
|
|
||||||
# 启动所有服务(从镜像仓库拉取预构建镜像)
|
# 固定镜像版本。GHCR 镜像已公开,无需 docker login
|
||||||
docker-compose -f docker-compose-all.yaml up -d
|
cp docs/docker/ruoyi-ai/.env.example docs/docker/ruoyi-ai/.env
|
||||||
|
sed -i 's/^RUIYI_VERSION=.*/RUIYI_VERSION=v3.1.0/' docs/docker/ruoyi-ai/.env
|
||||||
|
|
||||||
|
# 从 GHCR 拉取预构建镜像并启动全部服务
|
||||||
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml pull
|
||||||
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml up -d
|
||||||
|
|
||||||
# 查看服务状态
|
# 查看服务状态
|
||||||
docker-compose -f docker-compose-all.yaml ps
|
docker compose --env-file docs/docker/ruoyi-ai/.env \
|
||||||
|
-f docs/docker/ruoyi-ai/docker-compose-all.yaml ps
|
||||||
|
|
||||||
# 访问服务
|
# 访问服务(将 SERVER_IP 替换为服务器地址)
|
||||||
# 管理端: http://localhost:25666 (admin / admin123)
|
# 管理端: http://SERVER_IP:25666 (admin / admin123)
|
||||||
# 用户端: http://localhost:25137
|
# 用户端: http://SERVER_IP:25137
|
||||||
# 后端API: http://localhost:26039
|
# 后端API: http://SERVER_IP:26039
|
||||||
```
|
```
|
||||||
|
|
||||||
|
默认 Compose 还会发布 MySQL(`23306`)、Redis(`26379`)、Weaviate(`28080`)和
|
||||||
|
MinIO(`29000`/`29090`)端口。生产环境请修改 MySQL 和 MinIO 默认密码,并通过防火墙或反向代理只开放应用端口。
|
||||||
|
|
||||||
|
升级到其他已发布版本时,修改 `docs/docker/ruoyi-ai/.env` 中的 `RUIYI_VERSION`,然后使用相同的
|
||||||
|
`--env-file` 和 `-f` 参数执行 `docker compose pull`、`docker compose up -d`。除非确定要删除持久化数据卷,
|
||||||
|
不要执行 `docker compose down -v`。
|
||||||
|
|
||||||
### 方式二:分步部署(源码编译)
|
### 方式二:分步部署(源码编译)
|
||||||
|
|
||||||
如果您需要从源码构建后端服务,请按照以下步骤操作:
|
如果您需要从源码构建后端服务,请按照以下步骤操作:
|
||||||
@@ -142,36 +167,6 @@ docker-compose up -d --build
|
|||||||
| MinIO API | 29000 | 9000 | 对象存储 API |
|
| MinIO API | 29000 | 9000 | 对象存储 API |
|
||||||
| MinIO Console | 29090 | 9090 | 对象存储控制台 |
|
| MinIO Console | 29090 | 9090 | 对象存储控制台 |
|
||||||
|
|
||||||
### 镜像仓库
|
|
||||||
|
|
||||||
所有镜像托管在阿里云容器镜像服务:
|
|
||||||
|
|
||||||
```
|
|
||||||
crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
|
|
||||||
```
|
|
||||||
|
|
||||||
可用镜像:
|
|
||||||
- `mysql:v3` - MySQL 数据库(包含初始化 SQL)
|
|
||||||
- `redis:6.2` - Redis 缓存
|
|
||||||
- `weaviate:1.30.0` - 向量数据库
|
|
||||||
- `minio:latest` - 对象存储
|
|
||||||
- `ruoyi-ai-backend:latest` - 后端服务
|
|
||||||
- `ruoyi-ai-admin:latest` - 管理端前端
|
|
||||||
- `ruoyi-ai-web:latest` - 用户端前端
|
|
||||||
|
|
||||||
### 常用命令
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 停止所有服务
|
|
||||||
docker-compose -f docker-compose-all.yaml down
|
|
||||||
|
|
||||||
# 查看服务日志
|
|
||||||
docker-compose -f docker-compose-all.yaml logs -f [服务名]
|
|
||||||
|
|
||||||
# 重启某个服务
|
|
||||||
docker-compose -f docker-compose-all.yaml restart [服务名]
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📚 使用文档
|
## 📚 使用文档
|
||||||
|
|
||||||
想要深入了解安装部署、功能配置和二次开发?
|
想要深入了解安装部署、功能配置和二次开发?
|
||||||
@@ -235,9 +230,9 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
|
|||||||
<em>邀请进群学习</em>
|
<em>邀请进群学习</em>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="docs/image/wx06.png" alt="微信二维码" width="200" height="200"><br>
|
<img src="docs/image/douyin.png" alt="抖音二维码" width="200" height="200"><br>
|
||||||
<strong>微信技术交流群</strong><br>
|
<strong>抖音视频教程</strong><br>
|
||||||
<em>技术讨论</em>
|
<em>打开抖音扫一扫,关注查看视频教程</em>
|
||||||
</td>
|
</td>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<img src="docs/image/qq.png" alt="QQ群二维码" width="200" height="200"><br>
|
<img src="docs/image/qq.png" alt="QQ群二维码" width="200" height="200"><br>
|
||||||
|
|||||||
6
docs/docker/ruoyi-ai/.env.example
Normal file
6
docs/docker/ruoyi-ai/.env.example
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# GitHub Container Registry namespace owner.
|
||||||
|
# For the upstream project this is ageerle; change it when using a fork.
|
||||||
|
IMAGE_OWNER=ageerle
|
||||||
|
|
||||||
|
# Use latest for convenience, or pin a release such as v3.1.0.
|
||||||
|
RUIYI_VERSION=latest
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
# - RuoYi-Admin (管理端前端)
|
# - RuoYi-Admin (管理端前端)
|
||||||
# - RuoYi-Web (用户端前端)
|
# - RuoYi-Web (用户端前端)
|
||||||
#
|
#
|
||||||
# 镜像仓库地址: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
|
# 镜像仓库地址: ghcr.io/ageerle
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ==================== MySQL 数据库 ====================
|
# ==================== MySQL 数据库 ====================
|
||||||
mysql:
|
mysql:
|
||||||
# 阿里云镜像地址(包含初始化SQL)
|
# GHCR 镜像(包含初始化SQL)
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/mysql:v3
|
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-mysql:${RUIYI_VERSION:-latest}
|
||||||
container_name: ruoyi-ai-mysql
|
container_name: ruoyi-ai-mysql
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -41,7 +41,7 @@ services:
|
|||||||
|
|
||||||
# ==================== Redis 缓存 ====================
|
# ==================== Redis 缓存 ====================
|
||||||
redis:
|
redis:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/redis:6.2
|
image: redis:6.2
|
||||||
container_name: ruoyi-ai-redis
|
container_name: ruoyi-ai-redis
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -59,7 +59,7 @@ services:
|
|||||||
|
|
||||||
# ==================== Weaviate 向量数据库 ====================
|
# ==================== Weaviate 向量数据库 ====================
|
||||||
weaviate:
|
weaviate:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/weaviate:1.30.0
|
image: semitechnologies/weaviate:1.30.0
|
||||||
container_name: ruoyi-ai-weaviate
|
container_name: ruoyi-ai-weaviate
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -78,7 +78,7 @@ services:
|
|||||||
|
|
||||||
# ==================== MinIO 对象存储 ====================
|
# ==================== MinIO 对象存储 ====================
|
||||||
minio:
|
minio:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/minio:latest
|
image: minio/minio:latest
|
||||||
container_name: ruoyi-ai-minio
|
container_name: ruoyi-ai-minio
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -95,7 +95,7 @@ services:
|
|||||||
|
|
||||||
# ==================== RuoYi-AI 后端服务 ====================
|
# ==================== RuoYi-AI 后端服务 ====================
|
||||||
backend:
|
backend:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-backend:latest
|
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-backend:${RUIYI_VERSION:-latest}
|
||||||
container_name: ruoyi-ai-backend
|
container_name: ruoyi-ai-backend
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -129,7 +129,7 @@ services:
|
|||||||
|
|
||||||
# ==================== RuoYi-AI 管理端前端 ====================
|
# ==================== RuoYi-AI 管理端前端 ====================
|
||||||
admin-frontend:
|
admin-frontend:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-admin:latest
|
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-admin:${RUIYI_VERSION:-latest}
|
||||||
container_name: ruoyi-ai-admin
|
container_name: ruoyi-ai-admin
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
@@ -154,7 +154,7 @@ services:
|
|||||||
|
|
||||||
# ==================== RuoYi-AI 用户端前端 ====================
|
# ==================== RuoYi-AI 用户端前端 ====================
|
||||||
web-frontend:
|
web-frontend:
|
||||||
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-web:latest
|
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-web:${RUIYI_VERSION:-latest}
|
||||||
container_name: ruoyi-ai-web
|
container_name: ruoyi-ai-web
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
BIN
docs/image/douyin.png
Normal file
BIN
docs/image/douyin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 276 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 156 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 112 KiB |
File diff suppressed because it is too large
Load Diff
5
pom.xml
5
pom.xml
@@ -43,7 +43,6 @@
|
|||||||
<aws.sdk.version>2.28.22</aws.sdk.version>
|
<aws.sdk.version>2.28.22</aws.sdk.version>
|
||||||
<!-- SMS 配置 -->
|
<!-- SMS 配置 -->
|
||||||
<sms4j.version>3.3.5</sms4j.version>
|
<sms4j.version>3.3.5</sms4j.version>
|
||||||
<!-- FastJson已移除,使用Jackson替代 -->
|
|
||||||
<!-- 面向运行时的D-ORM依赖 -->
|
<!-- 面向运行时的D-ORM依赖 -->
|
||||||
<anyline.version>8.7.2-20250603</anyline.version>
|
<anyline.version>8.7.2-20250603</anyline.version>
|
||||||
<!-- 工作流配置 -->
|
<!-- 工作流配置 -->
|
||||||
@@ -62,6 +61,8 @@
|
|||||||
<weaviate.version>1.19.6</weaviate.version>
|
<weaviate.version>1.19.6</weaviate.version>
|
||||||
<dify.version>1.2.7</dify.version>
|
<dify.version>1.2.7</dify.version>
|
||||||
<coze.version>0.4.2</coze.version>
|
<coze.version>0.4.2</coze.version>
|
||||||
|
<!-- 智谱官方 Java SDK -->
|
||||||
|
<zai-sdk.version>0.3.5</zai-sdk.version>
|
||||||
|
|
||||||
<!-- gRPC 版本 - 解决 Milvus SDK 依赖冲突 -->
|
<!-- gRPC 版本 - 解决 Milvus SDK 依赖冲突 -->
|
||||||
<grpc.version>1.62.2</grpc.version>
|
<grpc.version>1.62.2</grpc.version>
|
||||||
@@ -342,8 +343,6 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- JustAuth 的依赖配置-->
|
<!-- JustAuth 的依赖配置-->
|
||||||
<!-- 排除 fastjson(存在 RCE 漏洞且已停止维护), 项目内自定义的登录类(钉钉/企业微信/gitea/maxkey/topiam)已改用 Jackson -->
|
|
||||||
<!-- 注意: JustAuth 内置平台类(github/gitee/qq 等)内部仍使用 fastjson, 排除后如需使用这些平台请自行覆写对应请求类 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.zhyd.oauth</groupId>
|
<groupId>me.zhyd.oauth</groupId>
|
||||||
<artifactId>JustAuth</artifactId>
|
<artifactId>JustAuth</artifactId>
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
<artifactId>ruoyi-common-sse</artifactId>
|
<artifactId>ruoyi-common-sse</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- FastJson已移除,使用Spring Boot自带的Jackson -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ public abstract class AbstractAuthWeChatEnterpriseRequest extends AuthDefaultReq
|
|||||||
String userTicket = object.has("user_ticket") ? object.get("user_ticket").asText() : null;
|
String userTicket = object.has("user_ticket") ? object.get("user_ticket").asText() : null;
|
||||||
JsonNode userDetail = getUserDetail(authToken.getAccessToken(), userId, userTicket);
|
JsonNode userDetail = getUserDetail(authToken.getAccessToken(), userId, userTicket);
|
||||||
|
|
||||||
// rawUserInfo 为 JustAuth 的 fastjson 类型字段, 项目内无消费方, 不再设置
|
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.username(userDetail.has("name") ? userDetail.get("name").asText() : null)
|
.username(userDetail.has("name") ? userDetail.get("name").asText() : null)
|
||||||
.nickname(userDetail.has("alias") ? userDetail.get("alias").asText() : null)
|
.nickname(userDetail.has("alias") ? userDetail.get("alias").asText() : null)
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ public class AuthDingTalkV2Request extends AuthDefaultRequest {
|
|||||||
|
|
||||||
authToken.setOpenId(object.has("openId") ? object.get("openId").asText() : null);
|
authToken.setOpenId(object.has("openId") ? object.get("openId").asText() : null);
|
||||||
authToken.setUnionId(object.has("unionId") ? object.get("unionId").asText() : null);
|
authToken.setUnionId(object.has("unionId") ? object.get("unionId").asText() : null);
|
||||||
// rawUserInfo 为 JustAuth 的 fastjson 类型字段, 项目内无消费方, 不再设置
|
|
||||||
return AuthUser.builder()
|
return AuthUser.builder()
|
||||||
.uuid(object.has("unionId") ? object.get("unionId").asText() : null)
|
.uuid(object.has("unionId") ? object.get("unionId").asText() : null)
|
||||||
.username(object.has("nick") ? object.get("nick").asText() : null)
|
.username(object.has("nick") ? object.get("nick").asText() : null)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ai.z.openapi</groupId>
|
<groupId>ai.z.openapi</groupId>
|
||||||
<artifactId>zai-sdk</artifactId>
|
<artifactId>zai-sdk</artifactId>
|
||||||
<version>0.3.5</version>
|
<version>${zai-sdk.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -126,6 +126,7 @@
|
|||||||
<version>${langchain4j.version}</version>
|
<version>${langchain4j.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>jsoup</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
@@ -145,8 +146,6 @@
|
|||||||
<version>${langgraph4j.version}</version>
|
<version>${langgraph4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.ruoyi.trace;
|
package org.ruoyi.argtrace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RAG trace 业务与节点类型常量。
|
* RAG trace 业务与节点类型常量。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.ruoyi.trace;
|
package org.ruoyi.argtrace;
|
||||||
|
|
||||||
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
|
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
|
||||||
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
||||||
@@ -48,11 +48,11 @@ public class McpToolController extends BaseController {
|
|||||||
*/
|
*/
|
||||||
@SaCheckPermission("mcp:tool:list")
|
@SaCheckPermission("mcp:tool:list")
|
||||||
@GetMapping("/all")
|
@GetMapping("/all")
|
||||||
public McpToolListResult listAll(
|
public R<McpToolListResult> listAll(
|
||||||
@RequestParam(required = false) String keyword,
|
@RequestParam(required = false) String keyword,
|
||||||
@RequestParam(required = false) String type,
|
@RequestParam(required = false) String type,
|
||||||
@RequestParam(required = false) String status) {
|
@RequestParam(required = false) String status) {
|
||||||
return mcpToolService.listTools(keyword, type, status);
|
return R.ok(mcpToolService.listTools(keyword, type, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ import org.ruoyi.service.chat.impl.memory.PersistentChatMemoryStore;
|
|||||||
import org.ruoyi.service.knowledge.IKnowledgeInfoService;
|
import org.ruoyi.service.knowledge.IKnowledgeInfoService;
|
||||||
import org.ruoyi.service.retrieval.KnowledgeRetrievalService;
|
import org.ruoyi.service.retrieval.KnowledgeRetrievalService;
|
||||||
import org.ruoyi.service.knowledge.retriever.CustomVectorRetriever;
|
import org.ruoyi.service.knowledge.retriever.CustomVectorRetriever;
|
||||||
import org.ruoyi.trace.RagTraceNodeTypes;
|
import org.ruoyi.argtrace.RagTraceNodeTypes;
|
||||||
import org.ruoyi.trace.RagTracePayloadBuilder;
|
import org.ruoyi.argtrace.RagTracePayloadBuilder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ public class ChatServiceFacade implements IChatService {
|
|||||||
.subAgents(skillsAgent, searchAgent, sqlAgent, chartGenerationAgent, echartsAgent, chitChatAgent)
|
.subAgents(skillsAgent, searchAgent, sqlAgent, chartGenerationAgent, echartsAgent, chitChatAgent)
|
||||||
.supervisorContext("仅当请求是问候或简单闲聊、不需要任何数据、搜索、技能或图表时,才使用 chitChatAgent;"
|
.supervisorContext("仅当请求是问候或简单闲聊、不需要任何数据、搜索、技能或图表时,才使用 chitChatAgent;"
|
||||||
+ "其余情况必须使用对应的专业 Agent")
|
+ "其余情况必须使用对应的专业 Agent")
|
||||||
.responseStrategy(SupervisorResponseStrategy.SUMMARY);
|
.responseStrategy(SupervisorResponseStrategy.LAST);
|
||||||
SupervisorAgent supervisor = supervisorBuilder.build();
|
SupervisorAgent supervisor = supervisorBuilder.build();
|
||||||
|
|
||||||
// 知识库增强:智能体绑定了知识库时,对 supervisor 输入做一次 RAG 增强(全程唯一一次检索)
|
// 知识库增强:智能体绑定了知识库时,对 supervisor 输入做一次 RAG 增强(全程唯一一次检索)
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import org.ruoyi.mapper.knowledge.KnowledgeFragmentMapper;
|
|||||||
import org.ruoyi.service.rerank.RerankModelService;
|
import org.ruoyi.service.rerank.RerankModelService;
|
||||||
import org.ruoyi.service.retrieval.KnowledgeRetrievalService;
|
import org.ruoyi.service.retrieval.KnowledgeRetrievalService;
|
||||||
import org.ruoyi.service.vector.VectorStoreService;
|
import org.ruoyi.service.vector.VectorStoreService;
|
||||||
import org.ruoyi.trace.RagTraceNodeTypes;
|
import org.ruoyi.argtrace.RagTraceNodeTypes;
|
||||||
import org.ruoyi.trace.RagTracePayloadBuilder;
|
import org.ruoyi.argtrace.RagTracePayloadBuilder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -128,7 +128,7 @@ public class KnowledgeRetrievalServiceImpl implements KnowledgeRetrievalService
|
|||||||
// 如果启用重排序,适当扩大召回数量
|
// 如果启用重排序,适当扩大召回数量
|
||||||
int originalMaxResults = queryVectorBo.getMaxResults() != null ? queryVectorBo.getMaxResults() : 10;
|
int originalMaxResults = queryVectorBo.getMaxResults() != null ? queryVectorBo.getMaxResults() : 10;
|
||||||
int targetMaxResults = originalMaxResults;
|
int targetMaxResults = originalMaxResults;
|
||||||
if (Boolean.TRUE.equals(queryVectorBo.getEnableRerank()) &&
|
if (Boolean.TRUE.equals(queryVectorBo.getEnableRerank()) &&
|
||||||
StringUtils.isNotBlank(queryVectorBo.getRerankModelName())) {
|
StringUtils.isNotBlank(queryVectorBo.getRerankModelName())) {
|
||||||
targetMaxResults = originalMaxResults * RERANK_EXPANSION_FACTOR;
|
targetMaxResults = originalMaxResults * RERANK_EXPANSION_FACTOR;
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ public class KnowledgeRetrievalServiceImpl implements KnowledgeRetrievalService
|
|||||||
if (!Boolean.TRUE.equals(queryVectorBo.getEnableHybrid())) {
|
if (!Boolean.TRUE.equals(queryVectorBo.getEnableHybrid())) {
|
||||||
QueryVectorBo vectorQuery = copyOf(queryVectorBo, targetMaxResults);
|
QueryVectorBo vectorQuery = copyOf(queryVectorBo, targetMaxResults);
|
||||||
List<KnowledgeRetrievalVo> results = vectorStoreService.search(vectorQuery);
|
List<KnowledgeRetrievalVo> results = vectorStoreService.search(vectorQuery);
|
||||||
|
|
||||||
// 应用基础相似度阈值过滤(如果有)
|
// 应用基础相似度阈值过滤(如果有)
|
||||||
if (queryVectorBo.getSimilarityThreshold() != null) {
|
if (queryVectorBo.getSimilarityThreshold() != null) {
|
||||||
results = results.stream()
|
results = results.stream()
|
||||||
@@ -214,7 +214,7 @@ public class KnowledgeRetrievalServiceImpl implements KnowledgeRetrievalService
|
|||||||
rerankInputPayload);
|
rerankInputPayload);
|
||||||
try {
|
try {
|
||||||
RerankModelService rerankModel = rerankModelFactory.createModel(queryVectorBo.getRerankModelName());
|
RerankModelService rerankModel = rerankModelFactory.createModel(queryVectorBo.getRerankModelName());
|
||||||
|
|
||||||
List<String> contents = coarseResults.stream()
|
List<String> contents = coarseResults.stream()
|
||||||
.map(KnowledgeRetrievalVo::getContent)
|
.map(KnowledgeRetrievalVo::getContent)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -241,7 +241,7 @@ public class KnowledgeRetrievalServiceImpl implements KnowledgeRetrievalService
|
|||||||
|
|
||||||
// 按新分排序
|
// 按新分排序
|
||||||
reranked.sort((a, b) -> b.getScore().compareTo(a.getScore()));
|
reranked.sort((a, b) -> b.getScore().compareTo(a.getScore()));
|
||||||
|
|
||||||
// 截断到 topN
|
// 截断到 topN
|
||||||
List<KnowledgeRetrievalVo> results = reranked.subList(0, Math.min(topN, reranked.size()));
|
List<KnowledgeRetrievalVo> results = reranked.subList(0, Math.min(topN, reranked.size()));
|
||||||
finishTraceNode(traceNode, TraceConstants.STATUS_SUCCESS, null,
|
finishTraceNode(traceNode, TraceConstants.STATUS_SUCCESS, null,
|
||||||
@@ -285,9 +285,9 @@ public class KnowledgeRetrievalServiceImpl implements KnowledgeRetrievalService
|
|||||||
List<KnowledgeRetrievalVo> fusedResults = new ArrayList<>();
|
List<KnowledgeRetrievalVo> fusedResults = new ArrayList<>();
|
||||||
for (Map.Entry<String, KnowledgeRetrievalVo> entry : allMap.entrySet()) {
|
for (Map.Entry<String, KnowledgeRetrievalVo> entry : allMap.entrySet()) {
|
||||||
String id = entry.getKey();
|
String id = entry.getKey();
|
||||||
double finalScore = (1 - alpha) * vectorScores.getOrDefault(id, 0.0) +
|
double finalScore = (1 - alpha) * vectorScores.getOrDefault(id, 0.0) +
|
||||||
alpha * keywordScores.getOrDefault(id, 0.0);
|
alpha * keywordScores.getOrDefault(id, 0.0);
|
||||||
|
|
||||||
KnowledgeRetrievalVo vo = entry.getValue();
|
KnowledgeRetrievalVo vo = entry.getValue();
|
||||||
vo.setScore(finalScore * 60.0); // 归一化缩放
|
vo.setScore(finalScore * 60.0); // 归一化缩放
|
||||||
fusedResults.add(vo);
|
fusedResults.add(vo);
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
package org.ruoyi.trace;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
|
|
||||||
import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
|
|
||||||
import org.ruoyi.domain.bo.vector.QueryVectorBo;
|
|
||||||
import org.ruoyi.domain.vo.knowledge.KnowledgeRetrievalVo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
class RagTracePayloadBuilderTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void chatRequestSummaryShouldHandleNullsAndAvoidPromptBody() {
|
|
||||||
ChatRequest request = new ChatRequest();
|
|
||||||
request.setSessionId(100L);
|
|
||||||
request.setModel("qwen-plus");
|
|
||||||
request.setKnowledgeId("200");
|
|
||||||
request.setContent("secret prompt body");
|
|
||||||
|
|
||||||
ChatModelVo model = new ChatModelVo();
|
|
||||||
model.setProviderCode("dashscope");
|
|
||||||
request.setChatModelVo(model);
|
|
||||||
|
|
||||||
String payload = RagTracePayloadBuilder.chatRequestSummary(request);
|
|
||||||
|
|
||||||
assertTrue(payload.contains("\"sessionId\":100"));
|
|
||||||
assertTrue(payload.contains("\"contentLength\":18"));
|
|
||||||
assertTrue(payload.contains("\"providerCode\":\"dashscope\""));
|
|
||||||
assertFalse(payload.contains("secret prompt body"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void retrievalInputSummaryShouldUseSummaryOnly() {
|
|
||||||
QueryVectorBo query = new QueryVectorBo();
|
|
||||||
query.setKid("200");
|
|
||||||
query.setQuery("private retrieval query");
|
|
||||||
query.setMaxResults(5);
|
|
||||||
query.setEnableRerank(true);
|
|
||||||
query.setRerankModelName("gte-rerank");
|
|
||||||
query.setRerankTopN(null);
|
|
||||||
|
|
||||||
String payload = RagTracePayloadBuilder.retrievalInputSummary(query);
|
|
||||||
|
|
||||||
assertTrue(payload.contains("\"kid\":\"200\""));
|
|
||||||
assertTrue(payload.contains("\"queryLength\":23"));
|
|
||||||
assertTrue(payload.contains("\"enableRerank\":true"));
|
|
||||||
assertFalse(payload.contains("private retrieval query"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void retrievalOutputSummaryShouldAvoidFragmentContent() {
|
|
||||||
KnowledgeRetrievalVo result = new KnowledgeRetrievalVo();
|
|
||||||
result.setId("fragment-1");
|
|
||||||
result.setDocId("doc-1");
|
|
||||||
result.setIdx(1);
|
|
||||||
result.setScore(0.85);
|
|
||||||
result.setContent("sensitive knowledge fragment");
|
|
||||||
|
|
||||||
String payload = RagTracePayloadBuilder.retrievalOutputSummary(List.of(result));
|
|
||||||
|
|
||||||
assertTrue(payload.contains("\"resultCount\":1"));
|
|
||||||
assertTrue(payload.contains("\"contentLength\":28"));
|
|
||||||
assertTrue(payload.contains("\"fragment-1\""));
|
|
||||||
assertFalse(payload.contains("sensitive knowledge fragment"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void summariesShouldAcceptNullValuesWithoutMapOfNpe() {
|
|
||||||
assertTrue(RagTracePayloadBuilder.chatRequestSummary(null).contains("\"requestPresent\":false"));
|
|
||||||
assertTrue(RagTracePayloadBuilder.retrievalInputSummary(null).contains("\"queryPresent\":false"));
|
|
||||||
assertTrue(RagTracePayloadBuilder.retrievalOutputSummary(null).contains("\"resultCount\":0"));
|
|
||||||
assertTrue(RagTracePayloadBuilder.rerankInputSummary(null, 0, null).contains("\"candidateCount\":0"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user