商業(yè)CRM系統(tǒng)的商機模塊業(yè)務(wù)復雜、場景繁多、規(guī)則調(diào)整頻繁,商機流轉(zhuǎn)效率一定程度決定了銷售開單的效率。如何高效配合產(chǎn)品側(cè)完成業(yè)務(wù)規(guī)則調(diào)整,商機流轉(zhuǎn)經(jīng)歷了硬編碼到半配置化的優(yōu)化升級,過程中遇到了一些問題,也總結(jié)了一些經(jīng)驗,今天來和大家掰開揉碎了講一講這其中遇到的問題和解決方案。
先看一下CRM的官方定義:
CRM(Customer Relationship Management):客戶關(guān)系管理,是指企業(yè)為提高核心競爭力,利用相應(yīng)的信息技術(shù)以及互聯(lián)網(wǎng)技術(shù)協(xié)調(diào)企業(yè)與顧客間在銷售、營銷和服務(wù)上的交互,從而提升其管理效率,向客戶提供創(chuàng)新式的個性化的客戶交互和服務(wù)的過程。
其最終目標是:吸引新客戶、保留老客戶以及將已有客戶轉(zhuǎn)為忠實客戶,增加市場。
可以這么簡單的理解,CRM的核心價值就是:將潛在客戶更高效的轉(zhuǎn)化為客戶,將客戶更高效的轉(zhuǎn)化為長期客戶。
圖片
介紹完什么是CRM,那CRM系統(tǒng)就很容易理解了,用于支撐企業(yè)進行客戶關(guān)系管理的系統(tǒng),就可以稱作CRM系統(tǒng)。這個定義比較寬泛,每個公司對CRM中功能邊界也不完全一樣,大家初步理解這個概念就行。比如轉(zhuǎn)轉(zhuǎn)商業(yè)CRM系統(tǒng),主要包含:商機管理、客戶管理、銷售/運營人員管理、業(yè)績管理、效率監(jiān)控等功能模塊。
要想把潛在客戶變成客戶,就需要銷售人員進行跟進,對潛在客戶進行產(chǎn)品的售賣,用戶購買產(chǎn)品后,變成客戶。這個潛在客戶,我們稱作“商機”,也就是一次成單的機會,有的CRM系統(tǒng)中,也稱為“線索”。
上圖是潛在用戶到客戶簡單的流轉(zhuǎn)圖
從商機生成到最終成單,銷售跟進過程中,涉及一些概念,比如商機池(公海池、私海池)、商機狀態(tài)/來源/類型/等級、商機的流轉(zhuǎn)等。
商機池:各種商機的集合。公海池:該集合里的商機當前不歸屬于任何銷售,所有銷售均可以看到公海里的商機。私海池:綁定了特定銷售的商機集合,比如銷售A的商機私海池,只有銷售A可以看到和跟進,其他銷售不可見、不可跟進。商機流轉(zhuǎn):商機在跟進過程中,被不同的銷售跟進,狀態(tài)發(fā)生不同的變化。流轉(zhuǎn)規(guī)則:流轉(zhuǎn)過程中會有各種各樣的業(yè)務(wù)規(guī)則限制,比如銷售最多可以認領(lǐng)100條商機、負責手機類目的銷售不能認領(lǐng)電腦類目的商機、銷售剛放棄的商機不能立馬重新認領(lǐng)、單位時間內(nèi)不進行電話溝通的商機將流出銷售私海等等。
這里舉一個例子來說明商機的流轉(zhuǎn),業(yè)務(wù)背景:商機對應(yīng)用戶主營類目為手機,銷售A、B負責手機類目,銷售C負責電腦類目,銷售D也負責手機類目。
圖片
這是一個簡單的流程,實際流程比這個復雜。從這個簡易的流程介紹中,可以窺見部分商機流轉(zhuǎn)模塊的業(yè)務(wù)特點,總結(jié)起來有三點:
圖片
圖片
圖片
之前商業(yè)CRM中關(guān)于流轉(zhuǎn)的處理邏輯,好多都是硬編碼,舉個銷售認領(lǐng)某條商機的例子:
//狀態(tài)校驗if(checkClueStatus(param)){ return “狀態(tài)不合法”;}//綁定人校驗if(checkClueBindUser(param)){ return “上一個綁定人不可以為···”;}//私海容量校驗if(checkPrivateClueCount(param)){ return “私海庫已滿,無法操作··”;}//類目校驗if(checkClueCate(param)){ return “類目不匹配,無法操作··”;}//任務(wù)是否完成校驗if(checkClueTaskFinished(param)){ return “任務(wù)未完成,無法操作··”;} ······bind(param);//綁定操作log();//日志記錄操作
從代碼中可以看出,銷售從公海進行認領(lǐng)一條自己覺得有價值的商機時,并不是直接就讓該商機流入到該銷售私海中,這個過程會有各種規(guī)則的業(yè)務(wù)校驗。
帶著我們的痛點和訴求,接下來看看可以找到什么樣的解決方案。然后我們進入了調(diào)研階段,發(fā)現(xiàn)對于這種策略比較密集的業(yè)務(wù),規(guī)則引擎是一個可參考方向,然后就開始了解規(guī)則引擎相關(guān)細節(jié),了解完后,發(fā)現(xiàn)和業(yè)務(wù)問題匹配度很高。接下來,先介紹一下規(guī)則引擎相關(guān)的基本知識。
規(guī)則就是:條件 --> 推理 --> 結(jié)果。一個完整的規(guī)則是需要這三部分元素的,平時大家討論規(guī)則,某些時候只是在討論第一部分的條件,比如學校的行為規(guī)范,咱們國家的各種法律條文,可能關(guān)注的部分是需要滿足什么條件(不能做什么什么),后面的推理和結(jié)果省去了。比如學生準則里的不辱罵同學,這是一個條件,那怎么算辱罵呢,這是推理過程,辱罵后會發(fā)生什么呢,會受到老師批評,這是結(jié)果。
那什么是推理引擎和規(guī)則引擎呢?
圖片
推理引擎通過決定哪些規(guī)則滿足事實或目標,并授予規(guī)則優(yōu)先級,滿足事實或目標的規(guī)則被加入議程,具體過程:
推理方式分為正向推理和反向推理
常見的模式匹配算法有Rete,LFA,TREAI,LEAPS。Rete算法是目前效率最高的一個演繹法推理算法,許多規(guī)則引擎都是基于Rete算法來進行推理計算的。
圖片
這是Rete算法的原理圖,Rete算法涉及兩種網(wǎng)絡(luò)和6種不同作用的節(jié)點。
圖片
a) 檢查模式1中的參數(shù)類型,如果是新類型,添加一個類型節(jié)點。
b) 檢查模式1對應(yīng)的Alpha節(jié)點是否存在,如果存在記錄下節(jié)點的位置;如果沒有,將模式1作為一個Alpha節(jié)點加入到網(wǎng)絡(luò)中。同時根據(jù)Alpha節(jié)點建立Alpah內(nèi)存表。
c) 重復b,直到處理完所有模式。
d) 組合Beta節(jié)點:Beta(2)左輸入節(jié)點為Alpha(1),右輸入節(jié)點為Alpha(2);Beta(i)左輸入節(jié)點是Beta(i-1),右輸入節(jié)點為Alpha(i),并將兩個父節(jié)點的內(nèi)存表內(nèi)聯(lián)成為自己的內(nèi)存表。
e) 重復d,直到所有Beta節(jié)點處理完畢。
f) 將動作Then部分封裝成最后節(jié)點做為Beta(n)。
圖片
上面介紹的這些都偏理論化,可能有一點不太容易理解,沒關(guān)系,接下來咱們用一個具體的例子,看看Rete算法到底是如何運行的。咱們依然以這個選拔籃球苗子的例子來說明。
圖片
圖片
A節(jié)點:拿StudentFact的年級數(shù)值進行年級匹配,如果年級符合條件,則把該StudentFact的引用記錄到A節(jié)點的alpha內(nèi)存區(qū)中,退出年級匹配。
B節(jié)點:拿StudentFact的性別內(nèi)容進行性別匹配,如果性別符合條件,則把該StudentFact的引用記錄到B節(jié)點的alpha內(nèi)存區(qū)中,然后找到B節(jié)點左引用的Beta節(jié)點,也就是C節(jié)點。
C節(jié)點:C節(jié)點找到自己的左引用也就是A節(jié)點,看看A節(jié)點的alpha內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級和性別兩個條件都符合,則在C節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出性別匹配。
D節(jié)點:拿StudentFact的年齡數(shù)值進行年齡條件匹配,如果年齡符合條件,則把該StudentFact的引用記錄到D節(jié)點的alpha的內(nèi)存區(qū)中,然后找到D節(jié)點的左引用的Beta節(jié)點,也就是E節(jié)點。
E節(jié)點:E節(jié)點找到自己的左引用也就是C節(jié)點,看看C節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級,性別,年齡三個條件符合,則在E節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出年齡匹配。
F節(jié)點:拿StudentFact的身體數(shù)值進行身體條件匹配,如果身體條件符合,則把該StudentFact的引用記錄到D節(jié)點的alpha的內(nèi)存區(qū)中,然后找到F節(jié)點的左引用的Beta節(jié)點,也就是G節(jié)點。
G節(jié)點:G節(jié)點找到自己的左引用也就是E節(jié)點,看看E節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放,說明年級,性別,年齡,身體四個條件符合,則在G節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact的引用,退出身體匹配。
H節(jié)點:拿StudentFact的身高數(shù)值進行身高條件匹配,如果身高條件符合,則把該StudentFact的引用記錄到H節(jié)點的alpha的內(nèi)存區(qū)中,然后找到H節(jié)點的左引用的Beta節(jié)點,也就是I節(jié)點。
I節(jié)點:I節(jié)點找到自己的左引用也就是G節(jié)點,看看G節(jié)點的Beta內(nèi)存區(qū)中是否存放了StudentFact的引用,如果存放了,說明年級,性別,年齡,身體,身高五個條件都符合,則在I節(jié)點的Beta內(nèi)存區(qū)中存放StudentFact引用。同時說明該StudentFact對象匹配了該規(guī)則,形成一個議程,加入到?jīng)_突區(qū),執(zhí)行該條件的結(jié)果部分:該學生是一個籃球苗子。
規(guī)則的條件與facts的數(shù)目如果過大,對應(yīng)memory會指數(shù)級升高,極端情況下會耗盡系統(tǒng)資源。
看完這個匹配的過程,相信大家對規(guī)則引擎中常用的Rete算法有了一定的了解。回到規(guī)則引擎,那為啥用規(guī)則引擎呢,也就是它有何優(yōu)勢,以及有哪些適用的場景呢?
一般多用于規(guī)則較多且規(guī)則調(diào)整頻繁的業(yè)務(wù)場景,比如:積分規(guī)則、計費系統(tǒng)、信用風險評估、監(jiān)控告警、工作流系統(tǒng)。
網(wǎng)上有兩種分類方式,這里我列舉出來,供大家了解。
圖片
了解了上面這些業(yè)務(wù)背景以及遇到的問題,也熟悉了規(guī)則引擎的理論知識,現(xiàn)在需要制定具體的解決方案了,我們怎么做的呢?市面有各種各樣的規(guī)則引擎,先進行技術(shù)選型,這里列舉下當前主流規(guī)則引擎優(yōu)缺點。
圖片
通過各方面綜合評估,重點放到了Drools和easyRule兩者,且easyRule最終勝出。
圖片
確定了要使用easyRule就得知道easyRule如何使用的,先介紹下其相關(guān)概念和使用方法。
Easy Rules提供了3種CompositeRule的實現(xiàn)。
值越低優(yōu)先級越高。要覆蓋此行為,可重寫compareTo()方法以提供自定義優(yōu)先級策略。
支持自定義規(guī)則監(jiān)聽器、規(guī)則引擎監(jiān)聽器。
支持MVEL、SPEL表達式語言,可通過編程方式定義規(guī)則。
還是用篩選籃球苗子的例子
圖片
public class Student { /** * 年級 */ private Integer grade; /** * 性別 */ private String gender; /** * 年齡 */ private Integer age; /** * 是否強壯 */ private Boolean isStrong; /** * 身高 */ private Integer height; /** * 是否一個好苗子 */ private Boolean isGoodSeed = true;}
//創(chuàng)建規(guī)則1-年級Rule rule1 = new MVELRule() .name("grade rule") .description("判斷一個學生是否是一個籃球好苗子-年級") .priority(1) .when("student.getGrade() <= 3") .then("System.out.println(/"年級-不是好苗子/");") .then("student.setIsGoodSeed(false);");
//創(chuàng)建規(guī)則2-性別Rule rule2 = new MVELRuleFactory(new YamlRuleDefinitionReader()). createRule(new FileReader( ResourceUtils.getFile("classpath:gender-rule.yml")));
規(guī)則2需要的yml文件內(nèi)容如下:
name: "gender rule"description: "判斷一個學生是否是一個籃球好苗子-性別"priority: 2condition: "student.getGender().equals(/"girl/")"actions: - "System.out.println(/"性別-不是好苗子/");student.setIsGoodSeed(false);"
//創(chuàng)建規(guī)則3-年齡 Rule rule3 = new MVELRuleFactory(new JsonRuleDefinitionReader()). createRule(new FileReader( ResourceUtils.getFile("classpath:age-rule.json")));
//創(chuàng)建規(guī)則4-是否強壯Condition condition = new MVELCondition("!student.getIsStrong()");Action action = new Action() { @Override public void execute(Facts facts) throws Exception { Student student1 = (Student) facts.get("student"); student1.setIsGoodSeed(false); System.out.println("強壯-不是好苗子"); }};Rule rule4 = new RuleBuilder() .name("strong rule") .description("判斷一個學生是否是一個籃球好苗子-是否強壯") .priority(4) .when(condition) .then(action).build();
@Rule(name = "height rule" ,description = "判斷一個學生是否是一個籃球好苗子-身高")public class HeightRule { @Condition public boolean checkHeight(){ return student.getHeight() <= 170;} @Action public void action(){ System.out.println("身高-不是好苗子"); student.setIsGoodSeed(false); } private Student student; public HeightRule(Student student){ this.student = student; }}//創(chuàng)建規(guī)則5-身高HeightRule rule5 = new HeightRule(student);
//創(chuàng)建一個Student實例(Fact) Student student = new Student(3,"girl",9,true, 160,true); Facts facts = new Facts(); facts.put("student", student);
//注冊規(guī)則Rules rules = new Rules();rules.register(rule1);rules.register(rule2);//rules.register(rule3);rules.register(rule4);rules.register(rule5);//創(chuàng)建規(guī)則執(zhí)行引擎,并執(zhí)行規(guī)則RulesEngine rulesEngine = new DefaultRulesEngine();System.out.println("開始判斷是否是一個籃球苗子:" + JSON.toJSONString(student));rulesEngine.fire(rules, facts);System.out.println("是否為好苗子:" + student.getIsGoodSeed());
圖片
熟悉了easyRule如何使用的,接下來看看我們?nèi)绾卧陧椖恐新涞氐模覀兎至藥撞剑?span style="display:none">XIB28資訊網(wǎng)——每日最新資訊28at.com
初始化規(guī)則相關(guān)配置(首次初始化+定時更新);
提供對外public T fire(String ruleId, V v)通用的規(guī)則引擎api接口。
圖片
這里我們將規(guī)則引擎的處理結(jié)果進行了返回,因為業(yè)務(wù)上很多場景需要,比如不符合規(guī)則時的提醒文案。
項目中配置規(guī)則引擎相關(guān)配置;
實例化RuleEngineTemplate類;
根據(jù)場景,組裝上下文context;
調(diào)用ruleEngineTemplate.fire(ruleId,context)方法。
圖片
引入后,我們的商機流轉(zhuǎn)流程發(fā)生了如下變化:
圖片
圖片
spring: easy-rule: priority-threshold: 100 skip-on-first-failed-rule: false skip-on-first-applied-rule: true skip-on-first-non-triggered-rule: false rules: - rule-id: "opportunity_unbind" rule-file-location: "opportunity_unbind" #規(guī)則配置文件 rule-config-type: JSON rule-factory-type: SPEL
具體的規(guī)則配置json
[ { "name": "bind_check_cate", "description": "判斷是否凍結(jié)-72小時", "condition": "@opportunityUnbindRuleBll.checkOpportunityNeedFreeze(#context.getOpportunityId(), n,m)", "priority": 4, "actions": [ "@clueOpporBll.unbindOpportunity(#context,T(OpportunityStatusEnum).UNBIND, T(com.clue.enums.OpportunityMinorStatusEnum).UNBIND_FROZEN)" ] }, { "name": "task_bind_out", "description": "任務(wù)商機流回公海", "condition": "#context.getOpportunityStatus() == T(com.enums.OpportunityStatusEnum).TASK && #context.getOperationTypeEnum() == T(com.OpportunityOperationTypeEnum).TASK_BACK_PUBLIC", "priority": 5, "actions": [ "@clueBll.unbindOpportunity(#context,T(com.zhuanzhuan.biz.clue.enums.OpportunityStatusEnum).UNBIND, T(com.OpportunityMinorStatusEnum).UNBIND_NORMAL)" ] }, { "name": "unbind_operate", "description": "判斷解綁后去向,現(xiàn)階段全部回到公海", "condition": "true", "priority": 10, "actions": [ "@clueOpportunityBll.unbindOpportunity(#context,T(com.OpportunityStatusEnum).UNBIND, T(com.enums.OpportunityMinorStatusEnum).UNBIND_NORMAL)" ] } ] }]
public Result<ParallelExecuteDTO> unbindOpportunity(UnbindOpportunityRequest request) { return parallelExecutor.parallelExecute(request.getOpportunityIds(), (Long opportunityId) -> { final Result<String> unbindResult = opportunityUnbindRuleBll.unbindOpportunity(opportunityId, request.getOperator(), request.getReasonType(), request.getReasonDesc(), request.getOperationType()); logger.info("method=unbindOpportunity, act=unbind, opportunityId={},unbindResult={}", opportunityId, unbindResult); return unbindResult; } ); }
圖片
在easyRule引入商機流轉(zhuǎn)業(yè)務(wù)過程中,從調(diào)研到選型再到最終落地,遇到了各種大大小小的問題,但最終的效果還是比較明顯的,對團隊的整體效率提升非常明顯,這里有幾點總結(jié)與建議與大家分享。
楊迎,轉(zhuǎn)轉(zhuǎn)商業(yè)后端開發(fā)工程師,目前負責商業(yè)B端相關(guān)業(yè)務(wù)系統(tǒng)開發(fā)(商機線索、客戶運營、銷售運營管理、廣告發(fā)布等)。
本文鏈接:http://www.tebozhan.com/showinfo-26-16530-0.html規(guī)則引擎與商業(yè)CRM的完美邂逅:將智能決策融入商業(yè)擴展
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com