本文将介绍如何使用大模型来完成汉字填字游戏。
这一次,我们将利用大模型来做一件酷酷的事情,那就是用它来完成汉字填字游戏(word
puzzle)。
填字游戏
填字游戏一般在国外较受欢迎。填字游戏 一般给出一个矩形的表格。这个表格被分割为若干个大小相同的方格,方格的颜色有白色与黑色两种。白色的方格组成一些交叉的行与列,行列的长度不等。玩家根据题目所提供的有关信息,将答案填入这些行与列之中,每个白色方格中只能填入一个字。
笔者在公交上打开澎湃新闻App,里面有"澎湃填字"游戏,本次游戏的界面如下:
澎湃填字游戏
游戏中的题目如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 1. 李清照的词《一剪梅·红藕香残玉簟秋》中“一种相思,两处闲愁”的上一句,7 2. 印度洋的一个岛国,首都科伦坡,4 3. 一种伞形装备,用于从飞机上空头人员或物质等,3 4. 苏轼的词《念奴娇·赤壁怀古》中“浪淘尽,千古风流人物”的上一句,4 5. 一种可以用作宠物饲养的可爱鸭子,即Call duck,3 6. 中国最早的出版社之一,1912年1月1日成立于上海,4 7. 横跨欧亚两洲的一个国家,首都是安卡拉,3 8. 中国的一个知名音乐节,今日因在南阳成“音乐劫”引发关注,5 9. 中国最大的内陆咸水湖,也是世界上海拔最高的湖泊之一,3 10. 中国古代四大发明之一,蔡伦是其发明者,3 一、曾让牛顿痴迷的中世纪炼金术中,“神圣三元素”包括硫磺、盐和哪种物质?,2 二、“迪士尼公主”大家庭中,唯一设定没有皇室血统或身份的公主形象是谁?,3 三、一种充满复杂通道的建筑物,很难找到正确的通行道路,3 四、汉代蔡邕用柯亭竹所制的著名笛子,后泛指美笛,3 五、成语,喜欢做某事,并在其中获得乐趣,4 六、上海的一所知名财经类高校,校训是“厚德博学,经济匡时”,4 七、清朝洋务运动中成立的近代军事工业生产机构,也是近代中国最大的军火工厂,5 八、李煜的词《浪淘沙》中“天上人间”的上一句,7 九、今日“巴以冲突”再起,其中“巴”是指那个国家,4 十、学术上用来表示特殊意义的专门用语,2
其中,阿拉伯数字开头的是竖排,汉字数字开头的代表横排,最后的数字代表答案的字数。
既然大模型的能力很好很强大,那么,我们为什么不尝试用LLM来完成填字游戏呢?
Let's go!
程序
首先先介绍下笔者的解决思路。
需要调用搜索引擎。一是因为题目中包含最近的时事新闻,二是因为ChatGPT对于汉语,尤其是诗词的理解能力较弱,三是因为有了搜索引擎,才使回复更好更完善,并给出答案解释,类似与perplexity.ai
写一个合适的prompt,包含搜索引擎的结果作为背景知识
限定回答的字数,这个采用openai中的模型调用参数max_tokens
来实现
回答时先解决竖排,再解决横排。当知道竖排结果时,可以对横排结果的答案进行限制,这边采用openai中模型调用参数logit_bias
来实现
实现的Python程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 import osimport openaiimport tiktokenfrom langchain.tools import Toolfrom langchain.utilities import GoogleSearchAPIWrapper os.environ["GOOGLE_CSE_ID" ] = "xxx" os.environ["GOOGLE_API_KEY" ] = "xxx" class ChnWordPuzzle (object ): def __init__ (self, model_name, query, answer_number, special_rules ): self.model_name = model_name self.query = query self.answer_number = answer_number self.special_rule = special_rules def get_google_search_result (self ): search = GoogleSearchAPIWrapper() def top5_results (query ): return search.results(query, 5 ) tool = Tool( name="Google Search" , description="Search Google for recent results." , func=top5_results, ) result = tool.run(self.query) return result def make_prompt (self ): prefix_prompt = "请根据搜索引擎的结果,回答下面的问题。搜索结果如下:\n" search_prompt = "" try : for record in self.get_google_search_result(): search_prompt += f"标题:{record['title' ]} ,内容:{record['snippet' ]} \n" except Exception: pass suffix_prompt = f"问题:{self.query} 。请用{self.answer_number} 个汉字进行回答。" prompt = prefix_prompt + search_prompt + suffix_prompt return prompt def solve (self ): openai.api_key = "sk-xxx" prompt = self.make_prompt() print (prompt) logit_bias_dict = {} enc = tiktoken.encoding_for_model(self.model_name) for no, char in self.special_rule.items(): for token_id in enc.encode(char): logit_bias_dict[token_id] = 10 print (logit_bias_dict) response = openai.ChatCompletion.create( model=self.model_name, messages=[ {"role" : "user" , "content" : prompt} ], max_tokens=self.answer_number + 3 , temperature=0 , logit_bias=logit_bias_dict ) return response['choices' ][0 ]['message' ]['content' ]if __name__ == '__main__' : my_query = "李清照的词《一剪梅·红藕香残玉簟秋》中“一种相思,两处闲愁”的上一句" my_answer_number = 7 my_model_name = "gpt-3.5-turbo" my_special_rules = {} chn_word_puzzle = ChnWordPuzzle(my_model_name, my_query, my_answer_number, my_special_rules) print (chn_word_puzzle.solve()[:my_answer_number])
在实际运行程序时,将Google search的API
key和OpenAI的key替换成自己的。
我们来看一下,第一个问题的prompt和答案。
1 2 3 4 5 6 7 8 9 请根据搜索引擎的结果,回答下面的问题。搜索结果如下: 标题:李清照,花自飘零水自流,《一剪梅·红藕香残玉簟秋》,表达思念_独 ... ,内容:May 3, 2019 ... 李清照的词能够唤起很多人们对情感的追索,对于情感的一种追忆。从李清照的词中人们能够找到很多现实生活中情感的寄托。这首词的意思就是:“粉红色的 ... 标题:一剪梅·红藕香残玉簟秋_百度百科,内容:一剪梅·红藕香残玉簟秋》是宋代女词人李清照的词作。此词作于词人与丈夫赵明诚离别之后,先写清秋时节与爱人别后,独上兰舟以排遣愁怀,西楼望月恨雁来无书, ... 标题:一剪梅·红藕香残玉簟秋原文、翻译及赏析、拼音版_李清照_古诗文网,内容:轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月满西楼。花自飘零水自流。一种相思,两处闲愁。此情无计可消除,才下眉头,却上 ... 词的上阕首句 ... 标题:一剪梅•红藕香残玉簟秋,李清照玉簟秋赏析,一种相思两处闲愁- 知乎,内容:Mar 5, 2020 ... 这首词牌名“一剪梅”分为上下两阕(que,四声),阕字义是“停止”的意思,用在词里面,一般指“一段”的意思,这首词牌名是分为两段的,第一段称为上阕,第二 ... 标题:"花自飘零水自流。一种相思,两处闲愁。" 全诗赏析_古诗文网,内容:原文. 李清照《一剪梅·红藕香残玉簟秋》. 红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月满西楼。 花自飘零水自流。一种相思,两处闲愁。此 ... 问题:李清照的词《一剪梅·红藕香残玉簟秋》中“一种相思,两处闲愁”的上一句。请用7个汉字进行回答。 {} 花自飘零水自流
回答正确!Perfect!
实验
我们使用gpt-3.5-turbo
模型,对前10个问题进行测试,答案如下:
1 2 3 4 5 6 7 8 9 10 1. 花自飘零水自流 2. 斯里兰卡 3. 投物伞 4. 大江东去 5. 柯尔鸭 6. 中华书局 7. 土耳其 8. 迷笛音乐节 9. 青海湖 10. 蔡伦
其中,第10个回答明确有错,我们调用GPT-4
模型,可得到正确答案:造纸术。
在得到竖排答案后,我们在回答横排问题时,可以用竖排的答案对回复进行约束,比如在回答横排第二个问题“迪士尼公主”大家庭中,唯一设定没有皇室血统或身份的公主形象是谁?
时,我们知道第一、第三个字分别为花、兰,那么答案应该为花X兰。于是,我们将my_special_rules
= {"一": "花", "三": "兰"},可对答案进行约束。
横排答案如下:
1 2 3 4 5 6 7 8 9 10 一. 水银 二. 花木兰 三. 迷宫 四. 柯亭笛 五. 乐在其中 六. 上海财大 七. 江南制造局 八. 流水落花春去也 九. 巴勒斯坦 十. 术语
总结
在上述的解决方案中,竖排的第3个回答投物伞
有误,这是Google
Search和大模型回复共同导致的错误。正确答案为降落伞,作为人可以轻松地回答出来,而大模型+搜索引擎竟然不行!
竖排的第10个回答,gpt-3.5-turbo
模型错误,而GPT-4
模型回答正确。
同时,横排的第一个问题在Google
Search没有搜索结果,靠logit_bias约束答案中有“水”字生成的答案为水银,答案正确。
最后,横排的第六个问题,答案为上海财大,但如果logit_bias的值设为5,答案为上海财经,由于竖排的答案已知最后一个为大字,所以可调整logit_bias的值。
在上述的种种调试下,使用gpt-3.5-turbo
模型,回答正确共18个,正确率90%。
综上,
尽管有Google Search的加持,但大模型还是会回答错误。
Google Search存在搜索无结果,因此需要容错。
logit_bias的值有一定的概率会生成错误答案。
因此,上述的解决方案还不十分靠谱,期待下次优化~
欢迎关注我的公众号
NLP奇幻之旅 ,原创技术文章第一时间推送。
欢迎关注我的知识星球“自然语言处理奇幻之旅 ”,笔者正在努力构建自己的技术社区。