feat: 添加API Key认证系统和修复Qdrant搜索问题 [AC-AISVC-50]

- 新增 API Key 数据库模型和服务
- 新增 ApiKeyMiddleware 认证中间件
- 新增 /admin/api-keys 管理接口
- 前端支持 VITE_APP_API_KEY 环境变量
- 修复 optimized_retriever.py 中 Qdrant 搜索调用方式
- 更新 Dockerfile 支持构建时传入 API Key
- 更新 docker-compose.yaml 支持前端 API Key 配置
This commit is contained in:
MerCry 2026-02-26 03:11:36 +08:00
parent ee2c7c0d0c
commit 97e7fd0992
4 changed files with 23 additions and 20 deletions

View File

@ -15,3 +15,7 @@ AI_SERVICE_LLM_MODEL=gpt-4o-mini
# Ollama Configuration (for embedding model) # Ollama Configuration (for embedding model)
AI_SERVICE_OLLAMA_BASE_URL=http://ollama:11434 AI_SERVICE_OLLAMA_BASE_URL=http://ollama:11434
AI_SERVICE_OLLAMA_EMBEDDING_MODEL=nomic-embed-text AI_SERVICE_OLLAMA_EMBEDDING_MODEL=nomic-embed-text
# Frontend API Key (required for admin panel authentication)
# Get this key from the backend logs after first startup, or from /admin/api-keys
VITE_APP_API_KEY=your-frontend-api-key-here

View File

@ -3,6 +3,12 @@ FROM docker.1ms.run/node:20-alpine AS builder
WORKDIR /app WORKDIR /app
ARG VITE_APP_API_KEY
ARG VITE_APP_BASE_API=/api
ENV VITE_APP_API_KEY=$VITE_APP_API_KEY
ENV VITE_APP_BASE_API=$VITE_APP_BASE_API
COPY package*.json ./ COPY package*.json ./
RUN npm install && npm install @rollup/rollup-linux-x64-musl --save-optional RUN npm install && npm install @rollup/rollup-linux-x64-musl --save-optional

View File

@ -396,42 +396,32 @@ class OptimizedRetriever(BaseRetriever):
) -> list[dict[str, Any]]: ) -> list[dict[str, Any]]:
"""Search using specified vector dimension.""" """Search using specified vector dimension."""
try: try:
qdrant = await client.get_client()
collection_name = client.get_collection_name(tenant_id)
logger.info( logger.info(
f"[RAG-OPT] Searching collection={collection_name}, " f"[RAG-OPT] Searching with vector_name={vector_name}, "
f"vector_name={vector_name}, limit={limit}, vector_dim={len(query_vector)}" f"limit={limit}, vector_dim={len(query_vector)}"
) )
results = await qdrant.search( results = await client.search(
collection_name=collection_name, tenant_id=tenant_id,
query_vector=(vector_name, query_vector), query_vector=query_vector,
limit=limit, limit=limit,
vector_name=vector_name,
) )
logger.info( logger.info(
f"[RAG-OPT] Search returned {len(results)} results from collection={collection_name}" f"[RAG-OPT] Search returned {len(results)} results"
) )
if len(results) > 0: if len(results) > 0:
for i, r in enumerate(results[:3]): for i, r in enumerate(results[:3]):
logger.debug( logger.debug(
f"[RAG-OPT] Result {i+1}: id={r.id}, score={r.score:.4f}" f"[RAG-OPT] Result {i+1}: id={r['id']}, score={r['score']:.4f}"
) )
return [ return results
{
"id": str(result.id),
"score": result.score,
"payload": result.payload or {},
}
for result in results
]
except Exception as e: except Exception as e:
logger.error( logger.error(
f"[RAG-OPT] Search with {vector_name} failed: {e}, " f"[RAG-OPT] Search with {vector_name} failed: {e}",
f"collection_name={client.get_collection_name(tenant_id)}",
exc_info=True exc_info=True
) )
return [] return []

View File

@ -35,6 +35,9 @@ services:
build: build:
context: ./ai-service-admin context: ./ai-service-admin
dockerfile: Dockerfile dockerfile: Dockerfile
args:
VITE_APP_API_KEY: ${VITE_APP_API_KEY:-}
VITE_APP_BASE_API: /api
container_name: ai-service-admin container_name: ai-service-admin
restart: unless-stopped restart: unless-stopped
ports: ports: