解决方案 —— 对于反序列化出现问题,出现多重转义符号的json文件解析

背景

最近年后受到导师推荐来一个做算法的公司实习,公司最近新推出了产品,可以提供稳定模型服务等,我作为小小实习生,为了研究 deepseek 模型的prefix caching的实现,收到的任务就是研究一下提示词的前缀和如果进行前缀缓存命中率

问题描述

遇到的数据经过一点点省略后如下:

{"request_body":"{\\\"model\\\":\\\"deepseek/deepseek_v3\\\",\\\"messages\\\":[{\\\"role\\\":\\\"system\\\",\\\"content\\\":\\\"You ...

问题分析以及尝试过的解决方案

requestbody里的数据,经过了错误的多重转义。

  1. 试图和ai交互来解决这些问题,结果4o,cloude3,deepseekr1全废(2025.2.11)

有可能是因为在输入的时候,作为string读入或者别的,ai去理解这些带转义符的字符串也会受到阻碍,甚至有些ai在读入这些字符串的时候会查错转义字符的数量

  1. 自己自作聪明写了类似的解决方案:
def parse_request_body(text):
    for i in range(20,0,-1):
        pattern = "\\" * i + '"'
        text = text.replace(pattern,'"')
        pattern = "\\" * i + 'n'
        text = text.replace(pattern,'\n')

事后来分析,思路整体上没什么问题,不管是由于几次错误转义导致的问题,都能差不多还原回来,唯一的问题是可能要枚举处理所有特殊情况,比如unicode,比如制表符。

本以为此时找到了一个相对不错的方案,只要没有用户瞎输入类似于\\",或者\n这种子串,应该都不会破坏本来的输入还原回来。

遇到的问题

本以为还不错的解决方案,没想到碰到高手了:
人家本来在message里的较多的转义符,就是不想被翻译成"的,不然反倒会影响json的解析,也就是说本来json里就该有这些//

我还傻乎乎的在这转换,结果出来的都没办法解析。

真正的高手方案

正苦恼,没办法通过简单的替换来解决(其实按照正确的顺序,一层一层的解,是有机会替换回去的),结果看到了一个解决方案

import json
import request_part as reqs

print("Parsing %d requests...", len(reqs.request))
for i in range(len(reqs.request)):
    # 解析 JSON 字符串
    data = json.loads(reqs.request[i])

    # 提取 "messages" 字段的内容
    req_body = json.loads(data['request_body'])

而request_part文件,就是把json文件读入后,把整个python list输出出来(list的每一项由于没法被解析为python,都是字符串形式)
image

问题居然就这样解决了???!!!
居然只是把json存储变成python列表存储,就可以处理转义字符了???

原因分析

十分不服,也很困惑,于是写了如下的代码进行对比:

def extract_messages(data):
    content_list = []
    req_body = reqs.request
    for i in range(1):
        data_1 = reqs.request[i]
        data_2 = data[i]
        
    
        print(repr(data_1))
        print('--------------------------------')
        print(repr(data_2))
        print('--------------------------------')
        
        # 比较 data_1 和 data_2是否相同
        if data_1 == data_2:
            print("data_1 和 data_2_str 是相同的")
        else:
            print("data_1 和 data_2_str 是不同的")
    
    return content_list

if __name__ == "__main__":
    cache_file_path = 'json_data_cache.pkl'
    data = read_data_with_cache(cache_file_path)
    extract_messages(data)

data_1就是他的数据,data_2是我的数据,经过比较发现,唯一的区别就是,我的是json数据形式的字符串,他的是string数据形式的字符串。

为什么我是json呢?因为我在别的程序里,使用json.loads读取了json文件,并且存储为了pickle。

我此时对于data_1,可以通过两层加载的方式自动解码:

data_1_outer = json.loads(data_1)
req_body = json.loads(data_1_outer['request_body'])

解决方案

解决方案巨简单,就是将我没法进行python.loads()的数据,这个形式为:{/"xx/"...的数据,当作string去处理,将其前后分别加入一个",使其形式变成"{/"xx/"... ,就可以进行json.loads了。

posted @ 2025-02-11 15:43  ZzTzZ  阅读(205)  评论(1)    收藏  举报