前言

近期需要利用chatgpt制作一个翻译脚本,同时为了一次请求尽可能多的处理翻译,多条翻译结果是通过json进行封装,之后请求gpt的,但实际使用过程中,gpt的返回结果并没有那么让人满意,也可能是我用的只是3.5模型的原因,以下是对常见的一些gpt返回的错误格式的结果处理

Prompt

GPTJsonPromptFormat = "1.你是一个翻译引擎, 只需要翻译内容而不要解释它;" +
        "2.我需要你将日文翻译为简体中文,我会给你一个json结构的数组, 键Original内的值是需要翻译的原文,请不要更改他的内容," +
        "你需要逐个翻译每个结构的内容,并将翻译结果补充至键Translation的值里,并按照json格式返回给我;"

请求json

[{"Original":"「えーっと、カエデさん……?」","Translation":""},{"Original":"「甘い!甘すぎるわ!クリームなんていらないくらい甘いわ!」","Translation":""},{"Original":"「こういうときはまったりほうじ茶が飲みたくなるわね……」","Translation":""},{"Original":"「でも、泰矢くんたちがすごく幸せなのが良~くわかったわ」","Translation":""},{"Original":"「そ、それなら良かったです」","Translation":""}]

gpt返回数据条数与请求条数不符

问题描述

例如json数组内请求了20条数据,但可能返回结果只有18条,请求所消耗的tokens也只有2000多,并没有超过上限4096,只能理解为gpt抽风

处理方式

在请求前记录请求内数组数量和返回后数组数量,如果数量对不上,重试请求

返回的结果在最后少一个引号,导致json格式错误无法解析

问题描述

返回结果可能是如下这样,很多次都是固定倒数第三个字符少一个引号,很难说不是gpt故意的,细思极恐

[{"Original":"「えーっと、カエデさん……?」","Translation":"「嗯……卡惠姐姐……?」"},{"Original":"「甘い!甘すぎるわ!クリームなんていらないくらい甘いわ!」","Translation":"「太甜了!太过甜了!不需要奶油什么的,已经够甜了!」"},{"Original":"「こういうときはまったりほうじ茶が飲みたくなるわね……」","Translation":"「这种时候总想喝上一杯悠闲的焙茶呢……」"},{"Original":"「でも、泰矢くんたちがすごく幸せなのが良~くわかったわ」","Translation":"「不过,太矢君他们的幸福感真的~能够好好理解呢」"},{"Original":"「そ、それなら良かったです」","Translation":"「那、那样就好」}]

错误的地方在这里,值的结束位置少一个引号

"Translation":"「那、那样就好」}]

处理方式

如果碰到json格式错误,先在倒数第三个字符的位置添加引号后再处理

// 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 get github.com/dlclark/regexp2

之后是处理代码

// 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 get github.com/go-creed/sat

实现代码超级简单,str为待处理文本,似乎在性能上损耗也不是很大

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 日
如果觉得我的文章对你有用,请随意打赏