最近做企微二开,业务方要求客户在企微里说一句"帮我查下张三上个月的订单",系统能自动识别意图、抽出参数、调对应业务接口、把结果用自然语言回给客户。看起来就是接个大模型的事,做完发现从"自然语言"到"业务执行"中间隔着一整个解析层。把这套链路怎么搭记下来。

 Eyun 平台开放的企微 API,承接消息收发和客户管理,本文重点不在调接口,在"自然语言指令怎么变成结构化业务调用"。

不能直接让大模型生成 API 调用

最早想偷懒:把企微 API 文档塞进 prompt,让大模型直接输出要调的接口和参数。跑两天放弃:

  • 模型经常幻觉,编一个不存在的接口名或者瞎填参数

  • 客户消息里"张三"可能对应多个客户,模型不知道选哪个

  • 业务接口要的 appid、uin 这些上下文模型凑不齐

  • 出错没法定位,模型说"我建议调 sendText",但为什么调、参数哪来的全凭猜

正确做法是中间加一层"指令解析层":大模型只负责意图识别和参数抽取,真正调哪个接口、传什么参数由结构化的映射表决定。这种范式落地到企微,最终调的还是企微接口,能力清单可以看Eyun 开发文档,但企微场景还要做一层业务化封装。

意图识别:规则和模型双路

意图识别不要全靠大模型。规则路先走:关键词命中直接定意图,准、快、可解释。模型路兜底:规则没命中再让大模型分类。

def recognize_intent(message):
    # 规则路
    for rule in intent_rules:
        if rule.match(message):
            return rule.intent, rule.confidence
    
    # 模型路
    prompt = build_intent_prompt(message, candidate_intents)
    result = llm.classify(prompt)
    return result.intent, result.confidence

规则路的意图表是核心资产,覆盖高频场景(查订单、查客户、转人工、改标签)。模型路负责覆盖长尾,准确率低一些但能兜住规则没覆盖的表达。双路并存比单走模型稳得多。

槽位填充:从消息里抽参数

意图定了,下一步抽参数。"帮我查下张三上个月的订单"——要抽客户名"张三"、时间"上个月"。槽位定义和意图绑定:

intent: query_order
slots:
  - name: customer_name, type: string, required: true
  - name: time_range, type: time, required: false, default: "本月"
  - name: order_status, type: enum, required: false

槽位填充靠大模型抽取(这是模型擅长的事),但抽完要校验:必填的有没有、类型对不对、枚举值在不在范围内。"张三"抽出来要去客户库里反查,可能命中多个,要回问客户"您说的是哪个张三"。

参数校验:比抽取更重要

抽取完的参数不能直接用,要过校验:

  • 必填校验:缺了回问客户

  • 类型校验:时间要能解析成时间区间

  • 业务校验:客户名要能在客户库找到对应 uin

  • 权限校验:当前员工有没有查这个客户订单的权限

校验失败不能直接报错,要转化成自然语言追问。"张三"命中三个客户,回问"我找到三位张三:张三(上海)、张三(北京)、张三(深圳),您要查的是哪位"。

指令到 API 的映射表

意图和参数都齐了,调哪个企微 API、传什么参数,靠映射表:

intent_mapping 表:
  intent              query_order
  api_module          order
  api_action          queryList
  param_mapping       {"customer_uin": "$customer.uin", "start": "$time_range.start", "end": "$time_range.end"}
  response_template   "找到 {count} 笔订单,总金额 {total_amount} 元"

param_mapping 用占位符引用已校验的参数,引擎渲染后调接口。response_template 把 API 返回的结构化数据填回自然语言模板。

这一层是配置化的——加一个新意图不用改代码,加一行映射就行。这套做法和 RAG 检索后生成的思路类似,但这里检索的是业务接口的返回,不是文档片段。企微侧能拿到的客户数据,凭证和接入地址可以在企业微信 API 平台开通。

执行结果回写

API 调完返回结构化数据,要回写成自然语言给客户。两种方式:

  • 模板填充:固定模板填字段,简单可控

  • 模型生成:把结构化数据塞 prompt 让大模型组织语言,更自然但可能跑偏

高频意图用模板,长尾意图用模型。模板要预留失败兜底——API 返回空怎么办、超时怎么办、权限不足怎么解释,不能让客户看到原始报错。

意图识别失败:必须有兜底

模型路也可能识别不出来。兜底机制:

  • 置信度低于阈值:转人工,不硬猜

  • 多意图命中(歧义):回问客户澄清

  • 完全没命中:引导客户重新描述或转人工

不做兜底,模型自己编一个意图去执行,事故必然。之前在另一篇聊智能任务分发的文章里也提过类似思路——派不出去的任务要兜底,不能丢。回调事件本身怎么进来可以看开发文档

写在最后

自然语言到业务执行这条路,难点不在大模型多强,在意图识别的双路设计、槽位校验、映射表配置化、结果回写、失败兜底这些工程细节。每一项都不深奥,但少做一项系统就跑不稳。这套搭扎实,企微里的客户对话才能真正从"机器人回话"升级成"机器人办事"。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐