ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

一键接入GPT-6 Astra:企业微信与飞书机器人统一网关实践

一键接入GPT-6 Astra:企业微信与飞书机器人统一网关实践 1. 整体设计思路为什么要把 GPT-6 Astra 接进企业微信和飞书这次要做的事是把 GPT-6 Astra 模型以机器人的形态同时接进企业微信和飞书两个办公 IM。在做之前说实话我纠结了一阵为什么非要接两个后来想明白了团队里一部分人用企业微信、一部分人用飞书如果只做一个平台另一边同事就还得切到网页去用 AI等于项目做了一半。所以干脆搞一个统一的消息网关让两边都走同一个模型入口谁在哪个群里 机器人谁就能直接对话。这个内容适合谁看主要是有一定后端基础、想在企业内部落地 AI 助手场景的开发者或运维同学。你会需要自己或者同事帮忙拿到企业微信/飞书的管理员权限用来创建自建应用还需要一个能公网访问的 HTTPS 服务或者干脆用飞书的长连接模式省掉公网暴露。前置条件不算多但里面有一些不实测不知道的坑比如企业微信的回调加解密、飞书的事件订阅重复投递这些我都会在后面的章节里逐个拆开讲。从架构上看整个网关并不复杂企业微信用户发消息 → 企业微信服务器回调到我部署的 FastAPI 服务 → 服务解析出文本内容 → 调 GPT-6 Astra 接口拿到回答 → 再通过企业微信主动消息接口把结果推回去。飞书侧逻辑一样只是入口换成了飞书的事件订阅出口换成了飞书的发送消息接口。核心其实就是一张表每个平台负责收消息和发消息两端中间全部走同一套 AI 调用逻辑。我在选型上有一个明确判断绝不把平台逻辑和模型逻辑写在一起。企业微信的消息格式是 XML 加密包飞书是 JSON 事件两者差异非常大但一旦转成统一的BotMessage结构文本、发送者、平台来源后续的模型调用就完全不用关心自己是在跟哪个平台对话。这样以后加钉钉、加 Slack成本只是新增一个适配器而不是重写一遍大脑。还有一个关键决策是聊天方式。企业微信自带群机器人功能通过 Webhook 就能往群里发消息很多人一开始会图省事直接用这个。但群机器人只能发不能收做不了对话闭环。所以要接 GPT-6 Astra 这种需要你问我答的场景必须用企业微信自建应用的回调接口飞书那边也一样我选择的是自建应用加事件订阅而不是单纯的自定义机器人。这个区别如果一开始没想清楚后面会走弯路。2. 企业微信机器人接入从创建应用到消息回调2.1 创建自建应用与获取企业凭证企业微信的接入第一步是在管理后台创建一个自建应用。登录 work.weixin.qq.com进入应用管理→应用→自建点创建应用填名称和可见范围。创建完成后你会拿到三个关键值CorpID企业 ID、AgentID应用 ID、Secret应用密钥。CorpID 在我的企业页面看Secret 在应用详情里查看AgentID 就在应用信息里。这里有个很多人忽略的细节企业微信调用主动发送消息接口时有可信 IP限制。也就是说你用来调 API 的服务器外网 IP必须提前配到这个应用的可信 IP 列表里否则请求会直接报 60020 错误。如果你是家庭宽带或者动态 IP这个配置会比较痛苦建议部署到有固定公网 IP 的云服务器上买一台最低配的就够跑这个网关。我当时因为本地调试一直报错查了半天才发现是 IP 没加白名单浪费了不少时间。另外建议把 Secret 放到环境变量里不要硬编码在代码仓库。这东西就相当于企业微信里的 API 密钥一旦泄露别人可以拿你的应用身份随便发消息。我见过有人把密钥传 GitHub 导致被刷消息的案例这个属于基础安全习惯但每次都要强调。2.2 配置接收消息服务器应用创建好之后进入应用详情找到接收消息设置打开 API 接收配置三个参数URL、Token、EncodingAESKey。URL 是你自己的服务地址企业微信会往这个地址推送消息事件。注意必须是公网可达的 HTTPS 地址且路径自定义建议用/wecom/callback这样的路径方便区分。Token 是你自己定的一个随机字符串用于签名校验。EncodingAESKey 可以点随机生成也可以自己填它本质上是一个用于 AES 加解密消息的密钥。这三项填完点保存企业微信会立刻发起一次验证请求。验证方式是 GET 请求到你配置的 URL带上四个参数msg_signature、timestamp、nonce、echostr。你的服务需要根据签名算法校验msg_signature然后用 EncodingAESKey 解密echostr再把解密后的明文原样返回企业微信才会确认这个 URL 有效。很多人栽在这一步最常见的问题就是签名拼接顺序搞错。正确的做法是把token、timestamp、nonce、echostr四个字符串先按字母序排序再拼成一个字符串做 SHA-1 哈希得到的十六进制结果和msg_signature比对。注意企业微信的签名用的是 SHA-1不是 SHA-256也别在这里用 HMAC就是最朴素的先排序再拼接再哈希。2.3 消息加解密原理与代码实现企业微信的消息回调是加密的这个加密方案对第一次接触 AES 的开发者来说会有点绕。简单说流程是这样企业微信用 EncodingAESKey 对消息做 AES-256-CBC 加密然后把密文 base64 编码后放到 POST 请求的 XML 里你收到后需要 base64 解码、AES 解密、再解析 XML才能拿到真正的消息内容。解密的细节如下。EncodingAESKey 是 43 个字符加上一个补齐成 44 字符再做 base64 解码得到 32 字节的 AES 密钥。CBC 模式下的 IV 取密钥的前 16 字节。密文解密后前 16 字节是随机字符串可以丢弃接着 4 字节大端序是消息长度再往后才是真正的消息 XML最后是 CorpID 字符串用来校验消息是否来自你的企业。注意企业微信加密填充用的是 PKCS7但分组大小是 32 字节而非常见的 16 字节。很多人直接用 OpenSSL 默认的 AES 工具去解密结果后面一截乱码就是这个原因。我贴一段核心代码解密部分是这样写的import base64 import hashlib import struct from Crypto.Cipher import AES class WeComCrypto: def __init__(self, token, encoding_aes_key, corp_id): self.token token self.corp_id corp_id self.key base64.b64decode(encoding_aes_key ) assert len(self.key) 32 def verify_signature(self, msg_signature, timestamp, nonce, echostr): s sorted([self.token, timestamp, nonce, echostr]) sign hashlib.sha1(.join(s).encode(utf-8)).hexdigest() return sign msg_signature def decrypt_msg(self, encrypt_text): cipher AES.new(self.key, AES.MODE_CBC, self.key[:16]) decrypted cipher.decrypt(base64.b64decode(encrypt_text)) pad_len decrypted[-1] decrypted decrypted[:-pad_len] content decrypted[16:] msg_len struct.unpack(I, content[:4])[0] msg content[4:4 msg_len].decode(utf-8) receive_id content[4 msg_len:].decode(utf-8) if receive_id ! self.corp_id: raise ValueError(corp_id mismatch) return msg这段代码里的encrypt_text是 POST 请求 XML 里Encrypt节点的内容decrypt_msg返回的msg是一段消息 XML里面包含发送者FromUserName、消息类型MsgType、文本内容Content等字段。拿到之后只需要再用xmltodict或者正则把关键字段捞出来就行。我建议在这里统一做一次结构转换把企业微信的消息转成我的统一消息结构后面章节会讲这个结构的设计。2.4 用户发消息后如何调通 GPT-6 Astra消息回调服务写好之后会遇到一个分布式系统里的经典问题你的模型响应太慢企业微信回调早就超时了。企业微信对回调响应的要求是 5 秒内返回而 GPT-6 Astra 这类大模型接口冷启动加推理少说也要两三秒复杂问题可能到十几秒。如果同步阻塞在回调里等模型返回企业微信会重试推送或者直接判定回调失败。我的处理方式是回调接口收到消息后先解析、再异步入队、立即返回收到企业微信要求返回空字符串或success即可真正跟模型通信和回复消息放到后台任务里执行。这个思路不只适用于企业微信飞书、钉钉都一样。模型回复通过主动发送消息接口推送给用户而不是依赖回调的同步响应。主动发送消息的接口是这样先调gettoken拿到 access_token再调message/send。access_token 有效期是 7200 秒必须做缓存不能每次都重新获取。企业微信对 gettoken 接口有频率限制如果被频繁调用还会暂时封禁 IP所以一定得加一个内存缓存或者 Redis 缓存。发送消息的请求体长这样import httpx async def send_wecom_message(access_token, agent_id, user_id, content): url fhttps://qyapi.weixin.qq.com/cgi-bin/message/send?access_token{access_token} payload { touser: user_id, msgtype: text, agentid: agent_id, text: {content: content}, safe: 0 } async with httpx.AsyncClient() as client: resp await client.post(url, jsonpayload) data resp.json() if data.get(errcode) ! 0: # 记录错误企业微信的错误码很有价值 print(fsend failed: {data})你注意到没有这里我没有把回复内容直接拼进回调响应而是走了一个异步发送通道。这样做的另一个好处是如果模型挂了或者内容需要二次校验我可以拦截住不发避免把错误信息直接暴露给用户。模型调用侧我用的是 OpenAI 兼容的异步客户端。不管你的模型服务商是谁只要支持 Chat Completions 协议下面这段代码稍微改改base_url和model就能跑from openai import AsyncOpenAI client AsyncOpenAI( api_keyos.getenv(GPT_ASTRA_API_KEY), base_urlos.getenv(GPT_ASTRA_BASE_URL) ) async def ask_gpt_astra(user_text: str) - str: resp await client.chat.completions.create( modelgpt-6-astra, messages[ {role: system, content: 你是企业内部 AI 助手回答简洁准确不过度解释。}, {role: user, content: user_text} ], temperature0.7, max_tokens1024, timeout30 ) return resp.choices[0].message.content.strip()这里我建议给模型调用加一个显式的 timeout默认值往往太长会让用户等得失去耐心。我在实际项目里是 30 秒超时超过就直接回复这个问题暂时没想好换个说法再问我一次。另外max_tokens不建议设太大IM 里的回答应该短平快1024 足够覆盖绝大多数问答。3. 飞书机器人接入自建应用与事件订阅3.1 创建飞书应用并开启机器人能力飞书的接法跟企业微信有相似之处但细节差得挺多。先到 open.feishu.cn 开放平台创建一个企业自建应用。创建完成后进入应用配置页在添加应用能力里找到机器人启用它。这个机器人就是你在飞书聊天窗口里能搜到、能拉群的那个联系人。启用机器人之后还要配权限。飞书的权限体系比企业微信更细我这次要接收用户消息、回复用户需要至少开通这几个权限im:message读取消息、im:message:send_as_bot以机器人身份发消息。如果后续要让机器人读取图片、文件还需要增加对应的im:resource权限。权限配好后记得发布一个版本企业自建应用只有发布版本后权限和机器人能力才会真正生效。这里有个很容易踩的坑修改权限或者机器人配置后如果只是保存而不发布新版本线上是完全不生效的。我第一次接入时在权限管理里加了半天权限结果机器人一直报权限不足检查了几轮才发现版本没发布。飞书的发布版本机制相当于把一段时间的改动统一打包上线跟发布 App 版本很像。3.2 事件订阅长连接还是 Webhook飞书的事件订阅有两种模式一种是传统的 Webhook 回调需要公网 URL另一种是长连接模式WebSocket。这一点跟企业微信很不一样企业微信没有长连接可选硬性要求公网 URL而飞书的长连接模式对开发者极其友好。长连接模式下你的服务作为 WebSocket 客户端主动连上飞书服务器飞书把事件推送到这个长连接通道上。这意味着你不需要公网 IP不需要配 HTTPS 证书本地开发调试简直舒服到起飞。我当时就是先在公司内网开发机上把长连接跑通确认逻辑没问题后再部署到线上几乎没有因为外网访问不到这件事踩过坑。如果你的生产环境有条件暴露公网 URL用 Webhook 方式也完全可以。但必须注意飞书 Webhook 回调的 URL 验证要求你的服务返回challenge字段的明文原值。如果没有开启加密回调请求体里会带一个challenge字段你原样返回即可如果开启加密需要用 Encrypt Key 解密后再返回。相比之下长连接模式不需要处理这套验证逻辑SDK 内部全包了。我最终选的是长连接因为我部署环境比较受限而且长连接减少了一层网络链路出错概率更低。飞书官方 Python SDKlark-oapi对长连接支持得很好几行代码就能把事件监听跑起来。3.3 接收消息与调用模型的完整流程我用lark-oapi的EventDispatcherHandler来注册消息事件处理器。监听的事件是im.message.receive_v1也就是任意用户私聊机器人、或者群里 机器人时触发的事件。处理器里拿到消息对象的content字段它是一个 JSON 字符串不同消息类型内容不一样文本消息是{text: 你好}图片消息是{image_key: img_xxx}。消息发送者的身份从data.event.sender.sender_id.open_id拿。注意这里返回的是 open_id它跟具体的应用绑定同一个用户在两个不同应用里 open_id 不一样这设计是为了防止应用间通过 ID 串数据。如果你需要把用户消息跟企业微信侧的同一个用户关联需要根据自己的用户体系做一层映射不能直接用 open_id 当全局用户 ID。下面是接收消息、调用模型、回复消息的完整代码骨架import json import lark_oapi as lark from lark_oapi.api.im.v1 import ( P2ImMessageReceiveV1, CreateMessageRequest, CreateMessageRequestBody ) def on_message(data: P2ImMessageReceiveV1) - None: msg data.event.message content json.loads(msg.content) if msg.message_type ! text: return user_text content[text] open_id data.event.sender.sender_id.open_id chat_id msg.chat_id reply_text asyncio.run(ask_gpt_astra(user_text)) request CreateMessageRequest.builder() \ .receive_id_type(chat_id) \ .request_body(CreateMessageRequestBody.builder() .receive_id(chat_id) .msg_type(text) .content(json.dumps({text: reply_text})) .build()) \ .build() client.im.v1.message.create(request) handler lark.EventDispatcherHandler.builder(, ) \ .register_p2_im_message_receive_v1(on_message) \ .build() client lark.Client.builder() \ .app_id(app_id) \ .app_secret(app_secret) \ .log_level(lark.LogLevel.INFO) \ .build()这段代码用的是lark-oapi的同步客户端但消息处理器里我用了asyncio.run包住ask_gpt_astra这在有事件循环冲突时会出问题。后面我在做并发优化时换成了异步版本的客户端写法在回调处直接await。这里给的是最直白的跑通版本先感知整体流程再去找更优的异步方案。3.4 发送丰富消息文本、富文本与表格飞书在消息形态上的能力比企业微信扎实除了纯文本还能发富文本 post、交互式卡片 interactive、文件 file、图片 image 等。我上线之后做了一件事让机器人在回复文本时自动把带结构化数据的回答转换成富文本消息结果大家反馈比纯文本好读很多。富文本消息的 content 也是一个 JSON 字符串只不过结构比文本复杂包含标题和若干段内容。每段可以是文本、链接、图片等不同类型的节点。实际使用中我封装了一个工具函数把模型的输出按行拆成若干段落首行作为加粗标题后续内容作为普通正文。关于飞书机器人发送表格这个需求我在这里多说一句。飞书消息协议里并没有直接的表格消息类型常见的做法有三种发送一个 CSV/Excel 文件用户点击下载后用表格软件打开。调用飞书多维表格 API把数据写入一张多维表然后机器人把表链接发给用户。用交互式卡片的表格组件渲染。我实际体验下来发送文件中转方案最省事把模型生成的表格数据写进 CSV上传到飞书获取 file_key然后发一条 file 类型的消息。这个链路在代码上也就二三十行关键是先调用上传文件接口拿到 file_key再调发送消息接口。4. 核心代码全解析一个网关服务跑通两个平台4.1 统一消息处理接口设计前面提过我不希望两个平台的逻辑互相污染。所以我设计了一个极简统一消息结构所有适配器都往这个结构上转换dataclass class BotMessage: text: str sender_id: str platform: str chat_id: str raw_event: Any Nonetext是用户发来的纯文本sender_id是平台侧的用户唯一标识企业微信的 user id 或飞书的 open_idchat_id是会话标识私聊或群聊platform打标记。企业微信适配器收到解密 XML 后转成BotMessage交给统一处理函数飞书适配器收到事件后同样转成这个结构再往下走完全相同的逻辑。统一处理函数里面只关心一件事用BotMessage.text去问模型拿到回复后调用平台发送器发出去。发送器根据platform字段做路由企业微信用主动消息接口推飞书用CreateMessageRequest发。这个设计让新增平台的边际成本降到最低我后来接钉钉也只花了半天就是同样的套路再加一个适配器。4.2 GPT-6 Astra 调用封装流式与限流模型调用这块除了基础的 Chat Completions 封装我额外加了一个语义缓存。同一个问题如果短时间内重复出现比如群里多个同事问同样的事直接命中缓存不回源模型。我用的缓存 key 是hash(用户问题 上下文摘要)TTL 设为 10 分钟。缓存命中时可以做到毫秒级响应用户体验和成本双双受益。至于流式输出我的看法是IM 场景暂时不值得做。流式输出的核心价值是减少首字节等待时间让用户在网页端感觉它开始在说话了。但企业微信的消息发送不支持流式打字效果飞书的消息更新机制对普通消息也不开放所以即使模型支持流式你也只能等全部内容生成完一次性发出去流式在这里没有用武之地。我针对模型 API 做了两层保护。第一层是并发控制用asyncio.Semaphore(10)限制同时打向模型的请求数避免突发消息把 API 打爆。第二层是用户维度的限流每个用户每分钟最多调用 20 次模型超过就回复你发得太快了稍微等一下这个限制写在统一处理函数里两个平台都生效。4.3 企业微信和飞书双平台的 API 封装对比两个平台的发送接口风格差异挺大我把核心差异整理成一张表方便后续维护对照对比项企业微信飞书发送消息接口message/sendim/v1/messages认证方式access_tokentenant_access_token消息类型text、markdown、news 等text、post、interactive、file 等接收消息方式POST 回调 加密 XMLWebSocket 长连接 / Webhook JSON用户标识user_idopen_id / union_id是否需要可信 IP是主动发送必须否事件重试机制不稳超时就重试有重试需做幂等这张表基本反映了两者的设计哲学差异企业微信更偏私有化、顺序化飞书更偏开放、事件驱动。没有谁更好只是在实现时要注意每个平台的特殊约束。比如企业微信的必须可信 IP这条在我部署到云服务器后就不是问题但如果你的服务器 IP 不固定那就得想别的办法比如走反向代理或者用固定出口 IP。4.4 日志、监控与错误兜底机器人跑起来之后最怕的不是逻辑错而是不知道错在哪。我给网关加了三层日志请求日志谁在什么时间发了什么、模型日志模型返回耗时、token 消耗、错误日志异常栈、错误码。每条日志都带上一个用 UUID 生成的trace_id这样从用户在 IM 里发消息到最终收到回复整条链路可以串联起来排查。错误兜底也很重要。模型调用失败时不能把异常堆栈直接发给用户应该统一回复服务暂时开了个小差请稍后再试并把详细错误打到日志。如果模型返回的内容明显异常比如空字符串、重复文本我做了个简单的过滤丢弃并重新请求一次还是异常就放弃回复。实测下来主模型偶尔会抽风返回空内容加一层重试之后成功率从 95% 提升到 99% 以上。5. 常见问题与排查技巧实录5.1 企业微信侧的高频问题企业微信接入过程中我实际踩过的和帮同事排查过的问题大概有以下几类按出现频率排个序回调 URL 验证失败。这个几乎是第一个坎。先从最简单的外网可达性检查开始用curl -I确认 URL 能从公网访问。再检查签名逻辑很多问题出在排序或拼接顺序上。最后看解密逻辑解密后的内容必须包含正确的 CorpID 后缀否则验证也会失败。我建议在本地先写个单元测试把企业微信用官方示例消息跑一遍再上线接真回调。消息解密后乱码。九成是 PKCS7 填充问题企业微信用 32 字节分组如果解密后末尾有多余的乱码字节多半是填充处理不对。另外注意EncodingAESKey解码前要手动补全一个很多编程语言在 base64 解码时不会自动帮你补。主动发送消息返回 60020。这是可信 IP 没配我刚才在前面已经强调过。补充一点如果有多台服务器都要调接口每个出口 IP 都要加进去。云服务器有多个出口 IP 的情况比较少见但公司内网代理出口往往不止一个要确认清楚。access_token 报无效或过期。确保 token 有全局缓存并且在失效前主动刷新。企业微信的 access_token 有效期 7200 秒我一般提前 600 秒就刷新一次防止消息量大时旧 token 突然失效。我把这些整理成表格方便查阅错误码 / 现象原因解决方案60020请求 IP 不在可信名单在应用详情里添加服务器出口 IP40014access_token 无效检查缓存提前刷新 token回调验证失败签名或解密错误用官方样例逐项对比 signature 和 AES 解密解密乱码PKCS7 填充块大小设置错误使用 32 字节分组而非 16 字节回调报重复推送响应速度慢触发重试回调立即返回 success异步处理后推送5.2 飞书侧的高频问题飞书侧我遇到的最大坑是事件重复投递。飞书为了保证事件不丢失会做重试机制。如果你处理逻辑没有做幂等用户发一句你好AI 可能收到两次甚至三次然后回复两句你好群消息直接刷屏。我后来在收到事件时先检查message_id如果这 30 秒内处理过就丢弃这招虽然简单但极其有效。第二个常见问题是权限不足。报错信息一般是权限不足或invalid permission。大多数情况是权限开了但没发布版本。记住在飞书开放平台点完权限后一定要去版本管理与发布里创建一个新版本并等待管理员审核通过。企业内部应用审核一般都很快但如果你自己就是管理员别忽略了这个步骤。第三个是长连接断开。飞书长连接偶尔会断线重连SDK 会自动处理但如果你在用很老的 SDK 版本重连逻辑可能有问题。建议升级到最新版本并开启log_level(LogLevel.INFO)观察重连日志。我跑了一个月长连接大约断了三四次每次都在几秒内自动恢复整体还是稳的。5.3 模型调用本身的问题接入 GPT-6 Astra 之后模型侧也会带来一些需要处理的边角问题。上下文过长。用户如果在群里聊嗨了历史消息会很长如果把整个对话历史全塞给模型token 消耗大且模型容易跑偏。我的方案是只保留最近三轮问答加上系统提示词组成新的请求。这样既控制了成本也避免模型被无关历史干扰。图片类消息。GPT-6 Astra 支持多模态输入企业微信和飞书也都能接收图片。如果你想做发图给机器人、让 AI 描述图片的功能需要先下载图片文件。企业微信需要通过media_id调用临时素材接口下载飞书则用message_id和image_key去拿图片。图片下载后转 base64放到模型请求的image_url字段里。这一步我没在初版实现是后面迭代加的但架构上因为消息转成了统一结构加图片支持只动了适配器不影响主流程。内容安全。企业内部的 AI 助手还是建议加一道内容过滤模型输出如果明显包含违禁词或者异常内容宁可丢弃也不发出去。这不是矫情是工作环境的基本要求。我用的方案是在模型输出后跑一遍关键词列表再决定是否发送。6. 上线之后我总结的五条经验项目跑起来之后有一些经验不在教科书里但非常值得记下来。第一优先用异步架构不要在回调里同步等模型。不管企业微信还是飞书平台侧都有超时限制同步等待模型返回不仅可能触发重试还会造成消息重复处理。回调接口只负责接收和转发真正干活放到后台任务里这个设计让我少处理了大量重复消息问题。第二先做文本再做多媒体。我在初版只支持文本消息图片、文件、语音都是后加的。文本链路跑通后整个框架的稳定性和日志都比较完善再迭代多模态时问题定位要容易得多。如果一开始就想把所有能力一次性做完调试复杂度会指数上升。第三限流是必须的不是可选的。你没看错群里一旦有人发现机器人好用就会疯狂提问。如果不加用户维度限流模型 API 账单会很难看更重要的是高并发下接口会不稳定最终影响所有人。用asyncio.Semaphore控制全局并发数再用滑动窗口限频每个用户这两层一加系统就稳了。第四一定要有 trace_id。跨平台联调时用户在企业微信问一个问题消息到了网关网关调模型模型回结果再推送回企业微信整条链路上任何一个环节都可能出问题。有了 trace_id我能直接在日志里 grep 出一次完整请求的流转记录排查效率提升好几倍。第五留一条手动踢出用户的通道。机器人如果在群里说错话或者被恶意灌入敏感内容需要能快速下线。我的做法是在统一处理函数入口加了一个全局开关平台维护人员随时可以把这个开关临时打开让机器人只回系统维护中不需要改代码重新部署。这个看似简单的开关帮我们避免过几次不可控场面。这个网关现在还在继续迭代目前计划是接入语音消息识别、增加按群配置不同人设、以及把飞书多维表格做成知识库挂到机器人后面。每次加功能时我都庆幸当初选择把平台逻辑和 AI 逻辑彻底分开不然改一处动全身恐怕早就被维护成本劝退了。如果你也在做类似的接入或者准备把自己的模型接到办公 IM 里照着这套思路走应该能少踩不少坑。
返回列表