基于企业微信 SDK Java + Dify 搭建企微客户群自动回复机器人
Dify 把知识库、编排、模型管理都做完了,Java 团队真正要写的只有两段胶水:把群消息喂给它,把回答送回群里。之前写过 Python 对接 Dify 做客服的思路,这篇换成 Java,重点讲最容易漏的一环——会话记忆。
整体链路
一条链说清:群消息 → 企微 Webhook 推到 Java 服务 → Java 组装请求调 Dify 的对话接口 → 拿到回答 → sendText 发回群。企微侧的客户端封装(token 管理、int64 处理)之前单独写过,直接复用那个 WecomClient,这篇不重复。
关键一环:conversation_id 就是群的记忆
Dify 的对话接口是无状态的——你不传会话 ID,它每次都当新对话处理,上一句问了什么完全不知道。群机器人的记忆全靠你自己维护 conversation_id:同一个群固定传同一个 ID,Dify 就会自动带上这个群的对话历史。
public String chatWithDify(String roomKey, String query) throws Exception {
String conversationId = redis.get("dify:conv:" + roomKey); // 群ID → 会话ID
ObjectNode body = mapper.createObjectNode();
body.put("inputs", mapper.createObjectNode());
body.put("query", query);
body.put("user", roomKey); // 用户标识用群标识
if (conversationId != null) {
body.put("conversation_id", conversationId);
}
Request req = new Request.Builder()
.url(DIFY_URL + "/v1/chat-messages")
.header("Authorization", "Bearer " + DIFY_API_KEY)
.post(RequestBody.create(mapper.writeValueAsBytes(body),
MediaType.parse("application/json")))
.build();
JsonNode resp = mapper.readTree(http.newCall(req).execute().body().string());
// 首次对话:把 Dify 分配的会话 ID 存回去,下次这个群就有了记忆
redis.setex("dify:conv:" + roomKey, 86400 * 3,
resp.get("conversation_id").asText());
return resp.get("answer").asText();
}
三个工程细节:user 字段固定传群标识,别乱换;会话 ID 给个过期时间(比如三天),过期自动开新会话,避免上下文越滚越长;readTimeout 要拉长到 60 秒,LLM 生成慢,OkHttp 默认 10 秒会直接超时报错——这是 Java 接 LLM 服务最常见的翻车点。
命中知识库才回,没命中就转人工
Dify 挂了知识库之后,返回体里有引用来源字段(retriever_resources)。这是防机器人瞎编的关键开关:
JsonNode resources = resp.path("metadata").path("retriever_resources");
if (!resources.isArray() || resources.isEmpty()) {
sendTextToRoom(roomId, "这个问题我需要人工确认,已通知客服同学,稍后回复您~");
notifyHuman(roomId, query); // 丢给人工队列
return;
}
sendTextToRoom(roomId, answer); // 命中知识库,正常回答
知识库里没有的内容就别让模型自由发挥——客户群里一句编错的答案,比十句"稍后回复您"伤害都大。
群触发过滤:Java 侧一行判断
老规矩,群里不能每条都回。Webhook 收到消息先过滤:只处理被 @ 机器人或带指定前缀的消息,其余直接返回 200 忽略。判断逻辑一行:
if (!msg.path("content").asText().startsWith("问") ) return;
过滤放在验签之后、调 Dify 之前,无效流量根本不该碰到 LLM。
上线前过一遍的清单
| 检查项 | 标准 |
|---|---|
| 会话隔离 | 每个群独立 conversation_id,互不串台 |
| 超时配置 | Dify 调用 readTimeout ≥ 60s |
| 命中策略 | 无知识库命中走人工兜底 |
| 幂等 | Webhook 重推按投递 ID 去重 |
| 回复长度 | 超长分段发(企微没有消息编辑接口) |
Dify 侧的应用编排、知识库上传是在它的控制台配的,企微侧的 Webhook 配置和接口字段在 Eyun 开发文档里查,实例凭证在Eyun 官网开通后即可调试。
这套架构的好处是各管一段:Dify 管"怎么答",Java 管"收和发",知识库更新在 Dify 后台点几下就生效——Java 代码一行不用动。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)