From 97e7fd09920e8e24a67ea8b64f1704df1805f5ee Mon Sep 17 00:00:00 2001 From: MerCry Date: Thu, 26 Feb 2026 03:11:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0API=20Key=E8=AE=A4?= =?UTF-8?q?=E8=AF=81=E7=B3=BB=E7=BB=9F=E5=92=8C=E4=BF=AE=E5=A4=8DQdrant?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E9=97=AE=E9=A2=98=20[AC-AISVC-50]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 API Key 数据库模型和服务 - 新增 ApiKeyMiddleware 认证中间件 - 新增 /admin/api-keys 管理接口 - 前端支持 VITE_APP_API_KEY 环境变量 - 修复 optimized_retriever.py 中 Qdrant 搜索调用方式 - 更新 Dockerfile 支持构建时传入 API Key - 更新 docker-compose.yaml 支持前端 API Key 配置 --- .env.example | 4 +++ ai-service-admin/Dockerfile | 6 ++++ .../services/retrieval/optimized_retriever.py | 30 +++++++------------ docker-compose.yaml | 3 ++ 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/.env.example b/.env.example index db110b4..9bd4a4d 100644 --- a/.env.example +++ b/.env.example @@ -15,3 +15,7 @@ AI_SERVICE_LLM_MODEL=gpt-4o-mini # Ollama Configuration (for embedding model) AI_SERVICE_OLLAMA_BASE_URL=http://ollama:11434 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 diff --git a/ai-service-admin/Dockerfile b/ai-service-admin/Dockerfile index fdaa9c0..bee8070 100644 --- a/ai-service-admin/Dockerfile +++ b/ai-service-admin/Dockerfile @@ -3,6 +3,12 @@ FROM docker.1ms.run/node:20-alpine AS builder 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 ./ RUN npm install && npm install @rollup/rollup-linux-x64-musl --save-optional diff --git a/ai-service/app/services/retrieval/optimized_retriever.py b/ai-service/app/services/retrieval/optimized_retriever.py index 1c773d8..74d6a21 100644 --- a/ai-service/app/services/retrieval/optimized_retriever.py +++ b/ai-service/app/services/retrieval/optimized_retriever.py @@ -396,42 +396,32 @@ class OptimizedRetriever(BaseRetriever): ) -> list[dict[str, Any]]: """Search using specified vector dimension.""" try: - qdrant = await client.get_client() - collection_name = client.get_collection_name(tenant_id) - logger.info( - f"[RAG-OPT] Searching collection={collection_name}, " - f"vector_name={vector_name}, limit={limit}, vector_dim={len(query_vector)}" + f"[RAG-OPT] Searching with vector_name={vector_name}, " + f"limit={limit}, vector_dim={len(query_vector)}" ) - results = await qdrant.search( - collection_name=collection_name, - query_vector=(vector_name, query_vector), + results = await client.search( + tenant_id=tenant_id, + query_vector=query_vector, limit=limit, + vector_name=vector_name, ) 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: for i, r in enumerate(results[:3]): 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 [ - { - "id": str(result.id), - "score": result.score, - "payload": result.payload or {}, - } - for result in results - ] + return results except Exception as e: logger.error( - f"[RAG-OPT] Search with {vector_name} failed: {e}, " - f"collection_name={client.get_collection_name(tenant_id)}", + f"[RAG-OPT] Search with {vector_name} failed: {e}", exc_info=True ) return [] diff --git a/docker-compose.yaml b/docker-compose.yaml index 9820697..760d5b2 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -35,6 +35,9 @@ services: build: context: ./ai-service-admin dockerfile: Dockerfile + args: + VITE_APP_API_KEY: ${VITE_APP_API_KEY:-} + VITE_APP_BASE_API: /api container_name: ai-service-admin restart: unless-stopped ports: