binary-husky/gpt_academic · error · ValueError
解析GEMINI消息出错。
Error message
解析GEMINI消息出错。
What it means
ValueError ('解析GEMINI消息出错。') raised when the regex-extracted "text" field from a Gemini stream frame cannot be re-assembled into valid JSON: the code fishes the captured group out of the raw SSE bytes with a regex, wraps it as '{"text": "%s"}', and calls json.loads. If the captured string contains unescaped quotes, control characters, or unicode the naive wrapping can't represent, json.loads throws and this error replaces it. It signals the hand-rolled parser lost against Gemini's escaping, not that Gemini itself errored (error frames take the separate error_match branch).
Source
Thrown at request_llms/bridge_google_gemini.py:36
def predict_no_ui_long_connection(inputs:str, llm_kwargs:dict, history:list=[], sys_prompt:str="", observe_window:list=[],
console_silence:bool=False):
# 检查API_KEY
if get_conf("GEMINI_API_KEY") == "":
raise ValueError(f"请配置 GEMINI_API_KEY。")
genai = GoogleChatInit(llm_kwargs)
watch_dog_patience = 5 # 看门狗的耐心, 设置5秒即可
gpt_replying_buffer = ''
stream_response = genai.generate_chat(inputs, llm_kwargs, history, sys_prompt)
for response in stream_response:
results = response.decode()
match = re.search(r'"text":\s*"((?:[^"\\]|\\.)*)"', results, flags=re.DOTALL)
error_match = re.search(r'\"message\":\s*\"(.*?)\"', results, flags=re.DOTALL)
if match:
try:
paraphrase = json.loads('{"text": "%s"}' % match.group(1))
except:
raise ValueError(f"解析GEMINI消息出错。")
buffer = paraphrase['text']
gpt_replying_buffer += buffer
if len(observe_window) >= 1:
observe_window[0] = gpt_replying_buffer
if len(observe_window) >= 2:
if (time.time() - observe_window[1]) > watch_dog_patience: raise RuntimeError("程序终止。")
if error_match:
raise RuntimeError(f'{gpt_replying_buffer} 对话错误')
return gpt_replying_buffer
def make_media_input(inputs, image_paths):
image_base64_array = []
for image_path in image_paths:
path = os.path.abspath(image_path)
inputs = inputs + f'<br/><br/><div align="center"><img src="file={path}"></div>'
base64 = encode_image(path)
image_base64_array.append(base64)
return inputs, image_base64_arrayView on GitHub (pinned to d6bde0fa54)
Solutions
- Retry the query — transient chunk-boundary splits often parse fine on a second attempt.
- Update gpt_academic: newer bridge_google_gemini.py replaced regex fishing with proper full-frame JSON parsing.
- If persistent, reduce prompt-induced heavy quoting (ask for plain text instead of JSON/code blocks) to confirm parser escaping is the cause.
- Check the proxy chain: intermediary re-chunking of the SSE stream is a common amplifier of partial-frame parse failures.
Example fix
# before (fragile regex reassembly)
paraphrase = json.loads('{"text": "%s"}' % match.group(1))
# after (parse the whole frame)
frame = json.loads(response.decode())
buffer = frame["candidates"][0]["content"]["parts"][0]["text"] Defensive patterns
Strategy: retry
Type guard
def is_parseable_gemini_text_frame(raw: bytes) -> bool:
"""A frame is safely parseable only if the regex capture survives JSON re-wrapping."""
import re, json
text = raw.decode(errors='replace')
m = re.search(r'"text":\s*"((?:[^"\\]|\\.)*)"', text, flags=re.DOTALL)
if not m:
return False
try:
json.loads('{"text": "%s"}' % m.group(1))
return True
except Exception:
return False Try / catch
try:
result = predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window)
except ValueError as e:
if '解析GEMINI消息出错' in str(e):
time.sleep(1)
result = predict_no_ui_long_connection(inputs, llm_kwargs, history, sys_prompt, observe_window) # chunk-boundary splits usually clear on retry
else:
raise Prevention
- Retry once — transient SSE chunk-boundary splits are the most common cause.
- Update gpt_academic to a version parsing full Gemini frames with json.loads instead of regex reassembly.
- Avoid proxies that re-chunk SSE frames.
- When prompts induce heavy quoting/code output, prefer models/endpoints whose parsing path is frame-based.
When it happens
Trigger: Gemini streams text containing characters that break the regex/wrapping contract: raw double quotes with unusual escaping, newlines/backslashes in the captured span, non-ASCII output under odd encodings; also fires on chunk boundaries that split an escaped sequence so the regex capture is malformed.
Common situations: Asking Gemini for code with heavy quote/backslash content; Chinese/multilingual replies with unicode escapes; proxy re-chunking SSE frames so decode() yields partial JSON; older bridge versions' regex parser versus newer Gemini response formats.
Related errors
AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14).
Data as JSON: /api/errors/828a898d7af15d34.
Report an issue: GitHub.