Files
2026Technology-Competition/src/genesis/inference/factory.py
T
lhl 958e2602cc feat(inference): 接通真实 LLM 引擎工厂(P5-T10 门禁接线)
- 新增 inference/factory.build_inference_engine:读 GENESIS_INFERENCE__* / 裸
  DEEPSEEK_API_KEY·LLM_BASE_URL 环境变量与 .env,构造 HttpLLMClient + InferenceEngine
- orchestrator/qa_loop 的 engine=None 分支改用工厂,真正接通真实 LLM 路径
- 脚本注入校验改为通用(非空段落数 + 残留占位符),适配真实模式
- 补工厂测试(缺密钥/前缀变量/裸变量/默认值/.env 解析),覆盖率 99.04%
2026-08-13 23:11:31 +08:00

69 lines
2.4 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.
"""真实 InferenceEngine 工厂:读取环境变量/.env 构造 HttpLLMClient + InferenceEngine。
设计要点:
- 不硬编码任何密钥;优先级 GENESIS_INFERENCE__* 环境变量 > 裸 DEEPSEEK_API_KEY/LLM_BASE_URL > 默认值。
- 自动加载仓库根目录 .env(被 .gitignore 忽略,密钥不入库)。
- engine=None 时由 orchestrator/qa_loop 调用,接通 P5-T10 人工质量门禁的真实 LLM 路径。
"""
from __future__ import annotations
import os
from pathlib import Path
from genesis.config import InferenceModels, ModelSpec
from genesis.inference.client import HttpLLMClient
from genesis.inference.engine import InferenceEngine
from genesis.inference.exceptions import LLMNotConfiguredError
_DEFAULT_BASE_URL = "https://api.deepseek.com"
_DEFAULT_MODEL = "deepseek-chat"
_DEFAULT_FALLBACK = "qwen-max"
def _load_dotenv(path: Path = Path(".env")) -> None:
"""将 .env 中的 KEY=VALUE 注入 os.environ(仅当变量尚未设置时)。"""
if not path.is_file():
return
for raw in path.read_text(encoding="utf-8").splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, _, val = line.partition("=")
key = key.strip()
val = val.strip()
if len(val) >= 2 and val[0] in "\"'":
if val[-1] == val[0]:
val = val[1:-1]
os.environ.setdefault(key, val)
def build_inference_engine() -> InferenceEngine:
_load_dotenv()
api_key = os.environ.get("GENESIS_INFERENCE__API_KEY") or os.environ.get("DEEPSEEK_API_KEY")
base_url = (
os.environ.get("GENESIS_INFERENCE__BASE_URL")
or os.environ.get("LLM_BASE_URL")
or _DEFAULT_BASE_URL
)
model = (
os.environ.get("GENESIS_INFERENCE__MODEL")
or os.environ.get("LLM_MODEL")
or _DEFAULT_MODEL
)
fallback = (
os.environ.get("GENESIS_INFERENCE__FALLBACK_MODEL")
or os.environ.get("LLM_FALLBACK_MODEL")
or _DEFAULT_FALLBACK
)
if not api_key:
raise LLMNotConfiguredError(
"缺少 LLM API Key:请设置 GENESIS_INFERENCE__API_KEY"
"(或 .env / 环境变量 DEEPSEEK_API_KEY"
)
models = InferenceModels(
primary=ModelSpec(name=model),
fallback=ModelSpec(name=fallback),
)
client = HttpLLMClient(base_url=base_url, api_key=api_key)
return InferenceEngine(client=client, models=models)