[微信机器人_05]会话管理

时间:2014-02-24 16:52:57   收藏:0   阅读:519

上一篇已经说明了自然语言处理的简单实现方法,在此基础上,如何实现一个机器人与我们交流,是这篇文章需要讨论的问题。希望这个机器人不算太笨。^_^


微信的交互方式是触发式的,由用户发起会话,一问一答。所有的设计都需要基于这个模式。

 

会话管理机制

想想平时交流时的行为,我们会根据对方的每句话来逐渐建立起一个语境,即对话上下文。根据不同的语境,即使是同一个问题,也会有不同的答案。

基于这个想法,设计一个简单的会话管理机制,即每个用户有一个独立的对话上下文context,每个context会有一个状态来标志当前的语境。

1、会话状态管理

public enumContextStateEnum {

         WAIT_QUERY,                    //等待询问

         WAIT_LEARN,                    //等待学习

         WAIT_CONFIRM,               //等待确认

         WAIT_WEATHER_CITY,  //等待指定需要查询天气的城市

         WAIT_MUSIC_INFO;        //等待指定需要搜索的歌曲信息

}


2、创建与删除会话

bubuko.com,布布扣


3、会话处理流程

有了这个基本思路,再来看看每个会话的处理流程。

我将用户的问题分为两类,非功能性问题和功能性问题:

  1. 非功能性:这类问题的答案由用户调教获得,存储在知识库中,查询本地数据库即可回答,用户可通过调教修改问题答案。
  2. 功能性:这类问题的答案通过访问外部API获得,比如查询天气,搜索音乐。Context状态中,WAIT_WEATHER_CITY, WAIT_MUSIC_INFO两个状态属于功能性问题的状态。

 Context的状态切换如下图:

bubuko.com,布布扣

                                bubuko.com,布布扣


Context模块与其他模块的关系

 

一些扩展的设想

当前的实现比较简单,如果继续扩展,可以加入一个解析模块。解析模块负责分析会话中的聊天记录,context模块根据分析结果切换会话状态,比如机器人可以有开心、愤怒、悲伤等状态,在不同的状态下,即使是同一个问题机器人也可以选择不同的回复。当然,这需要把知识库中的答案进行归类,机器人才能根据状态选择对应的答案。


实现过程中碰到的问题

问题:分布式服务器导致机器人状态机混乱

最初设计context保存在内存中,定义一个map容器,以用户ID作为key,context结构体作为value。

本地运行没有问题,但是发布到BAE服务器后,问题来了,通过微信与奇迹蛋robot对话,发现奇迹蛋的context状态机混乱,行为非预期。并且问题发生具有一定的随机性。

开始一直以为是多线程操作map引起的问题,在程序中又加了单例,满怀期待的发布了,结果还是不行。

折腾了挺久,最后在网上找到了一个比较靠谱的解释,参考:http://blog.csdn.net/ostrichmyself/article/details/8098119,“3.1 静态变量无法常驻内存”。

简单来说,由于BAE是分布式服务器,我们部署在上面的web应用会被放在多个容器里执行,而这些容器的内存是非共享的,如下图:

bubuko.com,布布扣

弄清楚了原因就好办了,有两种解决方法:

1. 使用BAE的cache服务,创建共享内存

    研究了一下,要调用BAE的API,本地调试不方便,加上BAE的文档看的蛋疼,放弃了。

2. 使用数据库来保存

    放弃使用内存的方式,用mysql来保存context map。尽管增加了数据库操作,不过用户也没几个,无所谓了。

 

奇迹蛋的主要设计思路基本就介绍完了,整个系统比较简单,有些功能设计了但是没有去实现。主要目的还是学习一下java web的开发方法,也顺便了解了解时下最火的微信APP。

Have fun~

 

下篇文章会聊一些代码实现中碰到的问题,并符上源码。


谢谢关注奇迹蛋~扫一下&调戏之

bubuko.com,布布扣

原文:http://blog.csdn.net/elcarim/article/details/19765627

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!