Skip to content

LLM 调用链路

LLM 调用链路由 LLMConfigLLMManager 和 provider client 组成。业务层不直接拼接厂商请求,而是通过 RAG response generation、处方 generation 或 Chat use case 的 provider 切换入口间接访问当前 client。

Provider 配置

ProviderClient模型配置协议
moonshotOpenAICompatClientmoonshot-v1-8kkimi-k2.5OpenAI Chat Completions 兼容 HTTP API。
sparkSparkLLMClientspark_maxspark_ultra讯飞星火 WebSocket API。

当前生产默认:

配置项
LLM_PROVIDERmoonshot
LLM_MODELmoonshot-v1-8k
SPARK_MODELspark_max

凭据从环境变量注入:MOONSHOT_API_KEY / KIMI_API_KEYSPARK_APP_IDSPARK_API_KEYSPARK_API_SECRET。文档和日志不记录真实值。

管理器职责

LLMManager 是统一入口:

方法行为
_init_default_provider()读取 LLMConfig.get_current_provider() 并加载对应 client。
_load_client(provider)通过 importlib 动态导入 client module 与 class。
switch_provider(provider, model)切换配置并重新加载 client;失败时尝试回滚到 spark
get_client()返回当前 client,缺失时重新初始化。
get_current_info()返回 provider 和 model 的可展示元信息。

Chat API 的请求体可传 providerSendChatMessageUseCase 会在本次执行开始时调用 llm_manager.switch_provider(...)。切换失败不阻断对话,会使用当前默认厂商。

OpenAI-compatible 路径

OpenAICompatClient 的调用流程:

  1. LLMConfig 读取当前 provider、model、base URL 和参数。
  2. 校验 API key 是否存在。
  3. 构造 AsyncOpenAI(api_key, base_url)
  4. chat_completion(...) 合并 system prompt、conversation history 和当前 user message。
  5. 消息超过 10 条时保留 system message 和最近 9 条。
  6. 调用 client.chat.completions.create(...)
  7. 返回 contentreasoning_contentmodelproviderusagecreated

kimi-k2.5 配置会通过 extra_body 关闭 thinking,并省略 temperature、top_p、seed、frequency_penalty 等参数。

Spark 路径

SparkLLMClient 的调用流程:

阶段行为
鉴权 URL使用 app id、api key、api secret、host、date、request-line 生成 WebSocket 鉴权 URL。
请求体构造 headerparameter.chatpayload.message.text
非流式外层 asyncio.wait_for 包住整个 WebSocket 生命周期。
流式收集默认 chat_completion(stream=True),内部逐帧收集,对上游仍返回完整 dict。
历史截断与 OpenAI-compatible 路径一致,保留 system message 和最近 9 条。
超时会话总超时后抛出异常,由上游 fallback 处理。

Spark client 当前返回的 model 字段仍是兼容命名,实际模型由 SPARK_MODEL 和 SparkConfig 解析。

Chat 生成

Chat 中的 LLM 调用由 ResponseGenerationService 承接:

步骤行为
患者画像render_patient_profile(...) 只基于已填写用户上下文生成摘要,不调用 LLM。
System prompt明确动养AI身份、回复长度原则、非诊断边界、紧急症状就医提示。
User message拼接用户问题、专业知识上下文和前 3 个来源。
LLM 调用调用 llm_client.chat_completion(...)
失败 fallbackLLM 异常时,从已检索知识上下文整理 1-3 条建议,并保留安全边界提示。
无证据 fallback通过 generate_fallback_response(...) 基于一般健康管理原则回答,并标记一般常识来源。

Chat use case 会根据 model_info.fallback 调整响应置信度:正常模型输出为较高置信,fallback 输出为较低置信。

Prompt 结构、患者画像拼接、JSON 输出约束和 fallback 文案在 Prompt 契约 中单独说明。

处方生成

处方生成由 PrescriptionGenerationService 承接:

步骤行为
Prompt基于年龄、性别、BMI、血压、脉搏、疾病史、手术史、评估上下文、器械、偏好构造系统提示词。
User message要求模型输出结构化运动处方 JSON。
解析从 LLM 文本中解析处方 JSON,并补齐必要字段。
安全检查使用 SafetyFilter.check_prescription_safety(...) 检查强度、禁忌、年龄和疾病冲突。
成功返回rag_used=falseknowledge_sources=[]information_source=基于循证医学通识
失败 fallback生成默认安全处方;再次失败时返回应急处方形状。

处方生成的 LLM 输出必须被视为待校验结构化草案,不能绕过后端安全检查直接写入展示。

处方 prompt 的角色、用户摘要、约束注入、JSON 形状和后处理在 Prompt 契约 中单独说明。

失败与降级

失败点处理
provider 配置缺失client 初始化抛错;manager 初始化记录 warning。
API key 缺失provider client 校验失败,不输出真实 key。
provider 切换失败Chat 记录 warning,并使用默认厂商继续。
LLM 调用失败且已有 RAG 上下文optimize_knowledge_response(...) 整理知识摘要。
LLM 调用失败且处方生成失败返回默认安全处方或应急处方。
Spark WebSocket timeout抛出超时异常,由上游 fallback。

来源锚点

  • Config: apps/backend_service/app/core/llm_config.pyapps/backend_service/app/core/config.py
  • Manager: apps/backend_service/app/external/llm_manager.py
  • OpenAI-compatible client: apps/backend_service/app/external/openai_compat_client.py
  • Spark client: apps/backend_service/app/external/spark_client.py
  • Chat generation: apps/backend_service/app/core/rag/response_generation.py
  • Prescription generation: apps/backend_service/app/core/rag/prescription_generation.py
  • Chat use case: apps/backend_service/app/use_cases/chat/send_message.py