我正在使用生成性AI API返回文本响应作为JSON字符串,这些字符串我打算实时输入到一个应用程序中。问题是GenAI API提供的JSON响应经常包含小错误——最常见的是双引号问题。这些响应JSON字符串中的语法问题在我的Python代码中转换为JSON时会触发错误。
例如,我有以下JSON字符串:'{"test":"this is "test" of "a" test"","result":"your result is "out" in our website"}'
如你所见,“test”的值包含多个双引号。所以如果我尝试将其转换为JSON,我会得到一个错误。我想做的是使用正则表达式将双引号转换为单引号。结果可以如下所示:'{"test":"this is 'test' of 'a' test'", "result": "your result is 'out' in our website"}'
我目前能做的最好方法如下:
def repl_call(m): preq = m.group(1) qbody = m.group(2) qbody = re.sub( r'"', "'", qbody ) return preq + '"' + qbody + '"'print( re.sub( r'([:\[,{]\s*)"(.*?)"(?=\s*[:,\]}])', repl_call, text ))
以下代码成功返回了预期的结果。然而,如果我添加一个逗号,例如{"test":"this is "test" of "a", test"","result":"your result is "out" in our website"}
…代码就会出错并返回以下内容:'{"test":"this is 'test' of 'a", test"","result":"your result is 'out' in our website"}'
🙁
目前我已经尝试通过改进我的AI提示(提示工程)来避免双引号,并只返回有效的JSON字符串。这在一定程度上有效,但我仍然遇到足够多的语法错误,需要多次重试相同的提示——这会导致不必要的延迟和成本。
我的问题是:在Python中是否有常用的函数和REGEX模式可以应用于修复我的JSON字符串,使其正确清理语法错误?特别是与错位的双引号有关的错误。
我对各种建议持开放态度,包括可能的Python包,可以处理JSON字符串清理。甚至关于高级GenAI工具的任何建议,这些工具可以执行JSON强制。我目前使用Gemeni——我非常喜欢它。但它不像OpenAI的API那样明确允许JSON强制执行。
回答:
如果你请求返回JSon,你应该使用response_mime_type,这样你就不会遇到解析JSon的问题。
from dotenv import load_dotenvimport google.generativeai as genaiimport osload_dotenv()genai.configure(api_key=os.environ['API_KEY'])MODEL_NAME_LATEST = os.environ['MODEL_NAME_LATEST']model = genai.GenerativeModel( model_name=MODEL_NAME_LATEST, # 将`response_mime_type`设置为输出JSON generation_config={"response_mime_type": "application/json"})prompt = """ 列出5种受欢迎的饼干食谱。 使用此JSON模式: Recipe = {"recipe_name": str} 返回一个`list[Recipe]` """response = model.generate_content(prompt)print(response.text)
请记住,确保你告诉它使用的JSon对象实际上是正确的JSon,否则它可能会错误地构建它,包括所有应该有的逗号。
响应模式
另一个选项是使用响应模式。
from dotenv import load_dotenvimport google.generativeai as genaiimport osimport typing_extensions as typingload_dotenv()genai.configure(api_key=os.environ['API_KEY'])MODEL_NAME_LATEST = os.environ['MODEL_NAME_LATEST']class Recipe(typing.TypedDict): recipe_name: strmodel = genai.GenerativeModel( model_name=MODEL_NAME_LATEST, # 将`response_mime_type`设置为输出JSON # 将模式对象传递给`response_schema`字段 generation_config={"response_mime_type": "application/json", "response_schema": list[Recipe]})prompt = "列出5种受欢迎的饼干食谱"response = model.generate_content(prompt)print(response.text)
参见 Json模式