amz_review_analyse/voc_llm.py
OnesvmWhoops 91e6c47fc0 迁移 DeepSeek Chat API,并支持本地 Qwen3 Embedding 向量化。
统一 voc_llm 密钥解析与默认模型;向量化改为本地 mlx 模型;更新 README、gitignore 与流水线文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-04 16:15:03 +08:00

74 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
VOC 流水线 Chat 模型配置(DeepSeek OpenAI 兼容 API)。
密钥(任选其一)::
export DEEPSEEK_API_KEY="sk-..."
export DEEPSEEK_API_KEY_FILE="/path/to/key.txt"
项目根单行文件 .deepseek_key
模型::
默认 deepseek-v4-pro;可用 DEEPSEEK_MODEL 覆盖。
流水线默认关闭思考(extra_body thinking disabled);报告等单独开启处见 voc_report。
"""
from __future__ import annotations
import os
from pathlib import Path
from typing import Any, Dict
from openai import OpenAI
PROJECT_ROOT = Path(__file__).resolve().parent
CHAT_BASE_URL = os.environ.get("DEEPSEEK_BASE_URL", "https://api.deepseek.com").strip()
CHAT_MODEL = os.environ.get("DEEPSEEK_MODEL", "deepseek-v4-pro").strip()
def resolve_chat_api_key() -> str:
"""环境变量 > DEEPSEEK_API_KEY_FILE > 项目根 .deepseek_key。"""
v = os.environ.get("DEEPSEEK_API_KEY", "").strip()
if v:
return v
fp = os.environ.get("DEEPSEEK_API_KEY_FILE", "").strip()
if fp:
p = Path(fp).expanduser()
if p.is_file():
return p.read_text(encoding="utf-8").strip().strip('"').strip("'")
local = PROJECT_ROOT / ".deepseek_key"
if local.is_file():
return local.read_text(encoding="utf-8").strip().strip('"').strip("'")
# 兼容:仅有 .dashscope_key 时提示(DashScope 密钥不能用于 api.deepseek.com)
legacy = PROJECT_ROOT / ".dashscope_key"
if legacy.is_file():
raise RuntimeError(
"检测到 .dashscope_key,但 Chat 已切换为 DeepSeek。"
"请在项目根创建 .deepseek_key(单行 DEEPSEEK 密钥),"
"或执行 export DEEPSEEK_API_KEY='sk-...'"
)
return ""
def require_chat_api_key() -> str:
key = resolve_chat_api_key()
if not key:
raise RuntimeError(
"缺少 DeepSeek API Key:设置 DEEPSEEK_API_KEY,"
"或 DEEPSEEK_API_KEY_FILE,或在项目根创建 .deepseek_key(单行)"
)
return key
def create_chat_client(*, api_key: str | None = None, timeout: float | None = None) -> OpenAI:
kw: Dict[str, Any] = {
"api_key": api_key or require_chat_api_key(),
"base_url": CHAT_BASE_URL,
}
if timeout is not None:
kw["timeout"] = timeout
return OpenAI(**kw)
def chat_extra_body(model: str | None = None) -> Dict[str, Any]:
"""流水线 Chat 默认关闭思考(Pro 模型 API 默认 otherwise 为 enabled)。"""
_ = (model or CHAT_MODEL).lower()
return {"thinking": {"type": "disabled"}}