feat: initial ragserver - web app skeleton with data models, CRUD, and build scripts
- ahserver web app on port 9190 - DB: rag (test/test123, utf8mb4) - 7 data models: knowledge_bases, documents, document_chunks, entities, entity_relations, subscriptions, engine_configs, usage_logs - 4 CRUD definitions: knowledge_bases, documents, subscriptions, engine_configs - build.sh clones all foundation modules + rag-pipeline + services - independent venv, bricks frontend, RBAC support
This commit is contained in:
parent
98d977d848
commit
254bf8e9b2
3
.env
Normal file
3
.env
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# RAG Server environment
|
||||||
|
SAGE_RBAC_DB=rag
|
||||||
|
PYTHONPATH=$PWD:$PWD/pkgs/apppublic:$PWD/pkgs/sqlor:$PWD/pkgs/ahserver:$PWD/pkgs/rbac:$PWD/pkgs/rag-pipeline
|
||||||
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Runtime
|
||||||
|
py3/
|
||||||
|
*.pid
|
||||||
|
logs/
|
||||||
|
files/
|
||||||
|
pkgs/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
wwwroot/bricks/
|
||||||
|
wwwroot/*_list/
|
||||||
|
mysql.ddl.sql
|
||||||
|
models/mysql.ddl.sql
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
67
README.md
67
README.md
@ -1,2 +1,67 @@
|
|||||||
# ragserver
|
# RAG Server — 多媒体知识库 SaaS 平台
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
RagServer 是一个独立的多媒体 RAG (检索增强生成) SaaS Web 应用。支持文本、图片、音频、视频文件的拖拽上传,自动向量化入库,人脸识别,声纹识别,知识图谱构建,以及统一的混合检索。
|
||||||
|
|
||||||
|
## 架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ RagServer (:9190) │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ RBAC 鉴权 │ │ 订阅容量 │ │ 拖拽上传 UI │ │
|
||||||
|
│ │ 多租户隔离 │ │ quota 管控│ │ 知识库/文档 CRUD │ │
|
||||||
|
│ └──────────┘ └──────────┘ └──────────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌──────────┴──────────┐ │
|
||||||
|
│ │ rag-pipeline 引擎 │ │
|
||||||
|
│ │ ingest / search │ │
|
||||||
|
│ └──────────┬──────────┘ │
|
||||||
|
└─────────────────────────┼───────────────────────────┘
|
||||||
|
│
|
||||||
|
┌─────────┬───────────┼───────────┬─────────┐
|
||||||
|
▼ ▼ ▼ ▼ ▼
|
||||||
|
┌───────┐ ┌───────┐ ┌─────────┐ ┌───────┐ ┌──────────┐
|
||||||
|
│ CLIP │ │ VDB │ │ Graph │ │Rerank │ │ Face │
|
||||||
|
│ 9086 │ │ 8886 │ │ 9092 │ │ 9090 │ │ 9091 │
|
||||||
|
└───────┘ └───────┘ └─────────┘ └───────┘ └──────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据库
|
||||||
|
|
||||||
|
- 数据库名: `rag`
|
||||||
|
- 用户: `test` / 密码: `test123`
|
||||||
|
- 字符集: `utf8mb4`
|
||||||
|
|
||||||
|
## 模块结构
|
||||||
|
|
||||||
|
| 模块 | 说明 | 仓库 |
|
||||||
|
|------|------|------|
|
||||||
|
| ragserver | 主 Web 应用 | yumoqing/ragserver |
|
||||||
|
| rag-pipeline | RAG 管线引擎 | yumoqing/rag-pipeline |
|
||||||
|
| clip_embedding | 多模态向量化 (CLIP ViT-H-14) | yumoqing/clip_embedding |
|
||||||
|
| vdb | 向量数据库 (Milvus Lite) | yumoqing/vdb |
|
||||||
|
| bge-reranker | 文本重排 (BGE Reranker v2-m3) | yumoqing/bge-reranker |
|
||||||
|
| face-service | 人脸识别 (InsightFace) | yumoqing/face-service |
|
||||||
|
| graph-service | 图数据库 (NetworkX) | yumoqing/graph-service |
|
||||||
|
| ner-service | 命名实体识别 (GLiNER) | yumoqing/ner-service |
|
||||||
|
| speaker-id | 声纹识别 (ECAPA-TDNN) | yumoqing/speaker-id |
|
||||||
|
|
||||||
|
## 部署
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 测试服务器
|
||||||
|
ssh apitest@tokentest.opencomputing.cn
|
||||||
|
cd ~/ragserver
|
||||||
|
git pull && bash build.sh && ./stop.sh && ./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据模型
|
||||||
|
|
||||||
|
- `knowledge_bases` — 知识库
|
||||||
|
- `documents` — 文档 (文本/图片/音频/视频)
|
||||||
|
- `document_chunks` — 文档分片
|
||||||
|
- `subscriptions` — 租户订阅 (磁盘容量/文档数/API调用量)
|
||||||
|
- `engine_configs` — 引擎配置 (支持租户级覆盖)
|
||||||
|
- `usage_logs` — 用量日志
|
||||||
|
|||||||
24
app/ragserver.py
Normal file
24
app/ragserver.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
from ahserver.webapp import webapp
|
||||||
|
from ahserver.serverenv import ServerEnv
|
||||||
|
|
||||||
|
|
||||||
|
def get_module_dbname(m):
|
||||||
|
return 'rag'
|
||||||
|
|
||||||
|
|
||||||
|
def password_encode(s):
|
||||||
|
if s is None:
|
||||||
|
return ''
|
||||||
|
from ahserver.globalEnv import password_encode as _orig
|
||||||
|
return _orig(s)
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
env = ServerEnv()
|
||||||
|
env.get_module_dbname = get_module_dbname
|
||||||
|
env.password_encode = password_encode
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
webapp(init)
|
||||||
86
build.sh
Executable file
86
build.sh
Executable file
@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cdir=$(cd "$(dirname "$0")"; pwd)
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
export SAGE_RBAC_DB=rag
|
||||||
|
|
||||||
|
# Virtualenv
|
||||||
|
if [ ! -d py3 ]; then
|
||||||
|
python3 -m venv py3
|
||||||
|
fi
|
||||||
|
source py3/bin/activate
|
||||||
|
|
||||||
|
# Install build tools
|
||||||
|
pip install -q xls2ddl
|
||||||
|
|
||||||
|
# pkgs directory
|
||||||
|
mkdir -p pkgs logs files
|
||||||
|
|
||||||
|
# Clone and install foundation modules
|
||||||
|
for repo in apppublic sqlor ahserver rbac appbase bricks-for-python; do
|
||||||
|
[ -d pkgs/$repo ] || git clone git@git.opencomputing.cn:yumoqing/$repo.git pkgs/$repo
|
||||||
|
pip install -q -e pkgs/$repo
|
||||||
|
done
|
||||||
|
|
||||||
|
# Clone and install rag-pipeline (core engine)
|
||||||
|
[ -d pkgs/rag-pipeline ] || git clone git@git.opencomputing.cn:yumoqing/rag-pipeline.git pkgs/rag-pipeline
|
||||||
|
pip install -q -e pkgs/rag-pipeline
|
||||||
|
|
||||||
|
# Clone service modules (for reference, not imported)
|
||||||
|
for svc in clip_embedding vdb bge-reranker face-service graph-service ner-service speaker-id; do
|
||||||
|
[ -d pkgs/$svc ] || git clone git@git.opencomputing.cn:yumoqing/$svc.git pkgs/$svc
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build bricks frontend
|
||||||
|
if [ ! -d pkgs/bricks ]; then
|
||||||
|
git clone git@git.opencomputing.cn:yumoqing/bricks.git pkgs/bricks
|
||||||
|
fi
|
||||||
|
mkdir -p pkgs/bricks/dist/i18n
|
||||||
|
cd pkgs/bricks
|
||||||
|
bash build.sh
|
||||||
|
cd $cdir
|
||||||
|
|
||||||
|
# Symlink bricks
|
||||||
|
ln -sf pkgs/bricks/dist wwwroot/bricks 2>/dev/null || true
|
||||||
|
|
||||||
|
# Install appbase and rbac
|
||||||
|
pip install -q -e pkgs/appbase
|
||||||
|
pip install -q -e pkgs/rbac
|
||||||
|
|
||||||
|
# Generate DDL from models
|
||||||
|
if ls models/*.json >/dev/null 2>&1; then
|
||||||
|
cd models
|
||||||
|
json2ddl mysql . > mysql.ddl.sql
|
||||||
|
mysql -h db -utest -ptest123 rag < mysql.ddl.sql 2>/dev/null || echo "DDL already applied or mysql not available"
|
||||||
|
cd $cdir
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate CRUD from json/
|
||||||
|
if ls json/*.json >/dev/null 2>&1; then
|
||||||
|
xls2ui -m models -o wwwroot ragserver json/*.json 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Symlink module wwwroots
|
||||||
|
for m in rag-pipeline; do
|
||||||
|
[ -d pkgs/$m/wwwroot ] && ln -sf ../pkgs/$m/wwwroot wwwroot/$m 2>/dev/null || true
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fix created_by in CRUD dspy files
|
||||||
|
if [ -d wwwroot/knowledge_bases_list ]; then
|
||||||
|
find wwwroot -name '*.dspy' -exec sed -i "s/ns\['created_by'\] = ''/ns['created_by'] = userorgid/" {} \; 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sync password_key from Sage if available
|
||||||
|
if [ -f /d/apitest/sage/conf/config.json ]; then
|
||||||
|
sage_key=$(python3 -c "import json; print(json.load(open('/d/apitest/sage/conf/config.json'))['password_key'])")
|
||||||
|
python3 -c "
|
||||||
|
import json
|
||||||
|
c = json.load(open('$cdir/conf/config.json'))
|
||||||
|
c['password_key'] = '$sage_key'
|
||||||
|
json.dump(c, open('$cdir/conf/config.json', 'w'), indent=4)
|
||||||
|
"
|
||||||
|
echo "password_key synced from Sage"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== RAG Server build complete ==="
|
||||||
54
conf/config.json
Normal file
54
conf/config.json
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"password_key": "RagServer2026Key",
|
||||||
|
"databases": {
|
||||||
|
"rag": {
|
||||||
|
"driver": "mysql+aiomysql",
|
||||||
|
"kwargs": {
|
||||||
|
"host": "db",
|
||||||
|
"port": 3306,
|
||||||
|
"user": "test",
|
||||||
|
"password": "test123",
|
||||||
|
"db": "rag",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"minsize": 2,
|
||||||
|
"maxsize": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SAGE_RBAC_DB": "rag",
|
||||||
|
"session_redis": {
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 6379,
|
||||||
|
"db": 1
|
||||||
|
},
|
||||||
|
"logger": {
|
||||||
|
"name": "ragserver",
|
||||||
|
"levelname": "info",
|
||||||
|
"logfile": "$[workdir]$/logs/ragserver.log"
|
||||||
|
},
|
||||||
|
"filesroot": "$[workdir]$/files",
|
||||||
|
"website": {
|
||||||
|
"paths": [
|
||||||
|
["$[workdir]$/wwwroot", ""]
|
||||||
|
],
|
||||||
|
"client_max_size": 524288000,
|
||||||
|
"host": "0.0.0.0",
|
||||||
|
"port": 9190,
|
||||||
|
"coding": "utf-8",
|
||||||
|
"indexes": [
|
||||||
|
"index.ui",
|
||||||
|
"index.html"
|
||||||
|
],
|
||||||
|
"processors": [
|
||||||
|
[".wss", "ws"],
|
||||||
|
[".ws", "ws"],
|
||||||
|
[".ui", "bui"],
|
||||||
|
[".dspy", "dspy"],
|
||||||
|
[".md", "md"]
|
||||||
|
],
|
||||||
|
"startswiths": [
|
||||||
|
{"leading": "/idfile", "registerfunction": "idfile"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hot_reload": true
|
||||||
|
}
|
||||||
25
json/documents.json
Normal file
25
json/documents.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"tblname": "documents",
|
||||||
|
"params": {
|
||||||
|
"title": "文档管理",
|
||||||
|
"browserfields": [
|
||||||
|
{"field": "file_name", "title": "文件名", "width": "25%"},
|
||||||
|
{"field": "file_type", "title": "类型", "width": "10%"},
|
||||||
|
{"field": "file_size", "title": "大小", "width": "10%"},
|
||||||
|
{"field": "chunk_count", "title": "分片数", "width": "8%"},
|
||||||
|
{"field": "status", "title": "状态", "width": "10%"},
|
||||||
|
{"field": "kb_id", "title": "知识库", "width": "17%"},
|
||||||
|
{"field": "created_at", "title": "上传时间", "width": "20%"}
|
||||||
|
],
|
||||||
|
"editfields": [
|
||||||
|
{"field": "file_name", "uitype": "Text", "required": true},
|
||||||
|
{"field": "kb_id", "uitype": "Text", "required": true},
|
||||||
|
{"field": "file_type", "uitype": "Text"}
|
||||||
|
],
|
||||||
|
"searchfields": ["file_name"],
|
||||||
|
"sort": "created_at desc",
|
||||||
|
"data_filter": {
|
||||||
|
"org_id": "{{userorgid}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
json/engine_configs.json
Normal file
26
json/engine_configs.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"tblname": "engine_configs",
|
||||||
|
"params": {
|
||||||
|
"title": "引擎配置",
|
||||||
|
"browserfields": [
|
||||||
|
{"field": "engine_type", "title": "引擎类型", "width": "15%"},
|
||||||
|
{"field": "engine_name", "title": "名称", "width": "15%"},
|
||||||
|
{"field": "endpoint_url", "title": "服务地址", "width": "25%"},
|
||||||
|
{"field": "model_name", "title": "模型", "width": "15%"},
|
||||||
|
{"field": "is_default", "title": "默认", "width": "8%"},
|
||||||
|
{"field": "status", "title": "状态", "width": "10%"},
|
||||||
|
{"field": "org_id", "title": "机构", "width": "12%"}
|
||||||
|
],
|
||||||
|
"editfields": [
|
||||||
|
{"field": "engine_type", "uitype": "Text", "required": true},
|
||||||
|
{"field": "engine_name", "uitype": "Text", "required": true},
|
||||||
|
{"field": "endpoint_url", "uitype": "Text"},
|
||||||
|
{"field": "api_key", "uitype": "Text"},
|
||||||
|
{"field": "model_name", "uitype": "Text"},
|
||||||
|
{"field": "is_default", "uitype": "Text"},
|
||||||
|
{"field": "config_json", "uitype": "Text"}
|
||||||
|
],
|
||||||
|
"searchfields": ["engine_type", "engine_name", "endpoint_url"],
|
||||||
|
"sort": "engine_type, priority desc"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
json/knowledge_bases.json
Normal file
26
json/knowledge_bases.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"tblname": "knowledge_bases",
|
||||||
|
"params": {
|
||||||
|
"title": "知识库管理",
|
||||||
|
"browserfields": [
|
||||||
|
{"field": "name", "title": "名称", "width": "20%"},
|
||||||
|
{"field": "description", "title": "描述", "width": "30%"},
|
||||||
|
{"field": "doc_count", "title": "文档数", "width": "10%"},
|
||||||
|
{"field": "total_size", "title": "大小", "width": "10%"},
|
||||||
|
{"field": "embedding_engine", "title": "向量引擎", "width": "15%"},
|
||||||
|
{"field": "created_at", "title": "创建时间", "width": "15%"}
|
||||||
|
],
|
||||||
|
"editfields": [
|
||||||
|
{"field": "name", "uitype": "Text", "required": true},
|
||||||
|
{"field": "description", "uitype": "Text"},
|
||||||
|
{"field": "embedding_engine", "uitype": "Text", "default": "clip-vith14"},
|
||||||
|
{"field": "vdb_collection", "uitype": "Text"},
|
||||||
|
{"field": "graph_name", "uitype": "Text"}
|
||||||
|
],
|
||||||
|
"searchfields": ["name", "description"],
|
||||||
|
"sort": "created_at desc",
|
||||||
|
"data_filter": {
|
||||||
|
"org_id": "{{userorgid}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
json/subscriptions.json
Normal file
28
json/subscriptions.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"tblname": "subscriptions",
|
||||||
|
"params": {
|
||||||
|
"title": "订阅管理",
|
||||||
|
"browserfields": [
|
||||||
|
{"field": "org_id", "title": "机构", "width": "15%"},
|
||||||
|
{"field": "plan_name", "title": "套餐", "width": "15%"},
|
||||||
|
{"field": "disk_quota_bytes", "title": "磁盘配额", "width": "12%"},
|
||||||
|
{"field": "disk_used_bytes", "title": "已用磁盘", "width": "12%"},
|
||||||
|
{"field": "doc_used", "title": "文档数", "width": "10%"},
|
||||||
|
{"field": "start_date", "title": "开始", "width": "12%"},
|
||||||
|
{"field": "end_date", "title": "结束", "width": "12%"},
|
||||||
|
{"field": "status", "title": "状态", "width": "12%"}
|
||||||
|
],
|
||||||
|
"editfields": [
|
||||||
|
{"field": "org_id", "uitype": "Text", "required": true},
|
||||||
|
{"field": "plan_name", "uitype": "Text", "required": true},
|
||||||
|
{"field": "disk_quota_bytes", "uitype": "Text", "default": "1073741824"},
|
||||||
|
{"field": "doc_quota", "uitype": "Text"},
|
||||||
|
{"field": "kb_quota", "uitype": "Text"},
|
||||||
|
{"field": "api_call_quota", "uitype": "Text"},
|
||||||
|
{"field": "start_date", "uitype": "Text"},
|
||||||
|
{"field": "end_date", "uitype": "Text"}
|
||||||
|
],
|
||||||
|
"searchfields": ["org_id", "plan_name"],
|
||||||
|
"sort": "created_at desc"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
models/document_chunks.json
Normal file
30
models/document_chunks.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "document_chunks",
|
||||||
|
"title": "文档分片",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "doc_id", "title": "文档ID", "type": "str", "length": 32},
|
||||||
|
{"name": "kb_id", "title": "知识库ID", "type": "str", "length": 32},
|
||||||
|
{"name": "chunk_index", "title": "分片序号", "type": "int", "default": 0},
|
||||||
|
{"name": "chunk_type", "title": "分片类型", "type": "str", "length": 32},
|
||||||
|
{"name": "content", "title": "文本内容", "type": "text", "length": 65535},
|
||||||
|
{"name": "description", "title": "描述", "type": "text", "length": 65535},
|
||||||
|
{"name": "vector_id", "title": "向量库ID", "type": "str", "length": 128},
|
||||||
|
{"name": "start_offset", "title": "起始偏移", "type": "int", "default": 0},
|
||||||
|
{"name": "end_offset", "title": "结束偏移", "type": "int", "default": 0},
|
||||||
|
{"name": "time_start", "title": "时间起始(秒)", "type": "float", "dec": 3},
|
||||||
|
{"name": "time_end", "title": "时间结束(秒)", "type": "float", "dec": 3},
|
||||||
|
{"name": "metadata", "title": "元数据JSON", "type": "text", "length": 2000},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_chunk_doc", "idxtype": "index", "idxfields": ["doc_id"]},
|
||||||
|
{"name": "idx_chunk_kb", "idxtype": "index", "idxfields": ["kb_id"]},
|
||||||
|
{"name": "idx_chunk_vector", "idxtype": "index", "idxfields": ["vector_id"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
37
models/documents.json
Normal file
37
models/documents.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "documents",
|
||||||
|
"title": "文档",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "kb_id", "title": "知识库ID", "type": "str", "length": 32},
|
||||||
|
{"name": "file_name", "title": "文件名", "type": "str", "length": 255},
|
||||||
|
{"name": "file_type", "title": "文件类型", "type": "str", "length": 32},
|
||||||
|
{"name": "file_size", "title": "文件大小", "type": "int", "default": 0},
|
||||||
|
{"name": "file_path", "title": "文件路径", "type": "str", "length": 500},
|
||||||
|
{"name": "mime_type", "title": "MIME类型", "type": "str", "length": 128},
|
||||||
|
{"name": "chunk_count", "title": "分片数", "type": "int", "default": 0},
|
||||||
|
{"name": "embed_dim", "title": "向量维度", "type": "int", "default": 1024},
|
||||||
|
{"name": "metadata", "title": "元数据JSON", "type": "text", "length": 4000},
|
||||||
|
{"name": "status", "title": "状态", "type": "str", "length": 16, "default": "pending"},
|
||||||
|
{"name": "error_msg", "title": "错误信息", "type": "text", "length": 2000},
|
||||||
|
{"name": "org_id", "title": "所属机构", "type": "str", "length": 32},
|
||||||
|
{"name": "created_by", "title": "创建人", "type": "str", "length": 32},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"},
|
||||||
|
{"name": "updated_at", "title": "更新时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "file_type", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='file_type'"},
|
||||||
|
{"field": "status", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='doc_status'"},
|
||||||
|
{"field": "kb_id", "table": "knowledge_bases", "valuefield": "id", "textfield": "name"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_doc_kb", "idxtype": "index", "idxfields": ["kb_id"]},
|
||||||
|
{"name": "idx_doc_org", "idxtype": "index", "idxfields": ["org_id"]},
|
||||||
|
{"name": "idx_doc_status", "idxtype": "index", "idxfields": ["status"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
33
models/engine_configs.json
Normal file
33
models/engine_configs.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "engine_configs",
|
||||||
|
"title": "引擎配置",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "org_id", "title": "机构ID", "type": "str", "length": 32, "nullable": "yes"},
|
||||||
|
{"name": "engine_type", "title": "引擎类型", "type": "str", "length": 32},
|
||||||
|
{"name": "engine_name", "title": "引擎名称", "type": "str", "length": 64},
|
||||||
|
{"name": "endpoint_url", "title": "服务地址", "type": "str", "length": 255},
|
||||||
|
{"name": "api_key", "title": "API密钥", "type": "str", "length": 255},
|
||||||
|
{"name": "model_name", "title": "模型名称", "type": "str", "length": 128},
|
||||||
|
{"name": "config_json", "title": "扩展配置JSON", "type": "text", "length": 4000},
|
||||||
|
{"name": "is_default", "title": "是否默认", "type": "int", "default": 0},
|
||||||
|
{"name": "priority", "title": "优先级", "type": "int", "default": 0},
|
||||||
|
{"name": "status", "title": "状态", "type": "str", "length": 16, "default": "active"},
|
||||||
|
{"name": "health_check_at", "title": "最近健康检查", "type": "datetime"},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"},
|
||||||
|
{"name": "updated_at", "title": "更新时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "engine_type", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='engine_type'"},
|
||||||
|
{"field": "status", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='engine_status'"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_eng_type", "idxtype": "index", "idxfields": ["engine_type", "is_default"]},
|
||||||
|
{"name": "idx_eng_org", "idxtype": "index", "idxfields": ["org_id", "engine_type"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
models/entities.json
Normal file
35
models/entities.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "entities",
|
||||||
|
"title": "实体",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "kb_id", "title": "知识库ID", "type": "str", "length": 32},
|
||||||
|
{"name": "name", "title": "实体名", "type": "str", "length": 255},
|
||||||
|
{"name": "entity_type", "title": "实体类型", "type": "str", "length": 64},
|
||||||
|
{"name": "description", "title": "描述", "type": "text", "length": 2000},
|
||||||
|
{"name": "graph_node_id", "title": "图节点ID", "type": "str", "length": 128},
|
||||||
|
{"name": "source_doc_ids", "title": "来源文档ID列表", "type": "text", "length": 2000},
|
||||||
|
{"name": "face_embedding_id", "title": "人脸特征ID", "type": "str", "length": 128},
|
||||||
|
{"name": "voice_embedding_id", "title": "声纹特征ID", "type": "str", "length": 128},
|
||||||
|
{"name": "metadata", "title": "元数据JSON", "type": "text", "length": 2000},
|
||||||
|
{"name": "org_id", "title": "所属机构", "type": "str", "length": 32},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"},
|
||||||
|
{"name": "updated_at", "title": "更新时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "entity_type", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='entity_type'"},
|
||||||
|
{"field": "kb_id", "table": "knowledge_bases", "valuefield": "id", "textfield": "name"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_entity_kb", "idxtype": "index", "idxfields": ["kb_id"]},
|
||||||
|
{"name": "idx_entity_name", "idxtype": "index", "idxfields": ["kb_id", "name"]},
|
||||||
|
{"name": "idx_entity_type", "idxtype": "index", "idxfields": ["kb_id", "entity_type"]},
|
||||||
|
{"name": "idx_entity_face", "idxtype": "index", "idxfields": ["face_embedding_id"]},
|
||||||
|
{"name": "idx_entity_voice", "idxtype": "index", "idxfields": ["voice_embedding_id"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
29
models/entity_relations.json
Normal file
29
models/entity_relations.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "entity_relations",
|
||||||
|
"title": "实体关系",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "kb_id", "title": "知识库ID", "type": "str", "length": 32},
|
||||||
|
{"name": "subject_id", "title": "主体实体ID", "type": "str", "length": 32},
|
||||||
|
{"name": "object_id", "title": "客体实体ID", "type": "str", "length": 32},
|
||||||
|
{"name": "relation_type", "title": "关系类型", "type": "str", "length": 64},
|
||||||
|
{"name": "description", "title": "关系描述", "type": "text", "length": 2000},
|
||||||
|
{"name": "graph_edge_id", "title": "图边ID", "type": "str", "length": 128},
|
||||||
|
{"name": "source_chunk_ids", "title": "来源分片ID列表", "type": "text", "length": 2000},
|
||||||
|
{"name": "org_id", "title": "所属机构", "type": "str", "length": 32},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "kb_id", "table": "knowledge_bases", "valuefield": "id", "textfield": "name"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_rel_kb", "idxtype": "index", "idxfields": ["kb_id"]},
|
||||||
|
{"name": "idx_rel_subject", "idxtype": "index", "idxfields": ["subject_id"]},
|
||||||
|
{"name": "idx_rel_object", "idxtype": "index", "idxfields": ["object_id"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
32
models/knowledge_bases.json
Normal file
32
models/knowledge_bases.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "knowledge_bases",
|
||||||
|
"title": "知识库",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "name", "title": "名称", "type": "str", "length": 100},
|
||||||
|
{"name": "description", "title": "描述", "type": "text", "length": 2000},
|
||||||
|
{"name": "org_id", "title": "所属机构", "type": "str", "length": 32},
|
||||||
|
{"name": "embedding_engine", "title": "向量化引擎", "type": "str", "length": 64, "default": "clip-vith14"},
|
||||||
|
{"name": "vdb_collection", "title": "向量库集合名", "type": "str", "length": 128},
|
||||||
|
{"name": "graph_name", "title": "图名称", "type": "str", "length": 128},
|
||||||
|
{"name": "doc_count", "title": "文档数", "type": "int", "default": 0},
|
||||||
|
{"name": "chunk_count", "title": "分片数", "type": "int", "default": 0},
|
||||||
|
{"name": "total_size", "title": "总大小(字节)", "type": "int", "default": 0},
|
||||||
|
{"name": "status", "title": "状态", "type": "str", "length": 16, "default": "active"},
|
||||||
|
{"name": "created_by", "title": "创建人", "type": "str", "length": 32},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"},
|
||||||
|
{"name": "updated_at", "title": "更新时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "status", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='kb_status'"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_kb_org", "idxtype": "index", "idxfields": ["org_id"]},
|
||||||
|
{"name": "idx_kb_name", "idxtype": "unique", "idxfields": ["org_id", "name"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
34
models/subscriptions.json
Normal file
34
models/subscriptions.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "subscriptions",
|
||||||
|
"title": "租户订阅",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "org_id", "title": "机构ID", "type": "str", "length": 32},
|
||||||
|
{"name": "plan_name", "title": "套餐名称", "type": "str", "length": 64},
|
||||||
|
{"name": "disk_quota_bytes", "title": "磁盘配额(字节)", "type": "int", "default": 1073741824},
|
||||||
|
{"name": "disk_used_bytes", "title": "已用磁盘(字节)", "type": "int", "default": 0},
|
||||||
|
{"name": "doc_quota", "title": "文档数配额", "type": "int", "default": 1000},
|
||||||
|
{"name": "doc_used", "title": "已用文档数", "type": "int", "default": 0},
|
||||||
|
{"name": "kb_quota", "title": "知识库数配额", "type": "int", "default": 10},
|
||||||
|
{"name": "kb_used", "title": "已用知识库数", "type": "int", "default": 0},
|
||||||
|
{"name": "api_call_quota", "title": "API调用配额(月)", "type": "int", "default": 10000},
|
||||||
|
{"name": "api_call_used", "title": "已用API调用(月)", "type": "int", "default": 0},
|
||||||
|
{"name": "start_date", "title": "开始日期", "type": "date"},
|
||||||
|
{"name": "end_date", "title": "结束日期", "type": "date"},
|
||||||
|
{"name": "status", "title": "状态", "type": "str", "length": 16, "default": "active"},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"},
|
||||||
|
{"name": "updated_at", "title": "更新时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "status", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='sub_status'"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_sub_org", "idxtype": "unique", "idxfields": ["org_id"]},
|
||||||
|
{"name": "idx_sub_status", "idxtype": "index", "idxfields": ["status"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
30
models/usage_logs.json
Normal file
30
models/usage_logs.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "usage_logs",
|
||||||
|
"title": "用量日志",
|
||||||
|
"primary": ["id"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{"name": "id", "title": "ID", "type": "str", "length": 32},
|
||||||
|
{"name": "org_id", "title": "机构ID", "type": "str", "length": 32},
|
||||||
|
{"name": "kb_id", "title": "知识库ID", "type": "str", "length": 32},
|
||||||
|
{"name": "operation", "title": "操作类型", "type": "str", "length": 32},
|
||||||
|
{"name": "bytes_delta", "title": "磁盘变化(字节)", "type": "int", "default": 0},
|
||||||
|
{"name": "bytes_total", "title": "累计磁盘", "type": "int", "default": 0},
|
||||||
|
{"name": "api_calls", "title": "API调用数", "type": "int", "default": 1},
|
||||||
|
{"name": "engine_type", "title": "引擎类型", "type": "str", "length": 32},
|
||||||
|
{"name": "tokens_used", "title": "Token消耗", "type": "int", "default": 0},
|
||||||
|
{"name": "cost_estimate", "title": "预估费用", "type": "float", "dec": 4},
|
||||||
|
{"name": "detail", "title": "详情JSON", "type": "text", "length": 2000},
|
||||||
|
{"name": "created_at", "title": "创建时间", "type": "datetime"}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{"field": "operation", "table": "appcodes_kv", "valuefield": "k", "textfield": "v", "cond": "parentid='usage_op'"}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{"name": "idx_usage_org", "idxtype": "index", "idxfields": ["org_id", "created_at"]},
|
||||||
|
{"name": "idx_usage_kb", "idxtype": "index", "idxfields": ["kb_id"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
start.sh
Executable file
7
start.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
cdir=$(cd "$(dirname "$0")"; pwd)
|
||||||
|
source py3/bin/activate
|
||||||
|
cd $cdir
|
||||||
|
nohup py3/bin/python app/ragserver.py > logs/ragserver_stdout.log 2>&1 &
|
||||||
|
echo $! > ragserver.pid
|
||||||
|
echo "RAG Server started (pid $(cat ragserver.pid))"
|
||||||
Loading…
x
Reference in New Issue
Block a user