jd-opensource/joyagent-jdgenie · error · RuntimeError
解析llm json结果失败
Error message
解析llm json结果失败
What it means
_parse_json_result in table_column_filter.py raises RuntimeError('解析llm json结果失败') when re.findall for the ```json ...``` fenced block on the LLM response returns nothing. It signals the LLM reply was not the expected JSON code block.
Solutions
- Log the full result_str (already logged as 生成结果格式不合法) and strengthen the prompt to demand exactly one ```json fenced block
- Broaden the parser to also accept bare JSON: try json.loads(result_str) directly before regex
- Use response_format/JSON mode if the LLM API supports it, or a json_mode flag in your client
- Retry the LLM call (the surrounding retry loop in _filter_single_table already retries) with an explicit format reminder
Example fix
// before
result = re.findall(r'```json\s*([\s\S]*?)\s*```', result_str)
return result[0]
// after
match = re.findall(r'```(?:json)?\s*([\s\S]*?)\s*```', result_str)
if match:
return match[0]
try:
json.loads(result_str)
return result_str
except Exception:
raise RuntimeError('解析llm json结果失败') Defensive patterns
Strategy: retry
Validate before calling
import re, json
def llm_json_block_ok(result_str: str):
m = re.findall(r'```json\s*([\s\S]*?)\s*```', result_str)
return bool(m) and _is_json(m[0]) Type guard
def is_fenced_json(s):
m = re.match(r'```json\s*([\s\S]*?)\s*```$', s.strip())
return m is not None Try / catch
try:
block = parse_json_result(result_str)
except RuntimeError:
logger.warning('no ```json block, retrying with stricter prompt')
result_str = llm_call(prompt + '\nRespond ONLY with a ```json block.') Prevention
- Use JSON mode / response_format when the LLM API supports it
- Include an explicit output-format example in every prompt
- Log full raw responses on failure
- Retry with format reminder before failing the table
When it happens
Trigger: The LLM response string contains no ```json fenced block (pattern ```json\s*([\s\S]*?)\s*```), e.g. plain text answer, bare JSON without fences, or a different fence language; findall returns [] and result[0] raises IndexError caught and re-raised.
Common situations: Model returns raw JSON without markdown fences; temperature/high randomness makes model drift from the requested format; prompt for column filtering changes; model truncation drops closing fence.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Empty or invalid response from LLM
- Invalid or empty response from LLM
- Error in code parsing
- Invalid tool_choice: " + toolChoice
- 字段" + fieldName + "值\"" + value + "\"转换成数值失败
AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08).
Data as JSON: /api/errors/0bc8dc4d8e16d66c.
Report an issue: GitHub.
Appendix: source
Thrown at genie-tool/genie_tool/tool/table_rag/table_column_filter.py:202
"user_info": self.user_info,
"time_info": self.time_info,
"query": self.query,
"memory_info": memory_info_str,
"error_msg": error_msg
}
table_rag_prompts = get_prompt("table_rag")
prompt = Template(table_rag_prompts["column_filter_prompt"]).render(info_dict)
return prompt
def _parse_json_result(self, result_str):
pattern = r'```json\s*([\s\S]*?)\s*```'
try:
result = re.findall(pattern, result_str)
return result[0]
except Exception as e:
logger.error(f"生成结果格式不合法:{result_str},{e}")
raise RuntimeError("解析llm json结果失败")
async def _filter_single_table(self, semaphore, table_schema_info: dict) -> dict | None:
async with semaphore:
llm_response = ""
request_id = ""
error_msg = None
for retry in range(3):
try:
columns_prompt = self._generate_filter_prompt(table_schema_info, error_msg)
messages = [
{
"role": "system",
"content": "you are a helpful assistant.",
},
{
"role": "user",View on GitHub (pinned to 2417e0b8b6)