update
This commit is contained in:
parent
c73341b950
commit
bf9b02c0b1
152
PM2_DEPLOYMENT_GUIDE.md
Normal file
152
PM2_DEPLOYMENT_GUIDE.md
Normal file
@ -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值)
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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(
|
||||
|
||||
82
diagnose_api_key.py
Normal file
82
diagnose_api_key.py
Normal file
@ -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()
|
||||
19
ecosystem.config.js
Normal file
19
ecosystem.config.js
Normal file
@ -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
|
||||
}]
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user