关于《鹦鹉之梦与提线木偶》中的鹦鹉学舌程序的尝试

本文基于《鹦鹉之梦与提线木偶》中的巴德鲁对话程序,描述了如何通过Python编程实现简单的对话交互。通过关键词分类和提问模式,模拟了智能机器人对人类对话的即时响应,探讨了使用jieba分词和词性分析来识别并提问重点词汇的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在2019年1期的《科幻世界》中我偶然看到了《鹦鹉之梦与提线木偶》里面的巴德鲁的对话程序我非常感兴趣,文章节选我分为两部分,使用案例和实现方式(引自《鹦鹉之梦与提线木偶》文/【日】藤井太洋 译/田田)

(文中的使用案例)

“谢谢。”飞美从四轮降到沙发高度的托盘上取下咖啡。

“不客气。”巴德鲁演示起飞美为它安装的回礼程序。

“还是要谢谢你。”飞美摸了摸巴德鲁的脑袋。

“谢谢你巴德鲁,你能和飞美说说话吗?”

巴德鲁看了一眼飞美的脸,然后开口道:“飞美总经理,您吃过饭了吗?”

“这又是什么鬼把戏?”飞美问。

“我编了简单的对话程序,试试和它说话吧。你吃过饭了吗?”

(略)…………………………

于是,我决定尝试一条新的思路。

“很遗憾,我已经吃过了。”

飞美话音刚落,巴德鲁就在恰好的时机接话道:“是吗,您吃的什么?”

“对面的那家温迪汉堡。”

“哦,是温迪汉堡呀?好吃吗?”

“一般般吧。”

“哦,一般般呀?有没有什么优点呢?”

“生菜还不错。”

“哦,生菜还不错呀?您喜欢生菜吗?”

“嗯,我爱吃蔬菜。有一次我在旧金山吃汉堡,里面夹的蔬菜鲜美极了。没想到日本也有这么香甜的生菜。”

“您喜欢旧金山吗?”

“喜欢。”

“是吗,您喜欢旧金山的哪一点呢?”

“嗯……”飞美一时答不上来,就冲巴德鲁挥了挥手。美味美公司的巴德鲁会在看到“再见”的手势时停止说话——这个设定是由飞美最初提议,我负责安装的。

只见巴德鲁晃了晃上身,发出“唔”的一声,像是在表示遗憾。“飞美总经理,下次记得和我讲讲旧金山的事。再见!”巴德鲁先是向后退了大约三十厘米,然后领着四轮离开了办公室。

“怎么样?”

“不可思议!”

“随便从公司里抓来一个巴德鲁,只要提起刚才的话,它就会陪你聊有关旧金山的事!如果把相应的照片分享到公共文件夹里,巴德鲁就会对照片提问。要是你把上次去旧金山出差时的照片传上去,它或许会问你喜不喜欢金门大桥。”

(文中描述的实现方式)

“说话的一直都是飞美。巴德鲁只是听了你的话,并对其中的关键词进行了提问而已。”

我掰着手指数道:“怎么样、你喜欢吗、喜欢哪里、有没有什么优点——我为巴德鲁输入了很多这样提问模式,然后让它对听到的关键词进行分类,比如场所、商品、人名等等。最后,再让它根据关键词的分属性选择问题即可。这种设计的关键就在于反应速度,这个飞美也注意到了。从人声的输入到应答的输出需要等待一段时间,而我要做的就是将这段时间尽可能地缩短。”

“你是怎么做到的?”

“听到一个词就往服务器里输入一个词,直到对方停嘴为止。然后再根据关键词的属性进行提问。比如‘你喜欢汉堡吗’。”

“也就是说,它并不需要听我把话说完?”

(略)……………………

“人们往往会在适当的时候搭腔,追问关键词以作确认,接着才开始说自己要说的。但巴德鲁不会有自己想要说的东西,所以一旦对话开始,它就会接连不断地追问下去。”

虽然文中的设定是使用在(2045年的二十年前)2025年发布的python5写的,但是我个人感觉可以使用当前的python3实现部分功能。

使用jieba分词的posseg词性分析来获取一句话中的重点词汇,比如动词,名词等。

然后用选择的重点词汇的词性使用已经设定好的一些句式发问。

import jieba
import random
import logging
import jieba.posseg as psg
#jieba库对的那个载入让人觉得有点烦躁用以下语句丢掉
jieba.setLogLevel(logging.INFO)
#用到的几个列表
##名词列表
global nounwordlist=[]
##形容词列表
global adjwordlist=[]
##动词列表
global verbwordlist=[]
##时间列表
global timewordlist=[]
#保存词和词性
class words:
    word=""
    flag=""
    def __init__(self,w,f):
        self.word=w
        self.flag=f
#随机抽取一个词
def randomselectfrom(wordlist):
    #print(wordlist)
    inde=random.randint(0,len(wordlist)-1)
    wordselect=wordlist[inde]
    del wordlist[inde]
    return wordselect
#对一个词进行回复的方式
def reply(words):
    if words.flag=='n':
        return (nounreply(words.word))
    elif words.flag=='a':
        return (adjreply(words.word))
    elif words.flag=='v':
        return (verbreply(words.word))
    elif words.flag=='t':
        return (timereply(words.word))
    else:
        return ("嗯,您说。")
#各种词回复
def nounreply(word):
    former=["可以聊聊关于「",
            "我对「"]
    latter=["」的事情吗?",
            "」有点兴趣,能说说看吗?"]
    sel=len(former)
    select=random.randint(0,sel-1)
    return (''+former[select]+word+latter[select])
def adjreply(word):
    former=["那个有点「",
            "有多「"]
    latter=["」呀,你觉得有什么优点吗",
            "」?"]
    sel=len(former)
    select=random.randint(0,sel-1)
    return (''+former[select]+word+latter[select])
def timereply(word):
    former=["「",
            "「"]
    latter=["」?还发生了什么吗?",
            "」啊,有什么别的事一起发生了吗?"]
    sel=len(former)
    select=random.randint(0,sel-1)
    return (''+former[select]+word+latter[select])
def verbreply(word):
    former=["为什么「",
            "「"]
    latter=["」?",
            "」的感觉你觉得怎么样?"]
    sel=len(former)
    select=random.randint(0,sel-1)
    return (''+former[select]+word+latter[select])

def main():
    buffer=input("说说看关于你的事情。")
    while(True):
        wordlistflag=list(psg.cut(buffer))
        print(wordlistflag)
        wordlist=[]
        for w,f in wordlistflag:#根据词性进行重新划分
            if f in("n",'i'):#普通名词,成语
                if (len(w)<1):
                    wordlist.append(words(w,'n'))
            if f in ("nr","nz","ns","nt","nw"):#专用名词,人名地名团体专名
                if (len(w)>1):
                    wordlist.append(words(w,'n'))
                    nounwordlist.append(words(w,'n'))
            if f in ("v","vd","vn"):#动词动名词
                if (len(w)>1):
                    wordlist.append(words(w,'v'))
                    verbwordlist.append(words(w,'v'))
            if f in ("t"):#时间
                if (len(w)>1):
                    wordlist.append(words(w,'t'))
                    timewordlist.append(words(w,'t'))
            if f in ("a","an","ad","d"):#形容词 形容副词
                if (len(w)>1):
                    wordlist.append(words(w,'a'))
                    timewordlist.append(words(w,'a'))
        #print(list(wordlist))
        if (len(nounwordlist)>=1):#特殊名词
            wordselect=randomselectfrom(nounwordlist)
        elif (len(verbwordlist)>=1):#verb
            wordselect=randomselectfrom(verbwordlist)
        elif (len(timewordlist)>=1):#time
            wordselect=randomselectfrom(timewordlist)
        elif (len(adjwordlist)>=1):#adj
            wordselect=randomselectfrom(adjwordlist)
        elif (len(wordlist)<=0):
            buffer=input("嗯,您说。")#或许还要一个开始问题的库
            continue
        else:
            wordselect=randomselectfrom(wordlist)
        while(True):
            buffer=input(reply(wordselect))
            if (len(buffer)>0):
                break
main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值