尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

WeKnora IM 集成完全指南:把 RAG 智能体接入企业微信、飞书、Slack 等 10 个聊天平台

WeKnora IM 集成完全指南:把 RAG 智能体接入企业微信、飞书、Slack 等 10 个聊天平台 WeKnora IM 集成完全指南把 RAG 智能体接入企业微信、飞书、Slack 等 10 个聊天平台【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnoraIM 集成是 WeKnora 将知识库问答与 Agent 能力延伸到即时通讯场景的核心模块通过「设置 → IM 集成」新建渠道把某个平台机器人绑定到一个自定义智能体用户即可在聊天窗口中直接提问由 WeKnora 执行检索RAG或 Agent 推理后回复。本文以 website-docs/03-features/12-im-integration.md 为主线结合 internal/im 的源码实现系统讲解平台接入模式、内置命令、群聊/私聊行为、文件消息、回复图片外链、MCP OAuth 授权通知以及多实例部署下的 Redis 协调机制帮助读者完成渠道配置、排障与二次开发。支持的平台与能力对比internal/handler/im.go中validIMPlatforms定义了 10 个合法平台wecom、feishu、lark、slack、telegram、dingtalk、mattermost、wechat、qqbot、yunzhijia。非法平台会被拒绝错误信息由invalidIMPlatformError自动从该集合生成两者不会漂移。各平台能力以各factory.go与 adapter 的编译期断言为准平台接入模式默认加粗流式回复 StreamSender文件下载 FileDownloader线程/话题 ThreadID主要凭据字段credentials JSON企业微信wecomwebsocket智能机器人长连接/ webhook自建应用回调仅 websocket 模式两种模式均支持否websocketbot_id、bot_secret、ws_endpoint、bot_namewebhookcorp_id、agent_secret、token、encoding_aes_key、corp_agent_id、api_base_url飞书feishuwebsocket长连接事件流/ webhook是流式卡片是是root_id顶层消息用自身message_idapp_id、app_secret、verification_token、encrypt_keyLarklark同飞书同一适配器RegionLark指向 open.larksuite.com是是是同飞书SlackslackwebsocketSocket Mode/ webhookEvents API是是是thread_tswebsocketapp_tokenbot_tokenwebhookbot_tokensigning_secretTelegramtelegramwebsocket长轮询 getUpdates/ webhook是消息编辑是是Forum Topics 的message_thread_idbot_tokenwebhook 另有secret_token钉钉dingtalkwebsocketStream 模式/ webhook是AI 卡片是否client_id、client_secret、card_template_idMattermostmattermostwebhook仅支持 Outgoing Webhook REST API是是是root_idsite_url、bot_token、outgoing_token必填、bot_user_id、post_to_main微信wechatiLink 机器人longpoll强制创建时后端强制modelongpoll、output_modefull否仅整段输出是否bot_token、ilink_bot_id均必填QQ 机器人qqbotwebsocket仅支持否否否app_id、client_secret、api_base_url、gateway_url云之家yunzhijiawebhook/ websocket从send_msg_url推导 WS 地址否是是顶层 msgId / 回复 replyRootMsgIdsend_msg_url必填、secret、app_id、app_secret、allowed_webhook_host_suffix、timeout_seconds从源码结构看模式默认值在internal/im/types.go的BeforeCreate钩子中补齐mattermost/yunzhijia默认webhook其余默认websocketwechat由 internal/handler/im.go 强制longpollfull。内置命令系统命令框架位于internal/im/command.go与command_registry.go命令只声明意图CommandResult.Action副作用由 Service 执行。LooksLikeCommand见command_registry.go用于区分命令尝试/help与应透传给 QA 的路径文本如/api/v2/users——前者未注册时回复未知指令后者正常进入问答。NewService中注册的全部命令命令实现文件功能副作用/help [命令名]cmd_help.go列出全部可用指令或查看某条指令的详细用法无/infocmd_info.go展示当前绑定 Agent 的信息与能力Agent/RAG 模式、启用的知识库清单KBSelectionModeall/selected/none、Skills、MCP 服务、联网搜索开关、输出模式无/search 关键词cmd_search.go直接对 Agent 可达的知识库做混合检索向量关键词返回原文片段不经 AI 总结最多显示 5 条、每条 200 rune附匹配度百分比。知识库范围与 QA 流水线的resolveKnowledgeBasesFromAgent一致含 Agent 模式能力过滤无/stopcmd_stop.go中止当前正在进行的回答可打断长 ReAct 推理链ActionStop先移出队列或取消本机 in-flight再向 StreamManager 写 stop 事件与 Web 端 StopSession 同机制支持跨实例停止——通过im:inflight:映射查到 sessionID/messageID最后写 Redisim:stop:标记兜底已排队未执行的请求/clearcmd_clear.go清空对话记忆ActionClear软删当前ChannelSession下一条消息创建全新 WeKnora 会话命令注册使用小写 key重复注册会在启动时 paniccommand_registry.go的Register把配置错误尽早暴露。群聊与私聊行为ChatType由适配器判定direct私聊ChatID为空或group常量定义见 internal/im/adapter.go。飞书/Lark群聊中通常需要 机器人长连接订阅到的群消息文本带_user_N前缀适配器循环剥除后再处理回复时群聊优先走 reply-in-thread话题回复若群不支持话题错误码 230071 等自动回退普通发消息adapter.go的 fallback 逻辑。Slack群聊消息来自AppMentionEvent机器人以及 channel/group 的MessageEvent过滤BotID非空的机器人消息、非file_share的 subtype回复固定发在 thread 中thread_ts顶层消息用自身时间戳。Telegramgroup/supergroup判定为群聊剥除botname提及前缀回复带reply_to_message_id。MattermostOutgoing Webhook 触发词必须是消息第一个词否则回调解析为空消息internal/handler/im.go 中有针对性的排查日志post_to_main凭据控制回帖发主频道还是线程。会话隔离user模式下同一用户在私聊与群 A群 B分别是不同ChannelSessionkey 含chat_idthread模式下同一线程内所有用户共享会话。两种模式常量在adapter.go的SessionMode中定义。文件消息处理文件和图片会作为 QA 附件处理文档内容会提供给模型图片会在模型支持时直接识别。因此即使渠道未配置文件知识库机器人也会基于附件内容正常回复。knowledge_base_id只决定是否将附件额外保存到知识库。配置后保存任务在后台执行不影响当前 QA 回复也不会额外发送已入库或解析完成消息。解析文本最多保留前 500 行且不超过 32 KiB常量maxIMAttachmentLines、maxIMAttachmentContentBytes见 internal/im/service.go触及任一限制时模型会得到通用截断提示。附件无法读取、平台不支持下载或文件超过 32 MiB 时maxIMAttachmentBytes机器人会提示用户改用文字描述或重新发送。图片另有 8 MiB 上限maxIMVisionAttachmentBytes防止超大图展开为过大的 data URI。回复中的图片外链resource:// 改写答案里引用知识库图片时正文中是resource://或local:///minio://等内部引用IM 客户端无法直接拉取。rewriteStorageURLsinternal/im/service.go在发送前把它们换成可访问的 http(s) URL其核心逻辑委托给 internal/storageurl 的共享实现解析结果不是http(s) 时例如仍是内部storage://路径保留原引用并打一条可操作的 WARN而不是把 IM 端注定加载失败的链接发出去成功改写记 INFO 日志含签名 URL便于排障代价是有日志权限的人可在有效期内使用该链接。要让图片正常显示二选一存储后端公网可达对象存储使用公网 endpoint或把MINIO_ENDPOINT设为公网 hostresource://会回退到后端预签名 URL配置APP_EXTERNAL_URLresource://改写成APP_EXTERNAL_URL/r/token请求经 nginx 的location ^~ /r/反代回 app。官方前端镜像已内置该 location自建反代必须补上否则请求落进 SPA fallback 返回空白页。默认的 MinIO 内网部署minio:9000和local后端只能走第二种。IM 渠道已启用但APP_EXTERNAL_URL为空时LoadAndStartChannels会打印一次启动告警imImageConfigWarning相关行为由 internal/im/im_config_warning_test.go 验证。图片仍然不显示时按 图片与文件的对外访问 的排查表逐项对照——那里汇总了四种 URL 形式与各渠道的取法。MCP OAuth 授权通知身份绑定IM 场景下没有可交互的前端来完成 MCP 服务的会话内 OAuth 授权因此withIMIdentity给上下文打上MCPOAuthNonInteractive标记——Agent 遇到未授权的 OAuth MCP 服务时不阻塞等待而是发出一次性EventMCPOAuthRequired事件handleMessageStream收集这些事件按 ServiceID 去重回答结束后由buildIMMCPAuthNotice生成授权提示追加在回复末尾若配置了APP_EXTERNAL_URL且 OAuthManager 可用则为每个服务生成专属授权链接回调地址APP_EXTERNAL_URL/api/v1/mcp-oauth/callback主体为PrincipalIMUser即授权与租户渠道平台IM 用户绑定否则提示到 WeKnora 管理后台完成授权用户点链接完成授权后重新发送原消息即可使用该 MCP 服务。配置与运行参考渠道模型与配置internal/im/types.go一个IMChannel表im_channels把某个平台机器人绑定到某个 Agent字段说明AgentID绑定的自定义智能体回答走该 Agent 的配置模型、知识库、Skills、MCP、联网搜索Platform/Mode平台与接入模式。默认值mattermost/yunzhijia →webhookwechat →longpoll且强制output_modefull其余 →websocketOutputModestream默认流式或full等完整答案后一次性回复KnowledgeBaseID可选文件知识库。无论是否配置文件/图片都会下载后供 QA 理解配置后会额外在后台入库SessionModeuser默认按 平台用户群 维度映射会话或thread按 平台线程群 维度每个顶层消息开新会话BotIdentity由平台模式凭据推导的机器人唯一标识computeBotIdentity如feishu:app_id、telegram:botID、wecom:ws:bot_id数据库唯一索引types.go中的uniqueIndex防止同一个机器人被配置到两个渠道checkDuplicateBot返回duplicate_bot:前缀错误 → HTTP 409CredentialsJSONB 凭据。列表接口IMChannelSummary从不返回凭据内容只返回credentials_configured布尔值见 internal/im/types.goChannelSession表im_channel_sessions把(platform, user_id, chat_id, thread_id, tenant_id)映射到 WeKnorasession_id实现 IM 侧的对话连续性。若底层 Session 被从 Web UI 删除HandleMessage会检测ErrSessionNotFound软删陈旧映射并自动重建修复机器人永久失联类问题相关回归测试见 internal/im/session_not_found_test.go。渠道管理 APIinternal/handler/im.go router.go方法与路径说明POST /api/v1/agents/:id/im-channels为 Agent 创建渠道校验 platform 合法性、填充默认 mode/output_modeGET /api/v1/agents/:id/im-channels列出 Agent 的渠道不含凭据GET /api/v1/im-channels租户内跨 Agent 渠道总览PUT /api/v1/im-channels/:id更新name/mode/output_mode/knowledge_base_id/credentials/enabled/agent_idDELETE /api/v1/im-channels/:id删除POST /api/v1/im-channels/:id/toggle启用/停用GET / POST /api/v1/im/callback/:channel_id平台回调地址webhook 模式下配置到各平台后台走平台自身签名校验不需要 WeKnora API Key路由注册位于 internal/router/router.go 的RegisterIMRoutes/RegisterIMChannelRoutes。Webhook 模式的接入方式就是把https://你的域名/api/v1/im/callback/channel_id填到平台的事件订阅/回调地址处WeKnora 会先响应平台的 URL 验证挑战HandleURLVerification如飞书的 challenge 回显、企微的 echostr 解密之后每个回调都过VerifyCallback签名校验。WebSocket/长连接模式则无需公网回调地址由 WeKnora 主动连接平台网关。飞书/Lark 反向代理credentials.api_base_url可覆盖 API origin并同时用作长连接 SDK 的 bootstrap domain。留空分别使用飞书/Lark 默认云地址私有网络可填https://feishu-proxy.example.com不在结尾附加具体 API 路径。代理应转发平台 API 与长连接启动请求启动响应返回的 WebSocket 地址也必须能从 WeKnora 服务器访问。只代理网页控制台不能解决服务器到飞书的网络问题。{platform:feishu,mode:websocket,credentials:{app_id:app-id,app_secret:app-secret,api_base_url:https://feishu-proxy.example.com}}云之家选择session_modethread后按话题复用会话顶层消息启动新线程回复沿根消息线程继续。钉钉富文本消息会提取可读内容飞书 post 消息中的图片进入图片处理。output_modefull可显示中间过程与输出进度answer_only保留最终答案。长连接的可靠性leader 选举与 Supervisor多实例 leader 选举service.gowebsocket/longpoll 渠道在多实例部署有 Redis时通过SETNX im:ws:leader:channelIDTTL 15s每 5s 续期保证只有一个实例维持长连接非 leader 实例每 10s 重试抢锁leader 宕机后自动接管。longpoll 渠道停止后保留锁至过期等 TTL 自然过期避免新旧实例短暂双写。续期失败丢失 leader 身份时走handleWSLeadershipLoss先停掉本实例的适配器再把渠道放回抢锁重试循环——重试前会重新读一次数据库中的渠道行因此期间被删除、禁用或改配置的渠道不会被旧运行时复活。相关常量wsLeaderTTL、wsLeaderRenewInterval、wsLeaderRetryInterval见 internal/im/service.go。连接保活supervisor.go的RunSupervised部分 SDK钉钉、飞书的内部重连可能出现连接对象存在但无法接收消息的状态Supervisor 每 6 小时defaultRecycleInterval见 internal/im/supervisor.go主动重建连接连接失败按 5s 退避重试把最坏停摆时间限制在回收间隔内。多实例部署要点所有分布式状态集中定义在service.go的 Redis key 前缀常量Redis Key用途im:ws:leader:channelIDWebSocket/长轮询渠道 leader 选举TTL 15s5s 续期10s 抢锁重试im:dedup:messageID跨实例消息去重TTL 5minim:stop:userKey跨实例 /stop 预执行标记TTL 30sim:inflight:userKeyuserKey →sessionID:messageID映射供跨实例 /stop 写 StreamManager 停止事件im:queue:user:userKey全局单用户排队计数im:ratelimit:key滑动窗口限流ZSETim:global:active全局并发 QA worker 计数Lua 原子 INCR校验TTL 5min 自愈无 RedisLite/单实例模式时全部回退为本地内存实现功能不变仅失去跨实例语义。消息处理流程IMCallbackwebhook或长连接回调最终都进入Service.HandleMessage随后经队列进入 QA 执行关键细节均见service.go去重MessageID写入 Redisim:dedup:TTL 5 分钟或本地sync.Map单实例模式IM 平台重推的回调直接跳过。限流按channelID:userID:chatID[:threadID]做滑动窗口限流默认 60s 内 10 条可经config.IM覆盖斜杠命令绕过限流保证用户在风暴中仍能/stop。QA 队列internal/im/qaqueue.go有界队列 固定 worker 池默认workers5、defaultMaxQueueSize50、单用户排队上限 3、排队超时queueTimeout60s多实例下通过 Redis 计数实现全局单用户上限im:queue:user:与可选的全局并发闸门im:global:active Lua 脚本GlobalMaxWorkers配置对下游 LLM 形成背压。排队位置 0 时先回一条排队中提示。会话解析user模式按用户维度共享会话标题形如张三 · 群聊 1a2b3c4dthread模式每个顶层消息/话题一个会话Slack thread、飞书话题群、Telegram Forum Topic、Mattermost root_id。首条消息会异步生成会话标题GenerateTitleAsync。身份注入withIMIdentityIM 回调走平台签名而非 WeKnora 登录态因此注入合成身份system-tenantIDPrincipalIMUsertenantID:channelID:platform:userID Viewer 角色使组织共享知识库等依赖 UserID 的逻辑正常工作同时标记MCPOAuthNonInteractive见上文 MCP OAuth 授权通知。流式渲染handleMessageStreamthink.gotool_display.go订阅 EventBus 的EventAgentThought思考、EventAgentToolCall/EventAgentToolResult工具状态行内部工具经isToolVisibleToUser过滤快速问答只显示query_understand/knowledge_search两个 RAG 流水线工具、EventAgentFinalAnswer答案分片、EventAgentReferences引用、EventAgentComplete。Agent 模式下乐观答案在后续又发起工具调用时会被撤回进思考块retractAgentLiveAnswer与 Web 端 superseded preamble 一致。每 300ms 把缓冲内容整段推送UpdateStreamContent为替换语义holdbackCutoff会扣住跨分片边界的不完整provider://URL、Markdown 图片、XML 标签避免闪烁半截内容。最终FinalizeStream只保留答案文本StripThinkBlocks并把kb/、web/引用标签与imageXML 清洗掉、provider://存储 URL 重写为可访问链接cleanIMContent/rewriteStorageURLs。非流式路径渠道output_modefull、适配器不支持StreamSender、或StartStream失败时走runQA聚合完整答案后SendReply一次性发送。引用消息Quote目前由 WeCom 长连接适配器等填充文本引用以quoted_message包裹注入 LLM 上下文上限 500 rune区分引用了机器人自己的回复引用图片/文件/视频等非文本消息时注入的是明确告知用户无法查看该内容的指令避免模型猜测无法读取的内容QuotedMessage.NonTextType字段与行为见 internal/im/adapter.go。架构总览Adapter 接口internal/im/adapter.go每个平台适配器实现统一的Adapter接口把平台差异收敛到四个方法type Adapter interface { Platform() Platform // VerifyCallback 校验回调请求的签名/Token VerifyCallback(c *gin.Context) error // ParseCallback 把平台原始回调解析为统一的 IncomingMessage非消息事件返回 nil ParseCallback(c *gin.Context) (*IncomingMessage, error) // SendReply 把回复发回 IM 平台 SendReply(ctx context.Context, incoming *IncomingMessage, reply *ReplyMessage) error // HandleURLVerification 处理平台的 URL 验证挑战 HandleURLVerification(c *gin.Context) bool }两个可选扩展接口决定了平台能力差异StreamSender—— 流式回复StartStream→UpdateStreamContent整段替换语义→FinalizeStream最终只保留答案剥离思考/工具过程→EndStream。实现者Feishu/Lark流式卡片、DingTalkAI 卡片需card_template_id、Slack、Telegram消息编辑、Mattermost、WeCom WebSocket 模式。FileDownloader—— 从平台下载用户发送的文件/图片DownloadFile。实现者除 QQ 机器人外的全部平台WeCom 两种模式均支持。统一消息模型IncomingMessage携带Platform、MessageTypetext/file/image、UserID、ChatID、ChatTypedirect/group、Content、MessageID用于去重、FileKey/FileName/FileSize、ThreadID话题/线程 ID、Quote引用消息等字段。Service 编排internal/im/service.goim.Service是消息处理中枢职责从 Adapter 接收统一的IncomingMessage为该 IM 渠道解析或创建 WeKnora 会话Session优先分发斜杠命令不进入 QA 流水线普通消息调用 WeKnora QA 流水线KnowledgeQA/AgentQA收集流式回答并通过 Adapter 回发。平台适配器通过AdapterFactory注册internal/container/container.go 的registerIMAdapterFactoriesimService.RegisterAdapterFactory(wecom, wecom.NewFactory()) imService.RegisterAdapterFactory(feishu, feishu.NewFactory(feishu.RegionFeishu)) imService.RegisterAdapterFactory(lark, feishu.NewFactory(feishu.RegionLark)) // Lark 与飞书同一适配器仅 API 域名不同 imService.RegisterAdapterFactory(slack, slack.NewFactory()) imService.RegisterAdapterFactory(telegram, telegram.NewFactory()) imService.RegisterAdapterFactory(dingtalk, dingtalk.NewFactory()) imService.RegisterAdapterFactory(mattermost, mattermost.NewFactory()) imService.RegisterAdapterFactory(wechat, wechat.NewFactory()) imService.RegisterAdapterFactory(qqbot, qqbot.NewFactory()) imService.RegisterAdapterFactory(yunzhijia, yunzhijia.NewFactory())实现参考核心框架与编排internal/imadapter.go、service.go、supervisor.go、command*.go、qaqueue.go、session/stream/think/tool_display等各平台适配器internal/im/{wecom,feishu,dingtalk,slack,telegram,mattermost,wechat,qqbot,yunzhijia}HTTP 接口层internal/handler/im.go路由internal/router/router.go 的RegisterIMRoutes/RegisterIMChannelRoutes渠道数据模型与默认值internal/im/types.go相关文档图片与文件的对外访问【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表