Python使用json_repair輕松修復(fù)大模型返回的非法JSON
為什么大模型生成的 JSON 需要修復(fù)
在使用大語(yǔ)言模型(LLM,例如 GPT 系列)時(shí),我們經(jīng)常要求模型返回結(jié)構(gòu)化的 JSON 數(shù)據(jù),以便程序進(jìn)一步解析和處理。然而,現(xiàn)實(shí)中模型輸出的 JSON 往往“不夠干凈”——可能會(huì)在前后多出說(shuō)明文字、注釋、甚至中途缺少引號(hào)或逗號(hào),從而導(dǎo)致 json.loads() 報(bào)錯(cuò)。
一個(gè)典型的錯(cuò)誤場(chǎng)景如下。
大語(yǔ)言模型在生成 JSON 數(shù)據(jù)時(shí),可能會(huì)出現(xiàn)多種格式問(wèn)題:
括號(hào)不匹配:缺少閉合的括號(hào)或方括號(hào)
# 模型可能返回
broken_json1 = '{"活動(dòng)名稱": "旋轉(zhuǎn)木馬", "游玩體驗(yàn)": "孩子們玩得非常開心!"'
缺失引號(hào):鍵或字符串值缺少引號(hào)
broken_json2 = '{活動(dòng)名稱: "旋轉(zhuǎn)木馬", "游玩體驗(yàn)": "孩子們玩得非常開心!"}'
缺少逗號(hào):鍵值對(duì)之間缺少分隔符
broken_json3 = '{"活動(dòng)名稱": "旋轉(zhuǎn)木馬" "游玩體驗(yàn)": "孩子們玩得非常開心!"}'
特殊字符未轉(zhuǎn)義:包含未轉(zhuǎn)義的特殊字符
broken_json4 = '{"描述": "這是一個(gè)"包含引號(hào)"的字符串"}'
非 JSON 內(nèi)容混雜:輸出中包含解釋性文本或其他非 JSON 內(nèi)容
broken_json5 = """
這里是返回的結(jié)果:
{
"name": "Alice",
"age": 25,
"city": "New York", // 用戶所在城市
}
"""
傳統(tǒng)處理方式的局限性
當(dāng)面對(duì)這些有問(wèn)題的 JSON 時(shí),開發(fā)者通常會(huì)考慮:
- 提示工程:優(yōu)化提示詞,明確要求模型輸出標(biāo)準(zhǔn) JSON
- 多次調(diào)用:當(dāng)?shù)谝淮畏祷責(zé)o效 JSON 時(shí),再次請(qǐng)求模型修正
- 正則表達(dá)式:編寫復(fù)雜的正則表達(dá)式來(lái)提取 JSON 部分
然而,這些方法都存在明顯缺點(diǎn):提示工程效果不穩(wěn)定,多次調(diào)用增加時(shí)間和 token 消耗,正則表達(dá)式編寫維護(hù)困難且容易出錯(cuò)。
有沒(méi)有更優(yōu)雅、更自動(dòng)化的方式?答案就是 —— json_repair。
一、什么是 json_repair
json_repair 是一個(gè) Python 庫(kù),用于自動(dòng)修復(fù)無(wú)效的 JSON 字符串。它會(huì)分析字符串中的結(jié)構(gòu)、引號(hào)、括號(hào)、逗號(hào)等錯(cuò)誤,嘗試將其糾正為可被 json.loads() 正常解析的合法 JSON。
相比于正則修正或多次調(diào)用大模型,json_repair 的優(yōu)勢(shì)在于:
無(wú)需二次調(diào)用模型,執(zhí)行速度快
可自動(dòng)修復(fù)常見(jiàn)錯(cuò)誤,例如:
- 缺少引號(hào)
- 結(jié)尾多余逗號(hào)
- 單引號(hào)替換為雙引號(hào)
- 非法字符混入
- JSON 前后附帶額外內(nèi)容
二、安裝方法
使用 pip 安裝:
pip install json-repair
三、基本用法示例
來(lái)看一個(gè)實(shí)際例子。假設(shè)大模型返回了以下內(nèi)容:
from json_repair import repair_json
import json
response = """
模型輸出:
{
name: 'Alice',
"age": 25,
"city": "New York",
}
"""
# 使用 json_repair 修復(fù)
fixed = repair_json(response)
print(fixed)
# 輸出:
# {"name": "Alice", "age": 25, "city": "New York"}
# 現(xiàn)在可以正常解析
data = json.loads(fixed)
print(data["name"]) # Alice
json_repair 自動(dòng)完成了幾個(gè)修復(fù)動(dòng)作:
- 為
name補(bǔ)上了引號(hào) - 將
'Alice'轉(zhuǎn)換為"Alice" - 去掉了最后一個(gè)多余的逗號(hào)
- 忽略了前面的“模型輸出:”這段無(wú)關(guān)內(nèi)容
四、更復(fù)雜的場(chǎng)景
有時(shí),大模型可能在 JSON 前后附帶了解釋說(shuō)明,例如:
response = """
以下是結(jié)果:
{
"status": "ok",
"data": {
"id": 123,
"items": ["apple", "banana"]
}
}
謝謝!
"""
這種情況下,json.loads() 同樣無(wú)法直接解析。
而使用 json_repair:
fixed = repair_json(response) print(json.loads(fixed))
輸出結(jié)果:
{'status': 'ok', 'data': {'id': 123, 'items': ['apple', 'banana']}}
json_repair 能夠智能識(shí)別出中間那段是完整的 JSON 塊,并自動(dòng)去除多余文字。
五、異常修復(fù)與邊界情況
json_repair 并非萬(wàn)能。如果輸入的內(nèi)容嚴(yán)重破損,例如括號(hào)完全不匹配、結(jié)構(gòu)不完整,它可能無(wú)法百分百恢復(fù)。
但它會(huì)盡力返回“最接近合法 JSON”的結(jié)果,而不會(huì)拋出異常。
示例:
bad_json = "{ name: Alice, age: 30"
fixed = repair_json(bad_json)
print(fixed)
# 輸出:{"name": "Alice", "age": 30}
六、實(shí)戰(zhàn)建議
優(yōu)先嘗試 json.loads(),若失敗再使用 json_repair。
這樣可以避免對(duì)原本就合法的 JSON 進(jìn)行不必要的處理。
try:
data = json.loads(response)
except json.JSONDecodeError:
data = json.loads(repair_json(response))
結(jié)合日志輸出,記錄修復(fù)前后的差異,方便排查模型輸出問(wèn)題。
不建議用于安全敏感場(chǎng)景(例如:直接信任外部輸入的 JSON),因?yàn)樾迯?fù)過(guò)程中會(huì)進(jìn)行字符串推斷。
七、總結(jié)
當(dāng)我們依賴大模型生成 JSON 數(shù)據(jù)時(shí),不可避免會(huì)遇到各種格式錯(cuò)誤的問(wèn)題。json_repair 讓我們不再需要反復(fù)提示模型“請(qǐng)返回合法 JSON”,也不必浪費(fèi) token 進(jìn)行多輪修正。
一句 repair_json(response),即可輕松將混亂的字符串變?yōu)榭捎玫慕Y(jié)構(gòu)化數(shù)據(jù)。
它的出現(xiàn),讓 LLM 與后端程序之間的數(shù)據(jù)對(duì)接更穩(wěn)定、更高效。
到此這篇關(guān)于Python使用json_repair輕松修復(fù)大模型返回的非法JSON的文章就介紹到這了,更多相關(guān)Python修復(fù)返回的非法JSON內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python通過(guò)LangChain調(diào)用LLM模型的完整過(guò)程
- Python與Java接入AI模型的MCP協(xié)議的原理與實(shí)現(xiàn)
- Python從零開始訓(xùn)練AI模型的實(shí)用教程
- python taipy庫(kù)輕松地將數(shù)據(jù)和機(jī)器學(xué)習(xí)模型轉(zhuǎn)為功能性Web應(yīng)用
- Python Multinomial Naive Bayes多項(xiàng)貝葉斯模型實(shí)現(xiàn)原理介紹
- Python實(shí)例:從零開始構(gòu)建訓(xùn)練AI模型(詳細(xì)圖文教程)
相關(guān)文章
Python利用SSH隧道實(shí)現(xiàn)數(shù)據(jù)庫(kù)訪問(wèn)
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)sshtunnel類庫(kù)建立SSH隧道,再使用paramiko通過(guò)SSH來(lái)訪問(wèn)數(shù)據(jù)庫(kù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03
Python特性之列表推導(dǎo)式和生成器表達(dá)式詳解
這篇文章主要介紹了python語(yǔ)言的兩個(gè)非常有用的特性:列表推導(dǎo)式和生成器表達(dá)式,但是它們之間也有一些重要的區(qū)別,我們一起來(lái)看看吧2023-08-08
Pandas對(duì)每個(gè)分組應(yīng)用apply函數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了Pandas對(duì)每個(gè)分組應(yīng)用apply函數(shù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

