Loading... ## 前言 近期需要利用chatgpt制作一个翻译脚本,同时为了一次请求尽可能多的处理翻译,多条翻译结果是通过json进行封装,之后请求gpt的,但实际使用过程中,gpt的返回结果并没有那么让人满意,也可能是我用的只是3.5模型的原因,以下是对常见的一些gpt返回的错误格式的结果处理 ### Prompt ```go GPTJsonPromptFormat = "1.你是一个翻译引擎, 只需要翻译内容而不要解释它;" + "2.我需要你将日文翻译为简体中文,我会给你一个json结构的数组, 键Original内的值是需要翻译的原文,请不要更改他的内容," + "你需要逐个翻译每个结构的内容,并将翻译结果补充至键Translation的值里,并按照json格式返回给我;" ``` ### 请求json ```json [{"Original":"「えーっと、カエデさん……?」","Translation":""},{"Original":"「甘い!甘すぎるわ!クリームなんていらないくらい甘いわ!」","Translation":""},{"Original":"「こういうときはまったりほうじ茶が飲みたくなるわね……」","Translation":""},{"Original":"「でも、泰矢くんたちがすごく幸せなのが良~くわかったわ」","Translation":""},{"Original":"「そ、それなら良かったです」","Translation":""}] ``` ## gpt返回数据条数与请求条数不符 ### 问题描述 例如json数组内请求了20条数据,但可能返回结果只有18条,请求所消耗的tokens也只有2000多,并没有超过上限4096,只能理解为gpt抽风 ### 处理方式 在请求前记录请求内数组数量和返回后数组数量,如果数量对不上,重试请求 ## 返回的结果在最后少一个引号,导致json格式错误无法解析 ### 问题描述 返回结果可能是如下这样,很多次都是固定倒数第三个字符少一个引号,很难说不是gpt故意的,细思极恐 ```json [{"Original":"「えーっと、カエデさん……?」","Translation":"「嗯……卡惠姐姐……?」"},{"Original":"「甘い!甘すぎるわ!クリームなんていらないくらい甘いわ!」","Translation":"「太甜了!太过甜了!不需要奶油什么的,已经够甜了!」"},{"Original":"「こういうときはまったりほうじ茶が飲みたくなるわね……」","Translation":"「这种时候总想喝上一杯悠闲的焙茶呢……」"},{"Original":"「でも、泰矢くんたちがすごく幸せなのが良~くわかったわ」","Translation":"「不过,太矢君他们的幸福感真的~能够好好理解呢」"},{"Original":"「そ、それなら良かったです」","Translation":"「那、那样就好」}] ``` 错误的地方在这里,值的结束位置少一个引号 ``` "Translation":"「那、那样就好」}] ``` ### 处理方式 如果碰到json格式错误,先在倒数第三个字符的位置添加引号后再处理 ```go // GptJsonErrorHandling gpt返回的json解析失败时处理 func GptJsonErrorHandling(str string) (newStr string) { strLen := len(str) index := strLen - 2 newStr = str[:index] + "\"" + str[index:] return newStr } ``` ## 返回结果错误的翻译为了其他语言 ### 问题描述 偶发情况,gpt不遵守prompt要求的从日文翻译为中文,而是翻译为了英文结果返回;或没有翻译,直接日文原文返回了 ### 处理方式 使用正则判断全部的翻译结果,如果满足英文句子正则的结果超过了一半,认为翻译结果无效,重新请求gpt,判断英文句子使用的正则如下 ``` ([a-zA-Z]{2,}\s){2,} ``` 判断日文句子使用的正则如下 ``` [\u3040-\u309F\u30A0-\u30FF]+ ``` ## 返回json内出现了额外的引号 ### 问题描述 这可能和我请求内容有关,请求的内容内的 `「`和 `」`是日语的引号,但是gpt对此有三种处理,不翻译,翻译为中文引号 `“”`,翻译为英文引号 `"`,最头疼的是翻译为英文引号 `"`,会导致json结构错误无法解析 ### 处理方式 这里用到的正则语句比较复杂,go官方正则库regexp不支持,需要安装另一个开源的正则库 ```go go get github.com/dlclark/regexp2 ``` 之后是处理代码 ```go // GptResTextReplace gpt返回文本替换,将全部"替换为\" func GptResTextReplace(str string) (newStr string) { r := regexp2.MustCompile("(?<={"Original":")(.*?)(?=","Translation":")|(?<=","Translation":")(.*?)(?="})", 0) //定义一个替换函数 var evaluator = func(m regexp2.Match) string { s := m.String() s = strings.ReplaceAll(s, "\"", "\\\"") return s } //查找子函数进行替换 newStr, err := r.ReplaceFunc(str, evaluator, -1, -1) if err != nil { return "" } return } ``` ## 返回内容出现繁体字 ### 问题描述 哪怕在prompt声明了需要翻译为`简体中文`,gpt依旧不管这些,日文翻译为中文时会出现很多繁体文字,这些还是需要代码进行替换 ### 处理方式 #### 方案一(放弃) 判断繁体中文句子使用的正则如下,实际使用发现这个繁体中文的正则可能匹配的只是生僻字,一些复杂的汉字仍属于简体字,但存在繁体形式,故放弃正则匹配 ``` [\u3400-\u4db5]+ ``` #### 方案二 对全部翻译结果直接进行处理,用到的一个繁体简体文字处理的依赖包 ```go go get github.com/go-creed/sat ``` 实现代码超级简单,str为待处理文本,似乎在性能上损耗也不是很大 ```go dicter := sat.DefaultDict() str = dicter.Read(str) ``` ## 返回内容为空值 ### 问题描述 返回的json中`Translation`字段的值为空值 ### 处理方式 判断非空,为空时重新请求gpt ## 翻译文本错位 ### 问题描述 返回的json中`Original`字段的值也被翻译了 ### 处理方式 一般出现这种情况,`Original`字段的值和`Translation`字段的值都会变成译文,且文本相同,判断他们文本是否相同,相同时重新请求gpt ## 返回内容不完整 ### 问题描述 请求和回复的内容所消耗的tokens都并没有超过4096,但有时就会突然结束文本,末尾是省略号`...` ### 处理方式 只能重新请求gpt ## 返回内容奇怪格式 ### 问题描述 返回了这种这样奇怪键值的json ``` {"Original":"Translation":""} ``` ### 处理方式 只能重新请求gpt ## 英文引号被翻译为了中文引号 ### 问题描述 json的键与键之间只能用英文逗号`,`进行分割,gpt返回的内容中用的却是中文逗号`,`分割,导致json无法解析 ``` {"Original":"「ちょ、ちょっとカエデ様!いきなり何を言ってるんですか!」||「念のためよ、念のため」","Translation":"等等,等等啊,楓大人!你突然說什麼啊!||預先說一下,預先說一下"} ``` ### 处理方式 其实先用正则取出所有的键值分割符号,再全部进行替换也可以,但这种情况出现的很少,没那个必要单独进行处理,直接重新请求更方便 最后修改:2023 年 06 月 23 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意打赏