diff --git a/backend/app/services/ontology_generator.py b/backend/app/services/ontology_generator.py index 2d3e39bd..8ab641b7 100644 --- a/backend/app/services/ontology_generator.py +++ b/backend/app/services/ontology_generator.py @@ -197,7 +197,7 @@ class OntologyGenerator: result = self.llm_client.chat_json( messages=messages, temperature=0.3, - max_tokens=4096 + max_tokens=32768 ) # 验证和后处理 diff --git a/backend/app/utils/llm_client.py b/backend/app/utils/llm_client.py index 6c1a81f4..1df96a96 100644 --- a/backend/app/utils/llm_client.py +++ b/backend/app/utils/llm_client.py @@ -54,9 +54,9 @@ class LLMClient: kwargs = { "model": self.model, "messages": messages, - "temperature": temperature, - "max_tokens": max_tokens, + "max_completion_tokens": max_tokens, } + kwargs["temperature"] = temperature if response_format: kwargs["response_format"] = response_format @@ -71,7 +71,7 @@ class LLMClient: self, messages: List[Dict[str, str]], temperature: float = 0.3, - max_tokens: int = 4096 + max_tokens: int = 16384 ) -> Dict[str, Any]: """ 发送聊天请求并返回JSON @@ -88,7 +88,6 @@ class LLMClient: messages=messages, temperature=temperature, max_tokens=max_tokens, - response_format={"type": "json_object"} ) # 清理markdown代码块标记 cleaned_response = response.strip() @@ -99,5 +98,27 @@ class LLMClient: try: return json.loads(cleaned_response) except json.JSONDecodeError: - raise ValueError(f"LLM返回的JSON格式无效: {cleaned_response}") + # Aggressive JSON repair for truncated responses + repaired = cleaned_response + # Try progressively trimming from the end until valid JSON + for trim in range(min(len(repaired), 2000)): + candidate = repaired[:len(repaired) - trim].rstrip(', \n\t\r') + # Remove incomplete string at end + if candidate and candidate[-1] not in ']}}"': + continue + open_braces = candidate.count('{') - candidate.count('}') + open_brackets = candidate.count('[') - candidate.count(']') + fixed = candidate + for _ in range(open_brackets): + fixed += ']' + for _ in range(open_braces): + fixed += '}' + try: + result = json.loads(fixed) + import logging + logging.getLogger(__name__).warning(f"JSON repaired by trimming {trim} chars") + return result + except json.JSONDecodeError: + continue + raise ValueError(f"LLM返回的JSON格式无效: {cleaned_response[:500]}") diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8c4fa710..fee02cad 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1331,7 +1331,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -1809,7 +1808,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -1943,7 +1941,6 @@ "integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -2018,7 +2015,6 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz", "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==", "license": "MIT", - "peer": true, "dependencies": { "@vue/compiler-dom": "3.5.25", "@vue/compiler-sfc": "3.5.25",