From 29d8d5fb94e411207cfe275418a3da754b184005 Mon Sep 17 00:00:00 2001 From: xiamuceer Date: Tue, 4 Nov 2025 17:27:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Ddocker=E9=95=9C=E5=83=8F?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 6 ++++++ Dockerfile | 15 ++++++++++++++- backend/app/services/memory_service.py | 2 ++ backend/requirements.txt | 11 ++++++++++- frontend/src/pages/Settings.tsx | 10 +++++----- frontend/src/services/api.ts | 2 +- frontend/src/types/index.ts | 4 ++-- 7 files changed, 40 insertions(+), 10 deletions(-) diff --git a/.dockerignore b/.dockerignore index 7dad3b1..e7c354e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -40,6 +40,12 @@ Thumbs.db data/*.db backend/data/*.db +# ChromaDB数据库(不包含在镜像中,会在运行时生成) +backend/data/chroma_db/ + +# 注意:backend/data/models/ 目录需要打包(包含预下载的Embedding模型) +# 所以不要添加到 .dockerignore 中 + # 日志文件 logs/ *.log diff --git a/Dockerfile b/Dockerfile index 60a4447..23877c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,7 +40,10 @@ RUN apt-get update && apt-get install -y \ # 复制后端依赖文件 COPY backend/requirements.txt ./ -# 安装Python依赖 +# 先从PyTorch官方源安装CPU版本的torch(避免GPU依赖) +RUN pip install --no-cache-dir torch==2.7.0 --index-url https://download.pytorch.org/whl/cpu + +# 再安装其他Python依赖(使用阿里云镜像加速) RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ # 复制后端代码 @@ -52,6 +55,10 @@ COPY --from=frontend-builder /frontend/dist ./static # 创建必要的目录 RUN mkdir -p /app/data /app/logs +# 复制预下载的Embedding模型(如果存在) +# 这样可以避免首次运行时联网下载约420MB的模型文件 +COPY backend/data/models /app/data/models + # 复制环境变量示例文件 COPY backend/.env.example ./.env.example @@ -63,6 +70,12 @@ ENV PYTHONUNBUFFERED=1 ENV APP_HOST=0.0.0.0 ENV APP_PORT=8000 +# 设置Transformers和Sentence-Transformers离线模式 +ENV TRANSFORMERS_OFFLINE=1 +ENV HF_DATASETS_OFFLINE=1 +ENV HF_HUB_OFFLINE=1 +ENV SENTENCE_TRANSFORMERS_HOME=/app/data/models + # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1 diff --git a/backend/app/services/memory_service.py b/backend/app/services/memory_service.py index 566235c..9700827 100644 --- a/backend/app/services/memory_service.py +++ b/backend/app/services/memory_service.py @@ -13,6 +13,8 @@ logger = get_logger(__name__) # 配置离线模式,避免联网检查 os.environ['TRANSFORMERS_OFFLINE'] = '1' os.environ['HF_DATASETS_OFFLINE'] = '1' +os.environ['HF_HUB_OFFLINE'] = '1' # 禁用HuggingFace Hub联网 +os.environ['SENTENCE_TRANSFORMERS_HOME'] = 'data/models' # 设置模型缓存目录 class MemoryService: diff --git a/backend/requirements.txt b/backend/requirements.txt index 11db975..91c0a37 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -19,6 +19,15 @@ anthropic==0.72.0 httpx==0.28.1 python-dotenv==1.0.0 +# NumPy版本锁定(兼容性要求) +numpy==1.26.4 + # 向量数据库和Embedding (长期记忆系统) chromadb==1.3.2 -sentence-transformers>=2.3.1 \ No newline at end of file + + +# Transformers(锁定兼容版本) +transformers==4.35.2 + +# Sentence Transformers(基于PyTorch的文本embedding库) +sentence-transformers==2.3.1 \ No newline at end of file diff --git a/frontend/src/pages/Settings.tsx b/frontend/src/pages/Settings.tsx index 85b319a..4e13690 100644 --- a/frontend/src/pages/Settings.tsx +++ b/frontend/src/pages/Settings.tsx @@ -59,7 +59,7 @@ export default function SettingsPage() { form.setFieldsValue({ api_provider: 'openai', api_base_url: 'https://api.openai.com/v1', - model_name: 'gpt-4', + llm_model: 'gpt-4', temperature: 0.7, max_tokens: 2000, }); @@ -96,7 +96,7 @@ export default function SettingsPage() { api_provider: 'openai', api_key: '', api_base_url: 'https://api.openai.com/v1', - model_name: 'gpt-4', + llm_model: 'gpt-4', temperature: 0.7, max_tokens: 2000, }); @@ -193,7 +193,7 @@ export default function SettingsPage() { const apiKey = form.getFieldValue('api_key'); const apiBaseUrl = form.getFieldValue('api_base_url'); const provider = form.getFieldValue('api_provider'); - const modelName = form.getFieldValue('model_name'); + const modelName = form.getFieldValue('llm_model'); if (!apiKey || !apiBaseUrl || !provider || !modelName) { message.warning('请先填写完整的配置信息'); @@ -208,7 +208,7 @@ export default function SettingsPage() { api_key: apiKey, api_base_url: apiBaseUrl, provider: provider, - model_name: modelName + llm_model: modelName }); setTestResult(result); @@ -406,7 +406,7 @@ export default function SettingsPage() { } - name="model_name" + name="llm_model" rules={[{ required: true, message: '请输入或选择模型名称' }]} >