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