
GitBot 看看 LangBot 最近有没有什么值得关注的更新。在飞书群里 机器人随口问一句最近 GitHub 上有什么更新几十秒后拿回一份由 GPT-6 Astra 生成的更新简报这背后不是某个爬虫脚本而是一套 LangBot 负责消息收发、Dify 负责流程编排、GitHub API 提供数据的自动化工作流。我这次把整条链路完整搭了一遍期间踩了不少坑也总结出很多文档里不会写的细节。这篇文章就是这份实战记录适合已经玩过一点 Dify、想往真实业务场景里落 AI 助手的同学。1. 整体设计一问一答背后的系统分工1.1 先拆需求我要的不是爬数据动手前我很认真地做了需求拆解。在飞书里问一句就拿到 GitHub 更新简报这几个字看起来简单但拆成技术语言会变成三件完全不同的事第一自然语言理解能力。用户的问法是随意的可能是看看最近更新也可能是这个仓库这周有什么变化还可能是v2.4.0 发了没有。如果只靠关键词匹配永远追不上人类的表达方式。第二真实数据获取能力。GitHub 上的 Release、Commit、Issue、PR 都是动态资源不能靠提前扒好一份静态文件应付所有情况。第三易读的展示能力。用户要的是一眼能看懂的简报而不是一坨 JSON。顺着这三个诉求技术选型就很自然了飞书机器人当交互入口GPT-6 Astra 负责语义理解和文本总结Dify 负责把整个业务流程编排成可视化工作流LangBot 负责屏蔽不同 IM 平台的接入差异GitHub API 当实时数据源。这一套组合下来用户感知到的是问一句就有简报背后则是好几个系统在协同。1.2 为什么选 LangBot Dify而不是自己写服务我最早做飞书机器人时习惯直接用飞书 SDK 写一个 HTTP 服务自己处理消息签名、事件订阅、会话回复然后在大模型 API 调用、JSON 解析、前端消息拼接上面反复折腾。功能能跑但改了三次需求之后我就决定换架构了。原因很简单飞书侧的消息验签和事件重试机制加上业务侧的意图判断、参数抽取、外部 API 调用、结果总结全部揉在一个项目里每次加一个渠道比如企业微信就要动主线逻辑维护成本非常高。引入 LangBot 和 Dify 之后分工清爽了很多。LangBot 管渠道层它原生支持飞书、企业微信、钉钉、Discord 等平台我只需要在配置里声明启用飞书通道、填上应用凭据它就替我搞定了事件接收、消息解析和回复发送。Dify 管逻辑层整个 Agent 工作流是可视化节点意图解析、条件分支、HTTP 调用、大模型生成每一步都能单独调试。GPT-6 Astra 管智能层理解自然语言、总结长文本这些事情交给模型比手写一堆 if/else 可靠得多。用个不太严谨的类比LangBot 是前台接待Dify 是装配车间GPT-6 Astra 是车间里的高级工程师GitHub API 是原材料仓库。前台只负责把客人领到车间工程师负责理解需求、查料、出活最后由前台把成品送回客人手上。1.3 一条消息的完整旅程为了让后面配置的时候不迷路我先把完整时序写出来。用户从提问到看到简报大概经过以下环节用户在飞书群里 机器人发送看看某仓库的更新。飞书开放平台通过事件订阅把消息事件推送到 LangBot 暴露的回调地址。LangBot 校验事件签名、解析文本按配置把消息转发给 Dify 工作流 API。Dify 工作流启动先用大模型节点提取仓库名、时间范围、查询类型等参数。工作流根据查询类型调用对应 GitHub API比如查 Release 走/repos/{owner}/{repo}/releases查 Commit 走/repos/{owner}/{repo}/commits。拿到原始 JSON 后再用模板节点裁剪只保留关键时刻避免把所有数据都塞给模型。GPT-6 Astra 在生成节点把结构化数据整理成自然语言简报。Dify 把结果返回给 LangBot。LangBot 把内容发回飞书用户看到简报。从架构上看各组件职责非常明确组件职责关键能力飞书开放平台交互入口事件订阅、机器人消息LangBot消息网关多平台适配、验签、回复发送Dify流程编排工作流、可视化调试、API 发布GPT-6 Astra语义 core意图解析、结构化输出、文本总结GitHub API数据源Release / Commit / Issue 数据2. 核心链路拆解每个组件到底在干什么2.1 飞书侧不只是发消息而是接收消息很多人对飞书机器人的理解还停留在往群里扔一个 webhook 地址用脚本 POST 一条消息。但在这个场景里单向推送根本不够用因为用户每次问法都不一样机器人必须能听到群里的消息再动态回复。所以必须用飞书开放平台的自建应用 事件订阅模式而不是自定义机器人 webhook。关键配置有三个应用必须开启机器人能力这样它在群里才是一个可被 的账号要订阅im.message.receive_v1事件这个事件在机器人被 或收到私聊消息时触发飞书会把消息内容、发送者、群 ID 以 JSON 形式 POST 到回调地址回调地址必须能快速返回成功响应。飞书对事件推送有超时机制我实测下来如果 3 秒内没有返回 200飞书大概率会判定失败并按策略重试。测试阶段回调地址可以用公网可达的服务器或临时端口转发方式暴露但生产环境建议直接用云主机加域名 HTTPS。这里的核心点是回调地址必须稳定、快速、不被防火墙拦截否则飞书那边的事件推送会一直失败。2.2 LangBot一个懂多种 IM 的信使LangBot 在整个方案里的角色我个人会用信使来形容。它本身不做太多智能判断但负责把消息从飞书安全地送到 Dify再把 Dify 的结果拿回来发出去。这中间包括事件验签、消息解码、平台格式适配、重试机制等一堆琐碎工作。LangBot 的配置模型大致是先声明启用哪些平台通道比如feishu然后填入该平台的 App ID、App Secret、Encrypt Key、Verification Token。它启动后会监听一个端口接收对应平台的回调请求。飞书推送过来的事件先在这里被验签和解码再被转成 LangBot 内部统一的消息对象。接下来LangBot 需要知道把消息交给谁。在我的方案里这个谁就是 Dify 工作流的 API。LangBot 支持配置自定义的 Agent/API 端点把 Dify 工作流发布后的请求地址填进去它就会把消息正文作为输入参数发送过去再把 Dify 的回复字段原样带回飞书。选 LangBot 还有一个挺实际的考虑如果哪天老板说企业微信也接一下,我只需要在 LangBot 配置里多开一个通道填上企微的凭证余下逻辑完全不用动。这就是渠道层和逻辑层分离带来的好处。2.3 Dify 工作流把写代码变成搭节点Dify 是开源的 LLM 应用开发平台我这次用的是社区版 1.17.1。相比普通聊天应用工作流类型的应用更适合这个需求因为整个流程是确定的先理解意图再查数据最后总结。用可视化节点把这些步骤串起来每一步的输入输出都能单独看调试效率非常高。我的工作流节点从上到下是这样的开始节点接收用户原始输入。LLM 节点意图解析让模型输出包含仓库名、时间范围、查询类型等信息的 JSON。条件分支节点根据查询类型走不同分支比如 release、commit、issue、overview。HTTP 请求节点每个分支调用对应的 GitHub API。模板节点把 API 返回的 JSON 裁剪成长度可控的结构化文本。LLM 节点用 GPT-6 Astra 生成最终简报。结束节点返回简报内容。这个结构最大的优势是每一层职责单一。意图解析不准就只调这个节点的提示词API 返回格式变了就只改模板节点简报太啰嗦就只调生成节点的提示词。相比传统代码里动一个函数牵扯一片这种搭积木的方式确实更适合 AI 应用的快速迭代。2.4 GPT-6 Astra简报质量的放大器GPT-6 Astra 在链路里承担了意图解析和简报生成两个关键职责。先说意图解析模型要能从看看 dify 最近有没有发版这句话里提取出ownerlanggenius、repodify、query_typerelease、time_rangeweek。过去用正则做很快就陷入用户换个说法就失效的泥潭。换用大模型后只要在提示词里给出示例和输出 schema基本能覆盖绝大多数表达。再说简报生成。GitHub API 返回的是结构化 JSON但用户要的是人话。Astra 的工作是把 Release 的版本号、发布时间、更新内容以及 Commit 里涉及的核心模块变化挑重点按影响程度排序再用简洁的 markdown 输出。这里很考验模型对信息的理解能力比如同样的更新内容哪些是性能优化哪些是破坏性变更哪些只是依赖升级都需要模型结合上下文判断。网上最近有不少关于 Rethinking Skills and Prompts for GPT-6 Astra 的讨论我的体会是新一代模型在结构化输出和工具调用上确实更强但它更需要清晰的任务边界而不是一堆你必须式的命令。给好示例、定义好输出的 JSON 结构模型反而不容易跑偏。3. 从零搭建一套可以直接抄的完整流程3.1 环境准备与部署规划先交代我的部署环境一台 4 核 8G 的 Linux 云主机Ubuntu 22.04用来跑 Docker、LangBot、Dify并且它本身能被飞书服务访问到。如果你只在本地体验也可以用公网可达的隧道把本地端口暴露出去做联调但生产环境别这么干稳定性太差。要安装的组件有Docker 与 Docker ComposeDify 社区版通过 docker compose 部署LangBot 本体我用 Docker 方式跑Git、curl、jq联调阶段用来直接测试 GitHub API 和检查 JSON 解析一个可用的 GPT-6 Astra API Key以及对应的 Base URL。端口规划也很关键。Dify 默认会占用 80/443 端口LangBot 我习惯让它监听 8790 端口避免冲突。如果服务器上已经有 Nginx 这类服务记得提前调整端口映射别等启动报错才想起来。我特意记录一下版本Dify 社区版用的是 1.17.1。这个版本的工作流编辑体验和模型供应商配置已经比较成熟下面的步骤在这个版本上都能直接落地。3.2 部署 Dify 社区版Dify 官方仓库的 release 页面可以找到对应版本的源码包。我的做法是直接 clone 指定 tag然后进 docker 目录启动git clone --depth 1 --branch 1.17.1 https://github.com/langgenius/dify.git cd dify/docker cp .env.example .env docker compose up -d第一次启动会拉取不少镜像时间比较久耐心等。启动完成后访问服务器的 80 端口能看到 Dify 的初始化页面创建管理员账号。注意.env里的SECRET_KEY生产环境一定要改成随机长字符串不然会有安全隐患。初始化完成后在 Dify 后台做几件事进入设置-模型供应商添加一个 OpenAI-兼容的供应商填入 GPT-6 Astra 的 API Base 和 Key然后创建一个工作流类型应用后面所有节点都在这个应用里编排。注意如果你发现 Dify 启动后 80 端口被占用可以先把 Dify 的对外端口改掉但那么做的代价是后面所有回调地址都要带上新端口。建议还是给 Dify 一个干净的 80 端口。3.3 部署 LangBot 并配置飞书通道LangBot 我用 Docker 方式部署容器需要映射一个端口出来同时挂载数据目录放配置文件mkdir -p langbot-data docker run -d \ --name langbot \ -p 8790:8790 \ -v $(pwd)/langbot-data:/app/data \ --restart unless-stopped \ your-registry/langbot:latest首次启动后LangBot 会在数据目录生成配置。建议先停掉容器改完配置再启动避免配置被覆写。配置里要启用飞书通道核心字段大概是platforms: - type: feishu enabled: true app_id: cli_xxxx app_secret: your_app_secret encrypt_key: your_encrypt_key verification_token: your_verification_token callback_url: https://your-domain.com/feishu/callback这里的四个凭据都来自飞书开放平台下面一节详细说怎么申请。callback_url就是飞书事件要推送到的地方生产环境最好用 HTTPS。3.4 创建飞书自建应用并配置事件订阅这块步骤琐碎但一步都不能少。我按操作顺序列一下登录飞书开放平台进入开发者后台创建企业自建应用。在应用能力里启用机器人能力。在权限管理里申请im:message、im:message.group_at_msg、im:message.p2p_msg这几个权限具体权限名以飞书后台实际显示为准。在事件订阅里添加im.message.receive_v1事件。把事件订阅请求地址配置为 LangBot 的回调地址比如https://your-domain.com/feishu/callback。开启 Encrypt Key 和 Verification Token把生成的值复制到 LangBot 配置里。点击创建版本并发布应用等管理员审核通过。这里最大的坑是只添加了事件、申请了权限但没发布应用版本导致权限不生效群里 机器人毫无反应。另一个坑是回调地址验证失败飞书会先发一个url_verification请求要求服务端按规则返回 challenge。LangBot 内置了这套逻辑所以关键是确保回调地址能真正到达 LangBot 进程而不是被 Nginx 或防火墙拦截。3.5 在 Dify 里编排工作流工作流应用创建好之后我们开始逐个节点配置。以下配置我直接给出参考模板读者可以按自己仓库情况调整。意图解析节点模型选择 GPT-6 Astra系统提示词大概是这样你是一个 GitHub 信息助手。根据用户输入提取以下 JSON不要输出其他内容 { owner: 仓库所有者, repo: 仓库名, time_range: 时间范围如 7d/24h/week无法判断则用 all, query_type: overview/release/commit/issue } 示例 用户说看看 dify 最近一周有没有 release 输出{owner:langgenius,repo:dify,time_range:week,query_type:release}温度设置为 0输出稳定性比创造性重要。这一步跑出来的 JSON后面的分支节点直接引用。条件分支节点根据query_type的值分成四个分支release、commit、issue、overview。Dify 的可视化界面里选择上一步节点的输出变量然后配置等于某个值即可。HTTP 请求节点以 release 分支为例GET https://api.github.com/repos/{{owner}}/{{repo}}/releases?per_page30 Headers: Authorization: Bearer ghp_xxxxxxxxxxxx Accept: application/vnd.githubjsonToken 一定要带上GitHub API 未认证时限额只有每小时 60 次一个真实工作流很容易触顶。认证后是每小时 5000 次放心很多。这里要特别说明per_page的设置。Release 接口不支持按时间筛选所以我一次性拉取 30 条后面在模板节点里用发布时间过滤。Commit 接口则更友好直接用since和until参数比如2025-01-01T00:00:00Z但需要在请求前把用户说的时间范围换算成时间戳这一步可以在 Dify 里用代码节点处理也可以直接让意图解析节点把时间范围输出为标准格式。模板节点裁剪数据这个节点容易被忽略但对控制 token 消耗和生成质量非常关键。GitHub 返回的 JSON 里光 Release 的 body 就可能几千字直接喂给大模型既浪费 token 又让模型抓不住重点。我用 Jinja2 模板把数组里的字段挑出来{% for item in items %} 版本: {{ item.tag_name }} 发布时间: {{ item.published_at }} 说明: {{ item.body[:500] }} {% endfor %}Commit 分支保留 commit message、author、changed file 数Issue 分支保留 title、state、comment count、html_url。裁剪之后模型看到的每条数据都足够精简能聚焦在哪些是真的值得关注的更新上。简报生成节点第二个 LLM 节点提示词我这么设计你是一名资深开源项目管理助理。用户查询的仓库是 {owner}/{repo}。 请根据以下原始数据生成一段简明扼要的更新简报 1. 如果包含 Release先说明最新版本和发布时间再列出值得关注的新特性或破坏性变更。 2. 如果包含 Commit概括主要改动方向不必逐个列举。 3. 如果包含 Issue总结讨论热度高的议题并给出链接。 4. 使用中文markdown 格式控制在 300 字以内。温度设 0.3既保持稳定又有一点自然语感。结束节点把该节点的输出作为最终回复字段返回。3.6 让 LangBot 调用 Dify 工作流完成端到端联调Dify 工作流编排完先点右上角发布。发布之后在 Dify 的 API 访问页能拿到工作流 API 地址类似POST https://your-dify-domain/v1/workflows/run Headers: Authorization: Bearer app-xxxxxx Content-Type: application/json Body: { inputs: { sys.query: 看看某仓库的更新 }, response_mode: blocking }LangBot 那边的配置核心是把默认的模型服务地址替换成这个工作流 API同时设置请求头 API Key 和请求体模板让 LangBot 收到的消息文本进入sys.query字段。不同版本 LangBot 的具体字段名有差异但要找的核心就是Base URL / API Key / 请求体模板这三项。联调时我的经验是先在 Dify 的运行页面手动测通整个工作流再配置 LangBot 去调用。如果直接上飞书联调万一没回复你很难判断是飞书配置问题、LangBot 路由问题还是工作流本身的问题。先分层测通能省很多排查时间。3.7 定时推送与多维表格扩展问答模式跑通后很多人会想更进一步每天自动往群里推一份关注项目的更新汇总。这个扩展思路其实很顺在 Dify 里可以新建一个入口默认不要求用户输入具体仓库而是查询关注列表。外部用 cron 定时请求 Dify 工作流 API把预设仓库列表传进去生成结果后用飞书机器人主动推送到群里。飞书机器人的主动推送可以用应用发送消息 API比自定义 webhook 更规范还能带消息卡片。另外热搜里提到的飞书机器人发送表格和飞书多维表格也是个很实用的延伸。如果需要把简报沉淀成可回溯的数据可以让 Dify 工作流在生成简报的同时把结构化数据追加到飞书多维表格。方法是在 Dify 里再加一个 HTTP 节点调用多维表格的 records 接口把版本号、发布时间、更新摘要这些字段写进去。这样团队每天不只有一份自然语言简报还有一张可以筛选、透视的更新台账。4. 常见问题与排查技巧实录4.1 飞书消息发出去机器人完全没反应这是最高频的问题。我的排查顺序是从外到内先看飞书开放平台的事件订阅列表里有没有推送失败记录。如果有点开看返回信息大多数是回调地址返回非 200 或超时。再用 curl 手动模拟一次飞书的验证请求确认回调地址可以公网访问且能正确返回 challenge。接着确认权限是否已发布这个坑我前面已经强调过。最后检查群里的 方式机器人只有在被 时才触发im.message.receive_v1单聊除外。有些群配置了仅群主可 机器人也会导致没反应。4.2 LangBot 转发到 Dify 失败报 404 或 401这类问题我归结为三件事URL 对不对、工作流有没有发布、字段名匹不匹配。404 大概率是 Dify 工作流 API 地址不对或者工作流没有真正发布。Dify 里就算测试运行通过没有发布就没有对外 API 地址。401 则检查 Authorization 头Dify 的 API Key 格式是app-xxxx还要注意 Bearer 前缀。最后请求体里的输入字段名必须严格等于工作流开始节点定义的名字比如sys.query多一个空格、少一个下划线都会报参数错误。4.3 GitHub API 限流、超时、拿不到数据如果 HTTP 节点返回 403且响应头里有x-ratelimit-remaining: 0就是限流了。解决方案是每个请求都带上 Authorization 头用 GitHub Token。Commit 查询要记得指定分支一般用?shamain否则返回的是默认分支的历史。按时间段过滤用since和until参数格式要符合 ISO 8601。Release 接口不支持时间过滤必须在模板节点里按published_at过滤。这里我踩过一个挺隐蔽的坑直接用字符串比较日期结果因为格式不一致全部被过滤掉。正确做法是在代码节点里先把 ISO 8601 字符串转成时间戳再和目标时间范围比较。考虑空值情况。某仓库没有 Release、某时间段没有 Commit都会导致模板节点拿到空数组要提前做兼容比如item.body or 或items | length 0时输出提示语。4.4 模型生成的简报太长、太啰嗦或无结构这是大模型工作流最常见的使用体验问题。我的优化顺序是第一在生成节点的提示词里把输出字数写死例如控制在 300 字以内并明确要求使用 markdown 子标题。第二把温度调低。刚开始我用默认 0.7模型经常自由发挥把不重要的 commit 也写进去改成 0.3 后稳定很多。第三检查模板节点的数据裁剪是否够狠。如果一次传入几十条数据模型就会雨露均沾输出变成流水账。我习惯只保留 top 5 Release、top 10 Commit。第四利用 GPT-6 Astra 的结构化输出能力在提示词里给出一个清晰的输出结构示例比如{summary, highlights, links}后续甚至可以解析成飞书卡片字段而不只是纯文本。4.5 部署与安全审查的提醒最后说几个安全相关的经验这些在真实项目里特别重要不要把飞书 App Secret、GitHub Token、Dify API Key 硬编码到配置里再提交到 Git 仓库。敏感信息尽量走环境变量或密钥管理服务。LangBot 和 Dify 的容器都要设置--restart unless-stopped并在前面放一层 Nginx 处理 HTTPS 和基础的访问限制避免回调地址被人恶意刷请求。定期关注 Dify 和 LangBot 的版本更新。我用的 Dify 1.17.1 社区版升级前一定先备份 docker volume尤其是包含知识库和配置的数据卷。LangBot 和 Dify 都支持日志输出。联调阶段把日志级别调到 debug能看到飞书推送的原始事件体和 Dify 返回的完整响应很多问题一看日志就清楚了。我在实际部署里还有一个体会整个链路最难调试的往往不是 AI 部分而是消息从飞书到 LangBot 这段网络链路。只要这段通了后面的 Dify 工作和模型生成反而是可控的。所以在前期准备阶段多花一点时间确认回调地址稳定、超时设置合理、日志能正常输出后面会轻松很多。另外一个很推荐的小扩展如果你们团队日常要用很多 GitHub 项目可以在 Dify 的知识库里维护一份关注仓库清单把每个仓库的 owner、默认分支、更新频率偏好都存好。这样用户在飞书里只要说看看最近的更新工作流自动匹配清单不需要每次完整报出仓库名使用体验会再上一个台阶。