fix: improve DeepSeek reasoning_content payload handling and update langchain dependencies

This commit is contained in:
jxxghp
2026-04-25 12:46:21 +08:00
parent bfc27d151c
commit 4fd5aa3eb6
2 changed files with 33 additions and 41 deletions
+31 -39
View File
@@ -2,11 +2,12 @@
import asyncio import asyncio
import inspect import inspect
import json
import time import time
from functools import wraps from functools import wraps
from typing import Any, List from typing import Any, List
from langchain_core.messages import convert_to_messages from langchain_core.messages import AIMessage
from app.core.config import settings from app.core.config import settings
from app.log import logger from app.log import logger
@@ -141,47 +142,38 @@ def _patch_deepseek_reasoning_content_support():
def _patched_get_request_payload(self, input_, *, stop=None, **kwargs): def _patched_get_request_payload(self, input_, *, stop=None, **kwargs):
payload = original_get_request_payload(self, input_, stop=stop, **kwargs) payload = original_get_request_payload(self, input_, stop=stop, **kwargs)
try: # Resolve original messages so we can extract reasoning_content from
original_messages = convert_to_messages(input_) # additional_kwargs. The parent's payload builder does not propagate
payload_messages = payload.get("messages") or [] # this DeepSeek-specific field.
model_name = getattr(self, "model_name", None) or getattr( messages = self._convert_input(input_).to_messages()
self, "model", None
)
extra_body = kwargs.get("extra_body")
if extra_body is None:
extra_body = getattr(self, "extra_body", None)
if extra_body is None:
extra_body = getattr(self, "model_kwargs", {}).get("extra_body")
if not _is_deepseek_thinking_enabled(model_name, extra_body): for i, message in enumerate(payload["messages"]):
return payload if message["role"] == "tool" and isinstance(message["content"], list):
message["content"] = json.dumps(message["content"])
elif message["role"] == "assistant":
if isinstance(message["content"], list):
# DeepSeek API expects assistant content to be a string,
# not a list. Extract text blocks and join them, or use
# empty string if none exist.
text_parts = [
block.get("text", "")
for block in message["content"]
if isinstance(block, dict) and block.get("type") == "text"
]
message["content"] = "".join(text_parts) if text_parts else ""
for index, message in enumerate(payload_messages): # DeepSeek reasoning models require every assistant message to
if not isinstance(message, dict): # carry a reasoning_content field (even when empty). The value
continue # is stored in AIMessage.additional_kwargs by
if message.get("role") != "assistant": # _create_chat_result(); re-inject it into the API payload.
continue if (
if not message.get("tool_calls"): "reasoning_content" not in message
continue and i < len(messages)
if message.get("reasoning_content") is not None: and isinstance(messages[i], AIMessage)
continue ):
message["reasoning_content"] = messages[i].additional_kwargs.get(
reasoning_content = "" "reasoning_content", ""
if index < len(original_messages):
additional_kwargs = (
getattr(original_messages[index], "additional_kwargs", None)
or {}
) )
if isinstance(additional_kwargs, dict):
captured_reasoning = additional_kwargs.get("reasoning_content")
if isinstance(captured_reasoning, str):
reasoning_content = captured_reasoning
message["reasoning_content"] = reasoning_content
except Exception as e:
logger.warning(
f"修补 langchain-deepseek reasoning_content 请求载荷时失败,将继续使用原始载荷: {e}"
)
return payload return payload
+2 -2
View File
@@ -77,9 +77,9 @@ smbprotocol~=1.15.0
setproctitle~=1.3.6 setproctitle~=1.3.6
httpx[socks]~=0.28.1 httpx[socks]~=0.28.1
langchain~=1.2.15 langchain~=1.2.15
langchain-core~=1.3.1 langchain-core~=1.3.2
langchain-community~=0.4.1 langchain-community~=0.4.1
langchain-openai~=1.2.0 langchain-openai~=1.2.1
langchain-google-genai~=4.2.2 langchain-google-genai~=4.2.2
langchain-deepseek~=1.0.1 langchain-deepseek~=1.0.1
langgraph~=1.1.9 langgraph~=1.1.9