From bf9b02c0b1c8e8fee5fa5b357a080593dfd4b318 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 3 Feb 2026 10:27:04 +0800 Subject: [PATCH] update --- PM2_DEPLOYMENT_GUIDE.md | 152 ++++++++++++++++++++++++++++ backend/app/config.py | 11 ++ backend/app/services/llm_service.py | 21 +++- diagnose_api_key.py | 82 +++++++++++++++ ecosystem.config.js | 19 ++++ 5 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 PM2_DEPLOYMENT_GUIDE.md create mode 100644 diagnose_api_key.py create mode 100644 ecosystem.config.js diff --git a/PM2_DEPLOYMENT_GUIDE.md b/PM2_DEPLOYMENT_GUIDE.md new file mode 100644 index 0000000..058652b --- /dev/null +++ b/PM2_DEPLOYMENT_GUIDE.md @@ -0,0 +1,152 @@ +# PM2部署问题排查指南 + +## 问题描述 +使用PM2部署时出现错误: +``` +LLM调用失败: Exception: ('invalid api_key', ValueError('not enough values to unpack (expected 2, got 1)')) +``` + +## 原因分析 +智谱AI的API Key格式要求包含`.`分隔符(例如:`xxxxx.yyyyyyy`),如果格式不正确或环境变量未正确加载,会导致此错误。 + +## 解决方案 + +### 方案1:使用PM2配置文件(推荐) + +1. 使用项目根目录的 `ecosystem.config.js` 配置文件: + +```bash +cd /path/to/Stock_Agent +pm2 start ecosystem.config.js +``` + +2. 如果需要修改路径,编辑 `ecosystem.config.js`: + +```javascript +module.exports = { + apps: [{ + name: 'stock-agent', + script: 'backend/app/main.py', + interpreter: 'python3', + cwd: '/your/project/path/Stock_Agent', // 修改为你的实际路径 + env: { + ENV_FILE: '/your/project/path/Stock_Agent/.env' // 修改为你的实际路径 + } + }] +}; +``` + +### 方案2:直接指定环境变量 + +```bash +cd /path/to/Stock_Agent +pm2 start backend/app/main.py \ + --name stock-agent \ + --interpreter python3 \ + --env ENV_FILE=/path/to/Stock_Agent/.env +``` + +### 方案3:在PM2中设置环境变量 + +```bash +pm2 start backend/app/main.py --name stock-agent --interpreter python3 +pm2 env stock-agent ENV_FILE /path/to/Stock_Agent/.env +pm2 restart stock-agent +``` + +## 诊断步骤 + +### 1. 运行诊断脚本 + +```bash +cd /path/to/Stock_Agent +python3 diagnose_api_key.py +``` + +这个脚本会检查: +- .env文件是否存在 +- API Key是否正确加载 +- API Key格式是否正确 +- 智谱AI客户端是否能初始化 + +### 2. 检查.env文件 + +确保 `.env` 文件存在且格式正确: + +```bash +cat .env +``` + +应该看到类似内容: +``` +ZHIPUAI_API_KEY=xxxxx.yyyyyyy +TUSHARE_TOKEN=your_token_here +``` + +### 3. 验证API Key格式 + +智谱AI的API Key应该: +- 包含 `.` 分隔符 +- 格式类似:`415e176f8b964f98a6b4e44b24171145.AVe4qY6RSbxBolhI` +- 长度通常在40-60个字符 + +### 4. 检查PM2日志 + +```bash +pm2 logs stock-agent +``` + +查看启动日志中的配置加载信息: +- `[Config] 找到.env文件: /path/to/.env` - 表示找到了配置文件 +- `正在初始化智谱AI客户端` - 表示开始初始化 +- `智谱AI LLM服务初始化成功` - 表示初始化成功 + +## 常见问题 + +### Q1: API Key格式错误 +**症状**: 错误信息包含 `not enough values to unpack` + +**解决**: +1. 检查API Key是否包含 `.` 分隔符 +2. 确认从智谱AI官网复制的完整Key +3. 检查是否有多余的空格或换行符 + +### Q2: 环境变量未加载 +**症状**: 日志显示 `智谱AI API Key未配置` + +**解决**: +1. 使用 `ecosystem.config.js` 配置文件 +2. 确保 `cwd` 和 `ENV_FILE` 路径正确 +3. 重启PM2进程 + +### Q3: .env文件路径问题 +**症状**: 日志显示 `警告:未找到.env文件` + +**解决**: +1. 确认.env文件在项目根目录 +2. 使用绝对路径指定ENV_FILE +3. 检查文件权限 + +## 验证修复 + +修复后,运行以下命令验证: + +```bash +# 1. 重启PM2进程 +pm2 restart stock-agent + +# 2. 查看日志 +pm2 logs stock-agent --lines 50 + +# 3. 应该看到成功信息 +# [Config] 找到.env文件: ... +# 正在初始化智谱AI客户端,API Key前10位: 415e176f8b... +# 智谱AI LLM服务初始化成功 +``` + +## 联系支持 + +如果问题仍未解决,请提供以下信息: +1. 诊断脚本输出 +2. PM2日志(隐藏敏感信息) +3. .env文件格式(隐藏实际Key值) diff --git a/backend/app/config.py b/backend/app/config.py index 22baedc..da202e9 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -17,19 +17,30 @@ def find_env_file(): # 尝试当前目录 env_path = current_dir / ".env" if env_path.exists(): + print(f"[Config] 找到.env文件: {env_path}") return str(env_path) # 尝试父目录(项目根目录) env_path = current_dir.parent / ".env" if env_path.exists(): + print(f"[Config] 找到.env文件: {env_path}") return str(env_path) # 尝试backend的父目录 if current_dir.name == "backend": env_path = current_dir.parent / ".env" if env_path.exists(): + print(f"[Config] 找到.env文件: {env_path}") return str(env_path) + # 尝试从环境变量指定的路径 + if os.getenv('ENV_FILE'): + env_path = Path(os.getenv('ENV_FILE')) + if env_path.exists(): + print(f"[Config] 从ENV_FILE环境变量找到.env文件: {env_path}") + return str(env_path) + + print(f"[Config] 警告:未找到.env文件,当前目录: {current_dir}") # 默认返回当前目录的.env return ".env" diff --git a/backend/app/services/llm_service.py b/backend/app/services/llm_service.py index 03faaf2..f9993c4 100644 --- a/backend/app/services/llm_service.py +++ b/backend/app/services/llm_service.py @@ -30,11 +30,28 @@ class LLMService: self.client = None return + # 验证API Key格式 + api_key = settings.zhipuai_api_key.strip() + if not api_key or len(api_key) < 10: + logger.error(f"智谱AI API Key格式无效,长度: {len(api_key)}") + self.client = None + return + + # 检查API Key是否包含必要的分隔符 + if '.' not in api_key: + logger.error("智谱AI API Key格式无效,缺少'.'分隔符") + logger.error(f"当前API Key前10个字符: {api_key[:10]}...") + self.client = None + return + try: - self.client = ZhipuAI(api_key=settings.zhipuai_api_key) + logger.info(f"正在初始化智谱AI客户端,API Key前10位: {api_key[:10]}...") + self.client = ZhipuAI(api_key=api_key) logger.info("智谱AI LLM服务初始化成功") except Exception as e: - logger.error(f"智谱AI初始化失败: {e}") + logger.error(f"智谱AI初始化失败: {type(e).__name__}: {e}") + import traceback + logger.error(f"详细错误: {traceback.format_exc()}") self.client = None def chat( diff --git a/diagnose_api_key.py b/diagnose_api_key.py new file mode 100644 index 0000000..8793eb0 --- /dev/null +++ b/diagnose_api_key.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +""" +诊断脚本:检查智谱AI API Key配置 +""" +import os +import sys +from pathlib import Path + +# 添加项目路径 +sys.path.insert(0, str(Path(__file__).parent / 'backend')) + +from app.config import get_settings + +def main(): + print("=" * 60) + print("智谱AI API Key 诊断") + print("=" * 60) + + # 检查当前工作目录 + print(f"\n当前工作目录: {Path.cwd()}") + + # 检查.env文件 + env_files = [ + Path.cwd() / ".env", + Path.cwd().parent / ".env", + Path(__file__).parent / ".env" + ] + + print("\n检查.env文件:") + for env_file in env_files: + if env_file.exists(): + print(f" ✓ 找到: {env_file}") + else: + print(f" ✗ 不存在: {env_file}") + + # 加载配置 + print("\n加载配置...") + try: + settings = get_settings() + print(" ✓ 配置加载成功") + except Exception as e: + print(f" ✗ 配置加载失败: {e}") + return + + # 检查API Key + print("\nAPI Key 检查:") + api_key = settings.zhipuai_api_key + + if not api_key: + print(" ✗ API Key 为空") + return + + print(f" ✓ API Key 已设置") + print(f" - 长度: {len(api_key)}") + print(f" - 前10位: {api_key[:10]}...") + print(f" - 后10位: ...{api_key[-10:]}") + + # 检查格式 + if '.' in api_key: + parts = api_key.split('.') + print(f" ✓ 包含'.'分隔符,分为{len(parts)}部分") + for i, part in enumerate(parts): + print(f" 部分{i+1}: {len(part)}字符") + else: + print(" ✗ 缺少'.'分隔符(智谱AI Key应该包含'.')") + + # 尝试初始化客户端 + print("\n尝试初始化智谱AI客户端...") + try: + from zhipuai import ZhipuAI + client = ZhipuAI(api_key=api_key) + print(" ✓ 客户端初始化成功") + except Exception as e: + print(f" ✗ 客户端初始化失败: {type(e).__name__}: {e}") + import traceback + print("\n详细错误:") + print(traceback.format_exc()) + + print("\n" + "=" * 60) + +if __name__ == "__main__": + main() diff --git a/ecosystem.config.js b/ecosystem.config.js new file mode 100644 index 0000000..deb12cb --- /dev/null +++ b/ecosystem.config.js @@ -0,0 +1,19 @@ +module.exports = { + apps: [{ + name: 'stock-agent', + script: 'backend/app/main.py', + interpreter: 'python3', + cwd: '/Users/aaron/source_code/Stock_Agent', + env: { + ENV_FILE: '/Users/aaron/source_code/Stock_Agent/.env' + }, + instances: 1, + autorestart: true, + watch: false, + max_memory_restart: '1G', + error_file: './logs/err.log', + out_file: './logs/out.log', + log_file: './logs/combined.log', + time: true + }] +};