feat: add DeepSeek official API support and capture reasoning content
- Add DeepSeek provider routing: deepseek-chat/deepseek-reasoner use api.deepseek.com, other models use SiliconFlow - Add stream_with_reasoning() using raw OpenAI SDK to capture reasoning_content (langchain_openai strips this field) - RAG chain and conversation chain both use stream_with_reasoning for proper reasoning display in thinking models - Frontend model selector: grouped by provider (DeepSeek official + SiliconFlow), default changed to deepseek-chat - Regenerate message converted to streaming with reasoning capture - Minor UI: globals.css additions, chat store refactoring Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,9 @@ class ConversationChain:
|
||||
system_prompt: 系统提示词
|
||||
model: 可选的模型名称,如 deepseek-ai/DeepSeek-V3, Qwen/QwQ-32B
|
||||
"""
|
||||
self.llm = get_llm_client(model=model).llm
|
||||
_sf_client = get_llm_client(model=model)
|
||||
self.llm = _sf_client.llm
|
||||
self.client = _sf_client
|
||||
self.system_prompt = system_prompt or "你是一个专业的国土空间规划知识问答助手。请基于你的知识回答用户的问题。"
|
||||
|
||||
# 创建带历史的Prompt模板
|
||||
@@ -94,24 +96,18 @@ class ConversationChain:
|
||||
|
||||
yield {"type": "thinking", "stage": "generating", "message": "正在生成回答..."}
|
||||
|
||||
# 直接流式调用 LLM 以捕获推理内容
|
||||
prompt_messages = await self.prompt.ainvoke({
|
||||
# 直接使用原始 OpenAI SDK 捕获推理内容
|
||||
prompt_value = await self.prompt.ainvoke({
|
||||
"question": question,
|
||||
"chat_history": history_messages
|
||||
})
|
||||
prompt_messages = prompt_value.to_messages()
|
||||
|
||||
content_started = False
|
||||
async for chunk in self.llm.astream(prompt_messages):
|
||||
# 捕获推理内容(DeepSeek-R1/QwQ 等推理模型)
|
||||
if hasattr(chunk, 'additional_kwargs') and 'reasoning_content' in chunk.additional_kwargs:
|
||||
reasoning_text = chunk.additional_kwargs['reasoning_content']
|
||||
if reasoning_text:
|
||||
yield {"type": "thinking", "stage": "reasoning", "message": reasoning_text}
|
||||
elif hasattr(chunk, 'reasoning_content') and chunk.reasoning_content:
|
||||
yield {"type": "thinking", "stage": "reasoning", "message": chunk.reasoning_content}
|
||||
|
||||
content = chunk.content if hasattr(chunk, 'content') else str(chunk)
|
||||
if content:
|
||||
async for event_type, content in self.client.stream_with_reasoning(prompt_messages):
|
||||
if event_type == "reasoning":
|
||||
yield {"type": "thinking", "stage": "reasoning", "message": content}
|
||||
elif event_type == "content":
|
||||
if not content_started:
|
||||
content_started = True
|
||||
yield {"type": "chunk", "content": content}
|
||||
|
||||
Reference in New Issue
Block a user