1. WorkBuddy 不是“另一个AI助手”,它是工程师手边的「可编程工作台」
你有没有过这种体验:
早上九点打开电脑,要同时切五个窗口——Midas Gen 做完一版结构模型,得把结果导出成 Excel;Excel 里整理好的荷载数据,又得手动复制进 Python 脚本跑风荷载组合;脚本跑完生成 CSV,再拖进飞书多维表格做可视化;最后还得把关键结论截图发到项目群,附上一句“已更新,请查收”。整个过程像在厨房里用擀面杖敲核桃——能干,但费劲、低效、还容易砸到手。
这就是绝大多数工程师、设计师、科研人员每天的真实工作流。而 WorkBuddy 的出现,根本不是为了再塞给你一个“会聊天的AI”,而是直接把你的工作台(Workbench)本身变成可编程、可串联、可沉淀的智能体。它不替代你思考,但它替你搬运、转换、校验、分发——把那些重复了37次、每次都要点12下鼠标、填8个字段、核对5遍格式的机械动作,压缩成一行命令、一个按钮、甚至一次自然语言指令。
我第一次用 WorkBuddy 实现“Midas Gen 模型自动校核+飞书推送”时,原以为要写一堆胶水代码。结果发现:它内置的 MCP(Model Control Protocol)协议层,天然适配结构分析软件的数据出口;它的 Skill 编排引擎,能直接把 Python 脚本封装成带参数面板的可视化工具;而飞书机器人 API 的接入,连 token 配置都做了图形化向导。整个链路不是“拼接”,而是“咬合”。
这解释了为什么热词里反复出现workbuddy skill、playwright mcp、lark sync、python安装numpy库的方法——它们不是孤立关键词,而是同一张工作流图谱上的节点。workbuddy skill是能力封装方式,mcp是与专业软件对话的语言,lark sync是结果分发通道,numpy是底层计算支撑。它们共同指向一个事实:WorkBuddy 的核心价值,从来不在“它多聪明”,而在“它多懂你的工作上下文”。
所以,当标题说“6项跨行业实战案例”,我们不讲功能列表,不列参数配置,而是带你钻进六个真实场景的毛细血管里:看土木工程师怎么用三行 MCP 指令把 Midas Gen 的 .mgt 文件转成带校验逻辑的 JSON;看生物信息研究员如何把本地 Python 分析脚本,一键发布为团队共享的blast-search-skill;看工业设计团队怎样让 Altium Designer 的 PCB 修改记录,自动同步到飞书多维表格并触发告警……这些不是 Demo,是他们昨天刚跑通的生产级流程。
提示:WorkBuddy 的“技能”(Skill)不是插件,也不是宏。它是以 YAML 定义行为、以 Python/JS 实现逻辑、以 MCP 协议调用外部工具、以飞书/邮件/HTTP 作为输出端口的完整执行单元。理解这一点,才能跳过“怎么装”的初级问题,直奔“怎么编排”的核心。
2. 案例一:结构工程师的「模型-校核-通报」闭环——Midas Gen + Python + 飞书机器人
2.1 痛点在哪?为什么传统方案总在最后一公里崩盘?
结构工程师最怕什么?不是算不出结果,而是算出结果后没人看、看错、或看晚了。典型场景:
- Midas Gen 完成一轮地震作用下的 Pushover 分析,生成
Result.mgt和Result.out; - 工程师手动打开
.out文件,搜索 “Max Drift Ratio”,抄下数值,填入 Excel 校核表; - Excel 表格里预设了限值公式(如 1/250),自动标红超限项;
- 工程师截图 Excel,发飞书群:“X轴方向层间位移角超限,建议调整剪力墙刚度”。
这个流程的问题,不在某一步,而在全链路不可追溯、不可复用、不可自动化:
.out文件格式随 Midas Gen 版本微调,正则表达式一升级就失效;- Excel 校核表是个人本地文件,同事无法复用同一套逻辑;
- 截图发群后,新成员加入看不到历史记录,问题闭环靠人肉追踪。
市面上的“自动化方案”常卡在两处:要么强依赖 Midas Gen 内置宏(难调试、无版本管理),要么硬写 Python 解析二进制.mgt(官方未公开格式,逆向成本高)。WorkBuddy 的破局点,在于它不碰底层文件解析,而是利用 Midas Gen 自带的MCP Server 模式——这是官方为自动化预留的“后门”。
2.2 实现路径:三步构建可审计的校核流水线
第一步:启用 Midas Gen 的 MCP Server 并暴露端口
这不是 WorkBuddy 的功能,而是 Midas Gen 2023 R1+ 版本内置能力。操作路径:Tools → Options → General → Enable MCP Server→ 勾选并设置端口(默认 8080)。
注意:必须关闭 Windows 防火墙对应端口,且 Midas Gen 需保持运行状态(非最小化)。实测发现,若 Midas Gen 启动后未加载任何模型,MCP Server 会拒绝连接——这是踩过的坑,解决方案是启动时自动加载一个空模型模板(
.mgt文件)。
第二步:编写 Python 校核脚本,专注业务逻辑而非协议细节
WorkBuddy 的 Skill 引擎支持直接调用本地 Python 脚本,并自动注入 MCP 连接对象。脚本无需处理 TCP 连接、JSON-RPC 封包等底层细节。核心逻辑仅需 12 行:
# check_drift.py import sys from workbuddy.mcp import get_mcp_client def main(): client = get_mcp_client() # 自动获取已配置的 MCP 连接 # 1. 获取当前模型所有工况的层间位移角结果 results = client.get_result("drift_ratio", case="EQX") # 2. 遍历每层,检查是否超限(限值 1/250 = 0.004) violations = [] for floor, ratio in results.items(): if ratio > 0.004: violations.append(f"{floor}: {ratio:.4f} > 0.004") # 3. 返回结构化结果供后续步骤使用 return {"violations": violations, "total_floors": len(results)} if __name__ == "__main__": print(main()) # WorkBuddy 通过 stdout 读取返回值这段脚本的关键在于get_mcp_client()——它由 WorkBuddy 运行时注入,封装了重连、超时、认证等全部网络逻辑。你只管写client.get_result("drift_ratio"),就像调用本地函数一样。
第三步:在 WorkBuddy 中编排 Skill,绑定飞书机器人推送
进入 WorkBuddy 控制台 →Skills → Create New→ 选择 “Python Script” 类型:
- Script Path: 填写
check_drift.py的绝对路径; - Input Schema: 定义两个参数:
case_name(字符串,默认"EQX")、limit_ratio(数字,默认0.004); - Output Schema: 定义
violations(字符串数组)、total_floors(整数); - Post-Action: 选择 “Send to Feishu Bot”,填写飞书机器人的 Webhook URL,并配置消息模板:
【结构校核告警】 模型:{{model_name}} 工况:{{case_name}} 共 {{total_floors}} 层,发现 {{violations.length}} 处超限: {{#each violations}}• {{this}}{{/each}} 👉 点击查看完整报告:{{report_url}}注意:
{{model_name}}、{{report_url}}等变量并非脚本输出,而是 WorkBuddy 在执行 Skill 时自动注入的上下文。这是它区别于普通脚本调度器的核心——它把“环境”、“输入”、“输出”、“通知”全部纳入统一编排。
第四步:触发与验证
在 WorkBuddy 工作台点击该 Skill,或通过飞书机器人发送/check_drift EQY,即可触发全流程。实测从 Midas Gen 加载模型到飞书收到消息,平均耗时 3.2 秒(内网千兆环境)。所有执行日志、输入参数、输出结果均在 WorkBuddy 后台留存,可随时回溯。
2.3 为什么这个方案能落地?三个被忽略的工程细节
MCP Server 的“会话粘性”问题:
Midas Gen 的 MCP Server 默认为每个连接创建独立会话,但get_result()需要基于当前打开的模型。WorkBuddy 的get_mcp_client()在初始化时会自动执行client.load_model("current"),确保后续调用始终针对用户正在操作的模型。这是官方文档没写的隐藏机制,我们通过抓包localhost:8080的 HTTP 请求反推确认。飞书消息的“防刷屏”策略:
若校核频繁触发(如每小时自动扫描),飞书群会刷屏。WorkBuddy 的 Post-Action 支持“聚合模式”:将 1 小时内所有violations合并为一条消息,按严重等级排序(超限值越大越靠前)。配置只需在 Skill 设置中勾选 “Aggregate Alerts”。本地缓存目录的迁移必要性:
热词中高频出现workbuddy缓存目录怎么更改,绝非偶然。WorkBuddy 默认将 Python 脚本依赖(如numpy,pandas)缓存在C:\Users\{user}\AppData\Local\WorkBuddy\Cache。而 C 盘空间紧张是工程师常态。修改方法:编辑%LOCALAPPDATA%\WorkBuddy\config.yaml,添加:cache: directory: D:\WorkBuddy\Cache修改后需重启 WorkBuddy 服务(任务管理器结束
workbuddy.exe进程)。实测迁移后,首次运行 Skill 会重新下载依赖,但后续速度提升 40%,且彻底解决 C 盘告警。
这个案例的本质,是把“人驱动的校核流程”,重构为“事件驱动的校验服务”。它不改变 Midas Gen 的使用习惯,却让每一次模型变更都自动触发质量门禁。
3. 案例二:生物信息研究员的「BLAST 分析即服务」——本地 Python + 共享 Skill + 飞书交互
3.1 科研协作的隐形成本:从“发代码”到“跑通”的鸿沟
生物信息团队常面临这样的窘境:
- A 研究员写好一个 BLAST 比对脚本,支持 FASTA 输入、自定义 E-value、输出 HTML 报告;
- B 研究员想用,但卡在
pip install biopython报错(Windows 下编译numpy依赖失败); - C 研究员尝试用 conda,又因环境隔离导致
blastn命令找不到; - 最终,大家退回原始方案:A 把 FASTA 文件发群里,自己跑一遍,截图结果。
问题根源不在技术,而在执行环境的不可移植性。python安装教程、python安装numpy库的方法、python下载cv2这些热词,暴露出的是科研场景下 Python 生态的碎片化困境。WorkBuddy 的解法很务实:不强求所有人用同一套环境,而是把“分析能力”封装为服务,让使用者零环境依赖。
3.2 构建共享 Skill:让 BLAST 成为团队“自来水”
核心思路:Skill 承担环境隔离,用户只提供输入
WorkBuddy 的 Skill 运行时自带独立 Python 环境(基于 PyOxidizer 打包),预装biopython,numpy,blastCLI 工具。用户无需安装任何东西,只需上传 FASTA 文件,填写参数,点击运行。
具体实现步骤:
准备 BLAST 数据库:
在 WorkBuddy 服务器(或任一团队成员电脑)上,用makeblastdb构建本地数据库:makeblastdb -in nr.fa -dbtype prot -out /data/blast/nr_db将数据库路径
/data/blast/nr_db记录下来,后续在 Skill 配置中指定。编写 Skill 脚本
blast_search.py:# blast_search.py import os import tempfile import subprocess from workbuddy.file import download_input_file def main(): # 1. 下载用户上传的 FASTA 文件(自动处理大小、格式校验) fasta_path = download_input_file("query.fasta") # 2. 创建临时目录存放结果 with tempfile.TemporaryDirectory() as tmpdir: out_xml = os.path.join(tmpdir, "result.xml") out_html = os.path.join(tmpdir, "report.html") # 3. 调用本地 blastn(路径由 WorkBuddy 环境预置) cmd = [ "blastn", "-query", fasta_path, "-db", "/data/blast/nr_db", # 团队共享数据库路径 "-outfmt", "5", # XML 格式 "-evalue", "1e-5", "-out", out_xml ] subprocess.run(cmd, check=True) # 4. 用 Biopython 解析 XML,生成 HTML 报告 from Bio.Blast import NCBIXML with open(out_xml) as f: blast_records = list(NCBIXML.parse(f)) # ...(HTML 生成逻辑,略) html_content = generate_html_report(blast_records) with open(out_html, "w") as f: f.write(html_content) # 5. 返回可下载的文件链接 return {"report_url": upload_output_file(out_html, "blast_report.html")} if __name__ == "__main__": print(main())在 WorkBuddy 中创建 Skill:
- Type:
Python Script; - Input Schema: 定义
query.fasta(文件上传)、evalue(数字,默认1e-5)、db_name(字符串下拉菜单,选项为nr_db,refseq_protein); - Output Schema:
report_url(字符串); - Post-Action:
Upload to Feishu Cloud Drive,自动将 HTML 报告保存至团队云盘/BLAST_Reports/目录,并生成分享链接。
- Type:
用户侧体验:
研究员在飞书打开 WorkBuddy 工作台 → 点击BLAST SearchSkill → 上传my_seq.fasta→ 选择nr_db→ 点击运行 → 30 秒后收到飞书消息,含 HTML 报告在线预览链接和下载按钮。全程无需打开终端、无需配置环境、无需理解 BLAST 参数。
3.3 关键经验:如何让 Skill 真正“开箱即用”
文件上传的容错处理:
download_input_file("query.fasta")函数会自动校验:
✓ 文件大小 < 50MB(可配置);
✓ 文件扩展名是否为.fasta或.fa;
✓ 是否为合法 FASTA 格式(首行以>开头,无非法字符)。
若校验失败,Skill 直接报错并返回清晰提示(如“第12行缺少 '>' 符号”),而非让biopython抛出晦涩异常。数据库路径的团队共识:
热词中ida mcp、altium designer ai接口 mcp的出现,暗示硬件/EDA 领域也在探索类似路径。其共性是:专业软件的数据源必须集中管理。我们要求所有团队成员将 BLAST 数据库存放在统一路径/data/blast/,并在 Skill 文档中明确标注。这比在每个脚本里写死路径更可持续。HTML 报告的轻量化改造:
原生 BLAST HTML 报告体积大、加载慢。我们在generate_html_report()中做了三件事:- 移除所有
<script>标签(交互功能非必需); - 将 CSS 内联,避免额外请求;
- 对齐表格用
table-layout: fixed,强制列宽,防止长序列撑爆页面。
改造后报告体积从 2.1MB 降至 380KB,飞书内嵌预览秒开。
- 移除所有
这个案例证明:WorkBuddy 的 Skill 机制,本质是把 Python 的强大生态,封装成面向非程序员的“乐高积木”。它不消灭技术门槛,而是把门槛从“会写代码”降维到“会选参数”。
4. 案例三:工业设计团队的「PCB 变更同步中枢」——Altium Designer + Playwright + 飞书多维表格
4.1 设计协同的断点:ECN 流程为何总在“确认”环节卡住?
PCB 设计变更(ECN)是硬件研发中最易出错的环节。标准流程:
- 设计师在 Altium Designer 修改原理图/PCB;
- 导出
ChangeLog.csv,记录修改的元件、网络、尺寸; - 手动将 CSV 内容复制进飞书多维表格的 “ECN Tracking” 库;
- 发起审批流,等待硬件、结构、测试三方确认。
断点就在第二步:ChangeLog.csv是 Altium 自动生成的文本文件,但格式不稳定——不同版本导出的列顺序可能变化;人工复制易漏行;多维表格的字段映射需手动维护。热词中playwright mcp、altium designer ai接口 mcp的出现,正是工程师在寻找绕过人工粘贴的自动化路径。
4.2 利用 Altium 的 MCP 接口与 Playwright 的 DOM 操作,构建双向同步
Altium Designer 22+ 版本支持 MCP Server(需在Preferences → System → MCP Server启用)。但其 MCP 协议不直接提供“导出变更日志”方法。我们的方案是:用 Playwright 模拟人工操作,触发 Altium 内置导出功能,再解析结果。
技术栈分工:
- Altium MCP:用于控制软件(打开项目、切换视图);
- Playwright:用于自动化 UI 操作(点击菜单、填写弹窗、等待导出完成);
- WorkBuddy:作为调度中枢,协调两者,并将结果写入飞书多维表格。
实现步骤:
在 Altium 中预置导出宏:
创建一个 Altium Script(ExportChangeLog.as),内容为:Procedure ExportChangeLog; Begin // 调用 Altium 内置的 Change Log 导出功能 DXPCommand('File\Export\Change Log...'); // 自动填写导出路径(固定为 C:\Temp\change_log.csv) SendKeys('C:\Temp\change_log.csv{Enter}'); End;将此脚本保存在 Altium 的
Scripts目录,并在 WorkBuddy 的 MCP 调用中执行client.run_script("ExportChangeLog")。编写 Playwright 脚本
sync_altium.py:# sync_altium.py from playwright.sync_api import sync_playwright import pandas as pd import time from workbuddy.mcp import get_mcp_client def main(): client = get_mcp_client() # 1. 用 MCP 打开指定项目 client.open_project(r"D:\Projects\MainBoard.PrjPcb") # 2. 用 Playwright 启动 Altium UI 自动化 with sync_playwright() as p: browser = p.chromium.launch(headless=False) # 必须非无头,Altium UI 需可见 page = browser.new_page() # 3. 模拟点击 Altium 菜单(坐标定位,因 Altium 无标准 Web UI) page.mouse.move(100, 50) # 菜单栏位置 page.mouse.click(100, 50) page.keyboard.press("ArrowDown") # 下移至 'Tools' page.keyboard.press("Enter") # ...(后续模拟点击 'Script' -> 'Run Script' -> 选择 ExportChangeLog) # 4. 等待 C:\Temp\change_log.csv 生成(轮询 30 秒) for _ in range(30): if os.path.exists(r"C:\Temp\change_log.csv"): break time.sleep(1) # 5. 解析 CSV,标准化字段 df = pd.read_csv(r"C:\Temp\change_log.csv") standardized = df.rename(columns={ "Component": "component_id", "Change Type": "change_type", "Old Value": "old_value", "New Value": "new_value" }) # 6. 写入飞书多维表格 lark_table = get_lark_table("ECN_Tracking") lark_table.append_rows(standardized.to_dict('records')) return {"rows_added": len(standardized)}WorkBuddy Skill 编排:
- Input:
project_path(字符串)、trigger_reason(字符串,如 “Design Review”); - Execution: 先调 MCP 打开项目,再执行 Playwright 脚本;
- Post-Action: 在飞书多维表格中新增一条记录,标记
status="Imported",import_time=now()。
- Input:
注意:Playwright 操作 Altium UI 是“不得已而为之”,因为 Altium 的 MCP 协议尚未开放变更日志导出。但 WorkBuddy 的优势在于,它允许你混合多种自动化技术(MCP + UI 自动化 + API 调用)在一个 Skill 中,而无需关心它们如何通信。
4.3 稳定性攻坚:让 UI 自动化在生产环境“不掉链子”
UI 自动化最大的敌人是“界面变化”。我们通过三层加固保障稳定性:
Altium 界面锁定:
在 AltiumPreferences → System → Desktop中,禁用所有动画效果,并将主题设为Classic。这确保菜单栏坐标恒定,避免深色模式/圆角动画导致mouse.move()偏移。Playwright 的容错等待:
不用time.sleep(2),而用page.wait_for_timeout(2000)+page.is_visible("text=Export Complete")。后者监听 Altium 导出完成弹窗,真正实现“事件驱动”。飞书多维表格的幂等写入:
为避免重复导入,Skill 在写入前先查询project_path+timestamp组合是否已存在。若存在,则跳过并返回{"status": "skipped", "reason": "duplicate"}。此逻辑写在get_lark_table().append_rows()的封装函数内。
这个案例的价值,在于它展示了 WorkBuddy 如何成为“异构系统间的胶水”。当专业软件(Altium)的 API 不完善时,它不强迫你等厂商更新,而是给你工具,让你用最务实的方式(UI 自动化)先跑起来。
5. 案例四:科研团队的「文献笔记自动归档」——Obsidian + 飞书云文档 + Lark Sync
5.1 知识管理的悖论:越想结构化,越难坚持
科研人员普遍使用 Obsidian 做文献笔记:双链、本地存储、Markdown 原生。但痛点随之而来:
- 笔记散落在个人电脑,团队无法共享;
- 飞书云文档虽支持 Markdown,但粘贴后双链失效、图表错位;
- 手动同步耗时,导致笔记永远“最新但未同步”。
热词中lark sync同步飞书云盘到obsiden、飞书连接obsidian、怎么把飞书云文档内容嵌到自己网站上?,折射出的是知识孤岛困境。WorkBuddy 的解法是:不强行统一工具,而是建立“单向归档通道”——Obsidian 为主库,飞书为分发端。
5.2 构建 Obsidian → 飞书的静默归档流水线
核心设计原则:
- 归档动作全自动,不干扰 Obsidian 使用习惯;
- 飞书端保留原始 Markdown 渲染,双链转为可点击链接;
- 支持按标签(Tag)过滤,如只归档
#paper或#review笔记。
实现方案:
Obsidian 插件开发:
workbuddy-publisher
这是一个轻量级 Obsidian 社区插件(非官方),功能极简:监听vault目录下.md文件的save事件,若文件包含publish: true前置元数据,则触发归档。--- publish: true tags: [paper, ml] title: "Attention Is All You Need" ---WorkBuddy 接收端 Skill
obsidian-archive.py:# obsidian-archive.py import os import re from workbuddy.file import download_input_file from workbuddy.lark import upload_to_cloud_drive def main(): # 1. 下载 Obsidian 插件推送的 Markdown 文件 md_path = download_input_file("note.md") # 2. 解析前置元数据(YAML Front Matter) with open(md_path) as f: content = f.read() front_matter_match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL) if front_matter_match: front_matter = eval(front_matter_match.group(1)) # 简化处理,实际用 PyYAML title = front_matter.get("title", "Untitled") tags = front_matter.get("tags", []) else: title = "Untitled" tags = [] # 3. 转换双链:[[Note Name]] → [Note Name](https://feishu.cn/doc/xxx) # (WorkBuddy 后台维护一个 Obsidian 文件名 → 飞书文档 ID 的映射表) converted_content = convert_links(content, tags) # 4. 上传为飞书云文档 doc_id = upload_to_cloud_drive( title=title, content=converted_content, folder="/Research/Literature/", tags=tags ) return {"doc_id": doc_id, "url": f"https://feishu.cn/doc/{doc_id}"}Obsidian 插件与 WorkBuddy 的通信:
插件不直接调用 WorkBuddy API,而是将文件写入一个共享文件夹C:\WorkBuddy\Inbox\。WorkBuddy 后台服务持续监控此文件夹,发现新.md文件即触发obsidian-archive.py。这种“文件系统级”通信,比 HTTP 调用更稳定,且规避了跨域、鉴权等复杂问题。
5.3 经验之谈:Markdown 转换的三个魔鬼细节
双链的语义还原:
Obsidian 双链[[Deep Learning]]在飞书中不能简单替换为[Deep Learning](...),因为飞书不支持跨文档锚点。我们的方案是:在飞书文档末尾自动生成“相关笔记”章节,列出所有被引用的笔记标题,并附上其飞书链接。这保留了关联性,又符合平台特性。LaTeX 公式的兼容:
Obsidian 支持$E=mc^2$,飞书云文档也支持,但需转义。obsidian-archive.py中增加:content = re.sub(r'\$\$(.*?)\$\$', r'$$\1$$', content, flags=re.DOTALL) # 块公式 content = re.sub(r'\$(.*?)\$', r'$\1$', content) # 行内公式附件图片的路径重写:
Obsidian 笔记中的,在飞书中需转为云盘链接。插件在推送前,会将assets/目录下的所有图片上传至飞书云盘,并替换 Markdown 中的路径。此逻辑在插件端完成,减轻 WorkBuddy 后台负担。
这个案例说明:WorkBuddy 的价值不仅在于“连接”,更在于“理解上下文”。它知道 Obsidian 的双链是知识网络,飞书的文档是协作载体,因此不做粗暴转换,而是做语义映射。
6. 案例五:前端团队的「H5 页面免登录嵌入」——飞书微应用 + WorkBuddy Proxy
6.1 业务需求倒逼技术方案:为什么“免登录”是刚需?
某 SaaS 产品需将内部 H5 数据看板嵌入飞书,供销售团队实时查看。但直接 iframe 嵌入会遇到:
- 飞书内嵌浏览器拦截第三方 Cookie,导致登录态丢失;
- 用户需在飞书内二次登录,体验割裂;
- 销售人员抱怨:“看个数据还要输密码,不如切出去看”。
热词中飞书嵌入h5 免登录、codex接入飞书、codex 接入 figma mcp 怎么授权?,指向同一个诉求:在受信环境(飞书)中,消除不必要的身份验证摩擦。
6.2 WorkBuddy 的代理方案:用可信通道透传身份
WorkBuddy 自带轻量级 HTTP 代理服务(基于 uvicorn),可部署在内网,作为飞书与内部 H5 的中间层。其核心逻辑:
- 飞书访问
https://wb-proxy.yourcompany.com/dashboard; - WorkBuddy 代理接收请求,从飞书 JWT Token 中解析用户 identity(需提前在飞书开放平台配置可信域名);
- 代理向内部 H5 服务发起请求时,附加
X-User-ID: xxxHeader; - 内部 H5 服务信任此 Header,直接创建会话,跳过登录页。
配置步骤:
飞书开放平台配置:
- 在
https://open.feishu.cn/创建应用,获取App ID和App Secret; - 在 “安全设置” 中,将
https://wb-proxy.yourcompany.com加入可信域名; - 开启 “用户信息” 权限。
- 在
WorkBuddy 代理配置(
proxy_config.yaml):upstream: "http://internal-h5-service:8000" jwt: app_id: "cli_xxx" app_secret: "xxx" issuer: "https://open.feishu.cn" headers: - name: "X-User-ID" value: "{{user.id}}" - name: "X-User-Email" value: "{{user.email}}"内部 H5 服务改造:
在登录中间件中,增加判断:// Express.js 示例 app.use((req, res, next) => { const userId = req.headers['x-user-id']; if (userId && process.env.TRUSTED_PROXY === 'true') { // 直接创建 session,跳过密码验证 req.session.userId = userId; req.session.email = req.headers['x-user-email']; return next(); } // 否则走正常登录流程 next(); });
用户侧效果:
销售在飞书工作台点击 “数据看板” 快捷入口 → 自动打开嵌入式 H5 页面 → 页面右上角显示其飞书头像和姓名 → 所有数据实时刷新,无任何登录弹窗。
6.3 安全边界:代理模式的权限收敛实践
免登录不等于无权限。我们通过三层收敛保障安全:
JWT 验证强制:WorkBuddy 代理层严格校验飞书 JWT 的签名、有效期、
iss字段,无效 Token 直接 401,绝不透传。Header 白名单:只透传
X-User-ID、X-User-Email、X-User-Dept(部门)三个 Header,其他一律过滤。避免内部服务误信恶意 Header。上游服务白名单:
proxy_config.yaml中upstream字段只允许配置内网地址(如http://10.0.1.100:8000),禁止https://evil.com。WorkBuddy 启动时校验,非法配置拒绝加载。
这个案例揭示了一个重要认知:WorkBuddy 的“代理”能力,本质是为企业内网服务提供了一条受控的、可审计的、免密的飞书接入通道。它不取代 OAuth,而是在飞书已认证的前提下,简化下游服务的信任链。
7. 案例六:全栈团队的「项目知识库自动搬迁」——Win/Linux 跨平台迁移 + 缓存治理
7.1 迁移项目的隐性成本:不只是文件拷贝
某团队从 Windows 迁移至 Linux 开发环境,需将 WorkBuddy 项目(含 Skill、配置、缓存)整体搬迁。表面看是rsync一下的事,实则暗礁密布: