/chatbot

framework to build chatbot which could handle complex multi-turn conversation by engineering, like build website or app

Primary LanguagePHPMIT LicenseMIT

Commune 项目介绍

"Commune" 有亲切交谈的意思,CommuneChatbot 项目旨在提供一个对话机器人的开源开发框架。

本项目是作者本人对于 对话交互 技术领域的个人探索,2019年完成了 v0.1 版本,2020年仍在探索 v0.2版本。

由于作者犯了一些策略上的错误, v0.2 版短期内无法完成开源

简单来说,一个可推广的开源项目应该上手简单,文档清晰,有明确的应用方向,然后是高质量和持续维护。

但由于作者的策略错误(也和 covid-19 疫情有关),用完了开发时间,却没有达到以上标准。

0.2 距离理想状态还差:

  • 完整的文档
  • 开箱即用,有价值的应用
  • 生产级可用的组
  • 管理后台

接下来的计划是:

  • 优先完成技术思路的相关文档
  • 作为个人项目,开发一些实际可用的应用
  • 将 0.2 版核心模块拆分成独立项目,降低开源成本

您也可以把这个项目当成对话系统的一种探索思路来看待。 如有兴趣,也可以加入讨论 QQ 群 (907985715) 交流。

本文后半部分会介绍作者的开发历程和现阶段的反思,与您分享。

Commune 项目定位

对话机器人目前有两种主流的应用方向,对话交流(闲聊,问答,陪伴等) 与 对话式控制 (任务,智能家居,车载对话OS,chatops,声控等)。

Commune 项目本意是实现一个通用的对话机器人框架,而偏重于 多轮对话管理

目前多轮对话管理有偏算法和偏工程两条道路,在对话式控制的场景中(低资源、冷启动、对话轮次较深),目前行业多见偏工程的做法。

Commune 是基于类似工作流的方案,用工程手段实现对话管理。目的在于解决 复杂多轮对话非阻塞对话对话任务调度对话式编程跨设备对话机器人 等问题。

对标的项目是 botkithubotbotman 等。

Commune 项目现状

2019 年初步完成了 v0.1 版本,相关 Demo 地址在:

2020 年 9月初步完成了 v0.2 的 Demo,相关 Demo 地址在:

v0.2 版核心功能均已实现,但已没有条件推进到开源可用的地步。目前最接近 Ready 的领域:

  • 钉钉机器人的对接 (outgoing + webhook)
  • ChatOps 基础功能 (命令行/异步任务)
  • 基于 Markdown 的文档库,反射成多轮对话 + 问答

这几个功能接下来会优先推进。

作者开发经历分享

写于 2020-11-26

为何要开发对话机器人项目?

简单来说,作者对对话式交互有浓厚的兴趣,并有一系列对话式产品的设想,认为对话交互的优势在于:

  • 走向语音交互,解放双手 (hands free),解放双眼 (eyes free),从而解放生产力
  • 相比复杂应用的图形界面,可实现 意图直达
  • 交互比触屏更贴近人的直观想象,使用成本更低
  • 一套应用开发,可适用于各种 IM 和语音控制设备
  • 未来所有的智能应用,都会有对话式交互的界面

关于产品的部分设想:

  • 对话式 wiki: 在对话中完成知识的 输入/编辑/查询 等,结合图形界面来展示
  • IM OS: 在 IM 里完成运维,办公,购物,应用等各种任务
  • 语音控制: 通过语音控制图形界面,物联网硬件,智能设备等
  • 场景控制: 为 在线课堂/车内/家居/商场门店 等综合场景提供统一的对话式控制
  • 机器人 IM平台: 由对话机器人作为联系人的 IM,每个机器人都是一个独立应用

作者最希望实现的是 对话式 wiki,在 2015年 ~ 2018年的个人探索中,发现现有的各种技术和框架无法实现产品需求, 主要是无法解决 复杂多轮对话 问题。

按作者个人理解,对话交互 本质上和其它各种常见交互 (仪表盘/桌面应用/ 触屏应用) 一样,都需要解决 交互 面临的 状态管理/任务调度 等问题。 由于对话交互的产品现阶段还不成熟,导致这个领域的技术实现还未被行业重视,所以没有趁手的工具。

作者在 2017 ~ 2018年在任职公司参与了三版对话机器人的开发,对此积累了许多技术上的思路,于是从 2019年着手独自开发 Commune 项目。

由于我设想的产品功能较为复杂,几乎不可能独立开发完成。因此想加入对话交互系统的开发团队来推进想法。

在 2019 年完成 Commune v0.1 版之后,一度得到了某公司对话系统团队的认可,约定年后入职。但在入职之前遭遇了 covid-19 疫情,对方单位收缩,取消了 HC。

在 19 年与该单位面试交流时,我提出了一些更激进的工业场景解决方案,包括 "跨设备机器人" "非阻塞对话" "多任务调度" "对话式编程" 等。 而在疫情期间进退两难的情况下,选择坚持独自实现了这些技术方案,于是有了 Commune v0.2版的 Demo

目前的开发遭遇的困难

而现阶段作者遇到的困难是:

  • 个人经济条件,不允许再脱产来完善项目
  • covid-19 疫情期间的独立开发让人极为疲惫,动力不足
  • v0.2 版架构过大,一个人已无法在短期内完善到开源可用
  • 因为种种原因,无法进入到对话系统的业内
  • 个人并没有一个短期内能落地的,能挣钱的对话应用业务
  • 认识到了自己能力不足的地方

所有原因归纳起来,是因为我视野、能力和经验均有不足,导致花了很多心血所做的探索,没能力使之立刻转化成对社区的价值。

所以我现在的想法是:

  • 回到与实际业务紧密结合的工作中,重新提高自己技术能力与视野
  • 将 v0.2 的各种技术成果拆散,应用到实际场景中
  • 坦诚总结经验教训,与朋友们分享

开发策略错误的总结与分享

1. 技术方案错误地超前于行业需求

Commune 在对话系统中探索的方案,如 复杂多轮对话/非阻塞对话/多任务调度/对话式编程/跨设备机器人 等,作者仍认为是对话交互技术未来必然要解决的问题。

不过有大佬说得好,你做了一个新技术,不一定是你厉害,多半是行业还不屑于做。 当对话系统的工业界需求推进到这一步时,相信有工程师作出更成熟的解决方案。

而现阶段对话式产品普遍交互轮次较浅,更谈不上 非阻塞/多任务 了。

由于我不在行业内,不拥有业务,这些略超前的探索无法与具体产品形态结合,也无法推动行业发展。

除非基于这些功能,开创出一种远超行业现状的新产品,来自我证明;但目前没有条件,缺乏信心和决心。

对于开源项目而言,这些技术方案又引入了更多不同于主流方案、令开发者费解的新概念,反而增大了推广成本。

2. 技术探索优先于产品

开发 Commune 项目前后有数十万行代码,但重点都放在技术方案的实现上,只有不到 1/10 的精力用于产品,且都停留在 Demo 阶段。

一个不够酷的 Demo 无法让用户立刻明白项目的长处。

而一些有用的产品方向,如 markdown 文档转多轮对话/问卷调查/问答/对话式游戏/chatops 等,目前没有一个推进到 开箱即用 的水平。

这使得现阶段推广这个项目缺乏明确应用场景。

3. 过早推行生产级方案

Commune 项目代码中一直考虑生产级可用,许多环节针对生产级场景的需要,做了解决方案。

例如项目需要大量读取对话逻辑的配置,考虑到分布式系统 配置存取一致性/存储介质差异,设计了 OptionRegistry 的方案, 可以从设置好的任意存储介质 (Mysql/file/redis 等) 中读取配置。

且不论给出的方案不一定是最佳实践,这要求使用本项目要学会开发和注册 Option Storage,对于一个开源项目而言反而增加了使用成本。

为了降低用户的成本,作者又得开发大量的默认配置方案,又增加了维护成本。

4. 架构设计过大

Commune 项目核心技术是 "复杂多轮对话管理",但项目本身试图实现一个全栈式的对话机器人框架。设计之初,作者一直按一个开发团队的思路去规划功能。

因此框架 3/5 的内容都是 IoC 容器/服务注册/协议匹配/配置存储/服务间通讯/跨设备/消息多模态渲染 等,战线越来越多。

这对一个工业级框架而言是必要的,但作为个人项目,它不仅意味着开发成本、还意味着线性增加的维护成本。倒过来导致许多个环节都未做到生产级可用。

例如:

  • 目前 Shell层与 Ghost层的通讯使用的仍是 Tcp \r\n 分包
  • 广播总线仍使用 Redis 的 pub/sub,没解决消息送达的问题
  • 数据库连接池的异常容错不完善

尽管基于 IoC 容器都设计了抽象,仍需要开发团队自己在生产环境中完善之。 这对于开源项目反而是负面的。

5. 技术栈脱离行业主流生态

Commune 项目的方案是完全用面向对象的 Interface 先设计完成的。

而项目本身是 PHP + Swoole + Hyperf 的一个实现。

作者认为由于 PHP 的几个优点:

  • 优秀的高级语言动态性
  • 弱类型与强类型约束兼备
  • 面向对象与匿名函数兼有

使 PHP 非常适合实现 Commune 的设计。

尽管如此,在我接触对话机器人相关企业时,面临的现状是绝大多数公司都在使用 Java。 Java 在工业级架构里的生态,的确比现阶段 PHP + Swoole 要成熟。

这使得作者用 PHP 实现的解决方案,对于这些公司而言风险过高,缺乏说服力。 已经有多位朋友提出希望用 Java 重构项目的内核。 这也是令人尴尬的现实。

6. 个人的技术瓶颈

设计 Commune 项目时,许多功能组件考虑到了工业级的需求,设计成了 Interface。 但作者自身的技术栈不够完整,许多环节无法给出工业级的实现。

例如 NLU (自然语言理解单元) 部分,由于需要一个可动态添加语料的 NLU,作者找不到成熟项目替代的情况下,只能临时用 SpaCy 做了一个 单点的 NLU 项目

另外接触一些对话系统的公司时,由于在起步阶段,都希望加入的是一个拥有全方位解决方案的总工角色。 而作者本人的技术能力与工作经历,还达不到工业级项目总工的水平。 而自己对话系统的解决方案,又与行业主流的方案有较大差别。

小结

综合以上分析,作者认为自己最大的错误在于没有认清 个人开源项目 的定位。 导致:

  • 对于 "项目",应用场景和价值不够明确
  • 对于 "个人",开发工作量过大
  • 对于 "开源",完成度不够高

其结果是既不利于开源推广,也难以立刻得到行业认可,而自己也没有独立的业务可以去推进。 倒过来无人参与,更难独自开发。

这个经验教训供您参考。

Commune 项目接下来的计划

  1. 暂时不把精力用在完善开源上
  2. 优先完成技术方案的介绍文档
  3. 用业余时间推进 钉钉/chatops 等功能
  4. 作为个人项目,开发小的、有价值的应用
  5. 将核心功能 (例如对话管理内核 Ghost)独立拆分,降低开源成本

对此若有任何批评与建议,欢迎您留言。