资讯动态

用Dify和飞书AI表格搭建简历自动筛选流水线

发布时间:2026/9/16 19:32:08 来源:尧图企业网站定制
先说我做这件事的真实背景。团队里负责招聘的同事每天光处理简历就要花两三个小时下载附件、打开PDF、滚动页面找教育经历、数工作年限、判断技能匹配度做完这些之后才有时间去约面试。更要命的是不同候选人简历格式千差万别同一个岗位收到的几十份简历光“技能栈”这一项就得来回翻三四遍才能比出高下。后来我用Dify搭了一条自动化的简历处理流水线配合飞书AI表格做数据入口和结果沉淀整个初筛过程从人工拆解变成了“文件传上去几分钟后表格里多出一行结构化评分”HR只需要看分数和摘要就行。这篇文章会把整条流水线的设计思路、节点配置、飞书侧联调、完整代码以及我上线后踩过的坑全部写出来适合有一定低代码基础、想用LLM工作流替代重复性筛选工作的读者参考。不需要你精通编程但至少要对Dify的基本概念工作流、节点、变量和飞书多维表格的操作有初步了解。1. 先从HR最崩溃的场景说起海量简历与低效筛选招聘季最忙的时候一个中型技术岗位能收到几百份简历其中有相当一部分投递者与岗位要求完全不符但HR依旧必须逐份点开确认。这个工作最消耗精力的地方不在于“看”而在于“提取信息后比较”。比如同样是“三年经验”有的人写的是累计三年有的人写的是某一段工作经历三年还有的人干脆没写需要从日期反推。如果纯靠人眼每个人看完一份简历至少要3到5分钟遇到那种排版极其混乱的十分钟也未必看得完。另一个被很多人忽略的问题是筛选标准的一致性。同一个岗位早上看简历和晚上看简历HR的耐心和敏感度完全不一样。经验不足的招聘助理可能把“使用了TensorFlow”当作“熟悉深度学习框架”而资深HR则会继续追问项目规模和应用场景。这恰恰是LLM擅长的事情它能像资深HR一样阅读自由文本把非结构化信息转成固定字段并且每次执行时都遵循同一套判断标准不会因为疲惫而降低准确率。所以我当时的目标非常明确做一个工具让候选人简历从上传进入飞书AI表格开始后续的下载、解析、字段提取、岗位匹配打分、结果回填全部走自动化流程。HR真正要做的只剩两件事——把简历拖进表格以及最后看一眼系统给出的匹配分和摘要决定是否约面。2. 为什么这个活该交给Dify和飞书AI表格干2.1 三种方案绕了一圈最后还是选了LLM工作流动手之前我评估过三条技术路线。第一条是传统RPA也就是模拟人去点击下载、打开文件、读取内容。它的优点是逻辑完全可控但致命缺陷在于对“简历内容的理解”无能为力。RPA可以帮你把PDF文字抽出来但抽出来之后要判断“这人到底会不会Java”你还是得写一堆关键词正则和老旧的规则映射。至于“项目经历是不是流水账”“跳槽频率是否异常”RPA几乎做不了。第二条是自己调大模型API写脚本。技术上完全可行但落地起来很痛苦你需要自己处理文件下载、分段传输、提示词版本管理、异常重试、并发控制还要做一个给HR操作的前端界面。这些工作全做完至少得两周。第三条就是用Dify这样的LLM应用开发平台做工作流编排让平台负责HTTP请求、文件解析、变量传递和节点串联我只需要把精力花在提示词设计和逻辑边界上。配合飞书AI表格这种HR本来就会用的工具作为数据入口整个开发周期被压缩到两三天。两条腿走路之后效果确实很好后面细说。2.2 Dify在这里负责什么飞书Base又负责什么我常跟人形容这两者的分工飞书AI表格是流水线的“传送带和分拣筐”Dify是流水线上的“质检员和记录员”。飞书AI表格多维表格Base承担数据承载和触发职责。HR不需要登录任何新系统也不需要学会调用API她只需要像平时一样把简历文件加到表格记录里多维表格的自动化流程就会立刻发送一个Webhook请求到Dify。招聘进度、候选人列表、备注、面试反馈等也都天然存在这个表格里。飞书Base自带的多视图能力还能按岗位、按日期、按打分排序HR自己就能灵活看板。Dify则承担核心的“理解”工作。它接收飞书推送过来的文件地址把简历附件下载下来提取出纯文本再调用大模型抽取结构化信息最后把结果回写到飞书表格对应记录中。整个过程中Dify所有节点都是可视化编排的出了问题我能清楚定位是文件下载失败、文本解析失败还是提示词抽取出错不用像传统脚本那样四处加print日志。2.3 这个方案的适用边界和团队要求这套方案最适合的是每月处理量在几百到一千份简历、需要快速初筛的团队。它解决的是“让HR从重复劳动中解脱”的问题而不是“完全替代HR做决策”的问题。匹配分数和摘要只能作为初筛参考真正决定候选人是否进入下一轮还是需要HR结合面试表现和岗位实际需求判断。对团队的技术要求也不高。至少得有一个人会基本的环境配置能把Dify社区版跑起来用Docker部署非常简单会看JSON结构能复制粘贴代码并做简单的参数修改。只要做到这一步后续的维护成本其实很低。飞书开发者后台的配置一次搞定之后基本不用动。3. 流水线长什么样从简历上传到评分回填的链路设计3.1 整条链路的数据走向先画一遍完整的数据流后面的配置全都围绕这条链路展开。候选人简历以附件形式被上传到飞书AI表格这是整条流水线的起点。飞书Base的自动化流程监听“记录创建”或“附件更新”事件一旦触发就把这条记录的字段信息包括文件token打包成HTTP请求发送到Dify工作流的Webhook入口。Dify工作流入口接收到请求后第一步是从JSON里取出文件token调用飞书接口换取临时下载链接把简历文件下载到工作流里。注意这里下载的是二进制文件后续的文档提取节点需要接收文件类型变量。第二步用Dify的文档提取节点把PDF、Word等格式的文件转化成纯文本。第三步把纯文本交给LLM节点配合预先定义的岗位要求让模型抽取出姓名、联系电话、工作年限、技能列表、匹配分等结构化字段。第四步是我们自己写的代码节点对LLM的输出做格式解析和兜底校验防止模型偶尔输出非法JSON把后面流程搞崩。第五步通过HTTP请求节点调用飞书Base的API把解析结果回写到原记录中。最后HR在表格视图里刷新一下就能看到匹配分和摘要。3.2 表格字段设计状态位是用来防重复的飞书AI表格的字段设计直接决定了流水线的健壮性。我最初只建了“候选人姓名”“简历附件”“解析结果”三个字段上线第一天就出了乱子——同一个简历因为被HR编辑触发了多次更新Dify重复处理了好几遍。后来我加了两列关键字段“解析状态”和“解析批次号”。解析状态是一个单选字段可选值有“待解析”“解析中”“已完成”“失败”。自动化流程的触发条件设置为当“解析状态”字段值等于“待解析”时触发。Dify回写结果时顺带把状态改成“已完成”。这样只要状态不是“待解析”触发器就不会再次运行即使HR误编辑了其他字段也不会造成重复处理。“解析批次号”用来排查问题。我手动填入一个时间戳作为批次号Dify回写时原样带回日志里一比对就知道是哪一轮处理的结果。3.3 核心设计决策为什么用Webhook而不是定时轮询有人可能会问直接用定时任务每隔十分钟扫描一次表格里有没有新简历不行吗技术上确实可以但实际体验会差很多。用Webhook推送简历进入表格到触发处理中间只有几秒钟延迟HR那边刚把文件拖进去刷新页面没多久就能看到结果。用轮询的话最低也得设置一分钟间隔而且每轮都得多维表格拉取全表做对比攒到上千条记录时接口消耗和延迟都会变大。还有一个更重要的原因飞书Base的自动化流程本身就是低代码的配置Webhook只需要填一个URL和请求体模板比在服务器上部署定时任务更符合“少维护”的目标。我只需要在Dify那边保证Webhook入口稳定在线其余交给平台调度就行。4. Dify工作流逐个节点的配置实录4.1 工作流入参设计比想象中多两个字段Dify工作流的入口节点不是“开始”就完了开始节点的输入参数决定了后面所有节点能引用哪些数据。飞书Base的Webhook请求体会把多维表格记录的完整信息POST过来所以我在开始节点里定义了五个参数record_id记录ID、app_token多维表格应用token、table_id数据表ID、file_token简历附件的token、job_requirement这个岗位的JD要求文本也可以从知识库节点动态获取。这里有个容易忽略的点job_requirement一开始只放在表格字段里传给Dify但后来发现不同岗位要求差异很大如果每次都要改表格配置很麻烦。我把岗位JD单独作为一个文本参数传入这样HR可以在Dify工作流里的对话框直接切换岗位类型灵活得多。4.2 文件下载节点飞书token换取临时链接的细节飞书Base的事件推送并不会直接给一个public可访问的文件URL它给的是一个file_token需要我们通过飞书开放平台的接口换取临时下载链接。这个接口的完整路径是GET https://open.feishu.cn/open-apis/drive/v1/medias/{file_token}/download但直接请求这个地址需要带上Authorization: Bearer tenant_access_token请求头所以不能用一个简单的HTTP节点搞定。我在Dify里先放了一个代码节点用来拼装请求头并返回最终的下载URL然后再用HTTP节点把文件下载下来。由于Dify的HTTP请求节点支持“文件”类型的输出下载简历文件时我选择用二进制方式接收并把结果存为文件变量。后面接文档提取节点时直接引这个文件变量就行。旧版的Dify对文件下载支持得比较弱我用的版本已经可以稳定处理这种场景了如果你发现自己的版本没有“输出为文件”的选项建议先升级一下。4.3 简历解析与LLM抽取提示词决定抽取质量简历解析这一步用的是Dify内置的文档提取节点支持PDF、DOCX、TXT等常见格式。它本质上完成的是把二进制文件转成纯文本的动作不改变内容的结构也不做语义判断。真实世界里的简历文本经常是半结构化的项目经历和时间线混在一起教育背景的行文方式五花八门所以接下来的LLM节点才是整个流程的胜负手。LLM节点的输入我设置了两个主要变量一个是文档提取结果简历纯文本另一个是岗位要求文本。系统提示词经过多次迭代当前版本长这样你是一名资深HR招聘顾问负责对候选人简历进行结构化信息抽取和岗位匹配度评估。 从简历文本中提取以下字段以JSON格式输出 { name: 候选人姓名, phone: 联系电话, email: 邮箱, years_of_experience: 工作年限数值, current_company: 当前公司, current_title: 当前职位, skills: [技能列表按熟练程度排序], education: {school: 毕业院校, degree: 学历, major: 专业}, work_summary: 200字以内的核心经历摘要, fit_score: 0到100之间的整数对应该候选人与岗位要求的匹配程度, highlight: 最值得关注的3个优势用分号分隔, risk_tag: 需要关注的疑点或短板没有就返回空字符串 } 注意 1. 如果某个字段在简历中不存在返回null不要编造。 2. 工作年限以简历中起止时间为准不要估算。 3. fit_score需要同时考虑硬性条件学历、经验年限、技能栈和软性能力项目复杂度、业务贡献。 4. 输出必须是合法JSON不要包含任何解释性文字。很多第一次搭提示词的人会犯的一个错误是要求大模型返回“分析过程”再加“结果”。看起来详细实际上不仅浪费token还容易导致JSON解析失败。强制要求只输出JSON解析逻辑会简单可靠得多。还要注意模型的选择。抽取类任务我用的是上下文窗口较大、指令跟随能力较强的模型这类模型一般都能稳定输出符合预期的JSON结构。如果选一个偏向对话风格的模型可能经常会发生“回复开头加一段寒暄”这种问题后面解析就会很痛苦。4.4 回写关卡解析LLM输出并做字段映射的代码节点LLM节点的输出在Dify里是一个字符串变量。虽然提示词要求模型输出JSON但实际模型输出时偶尔会带额外的空格、换行甚至Markdown代码块标记。所以LLM节点之后必须紧跟一个代码节点做清洗和解析不能直接把字符串塞给飞书API。这个代码节点我命名为“解析LLM输出”Python代码的骨架如下import json import re def main(llm_output: str) - dict: output llm_output.strip() match re.search(r\{.*\}, output, re.S) if not match: return {success: False, error: no json found} raw match.group() try: data json.loads(raw) except Exception as e: cleaned raw.replace(, ) try: data json.loads(cleaned) except Exception: return {success: False, error: fjson parse failed: {e}} required [name, phone, email, fit_score, work_summary] for field in required: if field not in data: data[field] None return {success: True, parsed: data}Dify代码节点要求入口函数名必须叫main入参通过类型标注声明返回字典作为输出变量。这个写法跑下来的成功率超过95%剩下的异常情况会在日志里留下error信息方便定位。4.5 回写飞书表格HTTP请求的鉴权与URL拼装最后一步是把解析结果回写到飞书Base对应的记录里。飞书开放平台的更新记录接口是PUT https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}请求体格式是{ fields: { 候选人姓名: 张三, 匹配得分: 85, 工作摘要: ..., 解析状态: 已完成 } }这里同样需要一个tenant_access_token。为了拿到它我单独放了一个HTTP请求节点去调飞书认证接口POST https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal Content-Type: application/json { app_id: your_app_id, app_secret: your_app_secret }然后在后续HTTP请求节点的Header里动态引用返回的tenant_access_token。这个token有效期一般是两小时每次调用都重新获取一次虽然稍慢但足够保证不因token过期而失败。字段名的映射要特别注意飞书Base的“匹配得分”字段类型如果是数字那么传回来的fit_score必须转成数字格式如果是文本字段可以直接传字符串。类型不匹配会导致API直接报错。我的做法是在代码节点里就把返回结构中的字段全部转换为与表格字段类型对应的格式避免在HTTP节点里临时处理。5. 飞书AI表格侧配置三个容易忽略的权限点5.1 创建多维表格的字段和视图飞书侧的表结构建议这样设计字段名字段类型说明候选人姓名文本手动填写或回写简历附件附件支持PDF、DOCX多个文件时只处理第一个岗位名称单选决定使用哪套岗位要求文本解析状态单选待解析、解析中、已完成、失败匹配得分数字0~100工作摘要文本LLM生成的核心经历摘要技能标签多选从JSON数组映射过来解析批次号文本排查用候选人备注文本HR手动填写不参与自动处理视图方面我建了两个一个“待处理视图”只筛选“解析状态为待解析”的记录方便HR看到还有哪些没跑完另一个“结果视图”按匹配得分降序排列HR直接按照分数从上往下看就行。5.2 自动化流程触发器的选择飞书Base的自动化流程支持多种触发条件。我选用的是“当记录满足条件时触发”条件设置为“解析状态为待解析”。之所以不用“记录创建时触发”是因为HR可能先上传附件、再填岗位名称如果简历文件还没传完就触发Webhook里拿到的file_token可能是空的。触发动作选择“发送Webhook请求”URL填Dify工作流的Webhook地址。请求体模板我用的是“包含记录内容”这样飞书会自动把这条记录所有字段打包进JSON包括附件列表对象。附件列表里会有file_token、文件名、大小等信息后续节点按需取用。5.3 权限开通与网络连通性检查在飞书开放平台创建企业自建应用时需要开通以下权限drive:drive:download下载云文档中的文件bitable:app:update更新多维表格记录contact:user.base:readonly读取用户基本信息一般配套开通权限模型如果没配好后面调用接口时大概率返回“permission denied”。这个报错在Dify的HTTP节点里会被当成普通的非200状态码捕获排查起来会有点绕建议在正式跑通之前先用飞书API调试台验证每个接口都能调通。网络连通性也是个容易被忽视的问题。你的Dify服务如果部署在内网或本机飞书云端的Webhook是推不到localhost的必须部署在一个飞书服务器可以访问到的公网地址。我最后是把Dify部署到一台有公网IP的轻量服务器上并且在飞书后台配置了回调地址。如果你只是本地测试可以先配合内网穿透工具把Webhook暴露出去但生产环境建议还是用正规服务器。6. 完整代码与提示词的一个可能版本6.1 Dify代码节点解析LLM输出并做兜底上面4.4节给了核心的解析代码实际生产环境我还在里面加了“技能标签”和“风险标签”的拆分逻辑。由于飞书Base的多选字段接收的是字符串数组代码节点里需要把LLM返回的字符串数组原样传给请求体不能先转成字符串再传否则飞书那边会报类型错误。还有一个兜底细节如果LLM输出的fit_score超出了0到100的范围我会做一次归一化把它强制截断到有效区间内。模型偶尔会在极端情绪下打出105分这种数字你没看错确实发生过。6.2 Dify代码节点构造飞书下载请求参数下载文件节点的完整逻辑不只是返回一个URL还需要处理重定向。飞书的媒体下载接口会返回302跳转Dify的HTTP节点如果开启了自动跟随重定向就直接能拿到文件内容。所以代码节点只需要负责拼装URL和鉴权Headerdef main(file_token: str, tenant_access_token: str) - dict: download_url fhttps://open.feishu.cn/open-apis/drive/v1/medias/{file_token}/download headers { Authorization: fBearer {tenant_access_token} } return {download_url: download_url, headers: headers}然后HTTP下载节点选择“GET”方法Header里引用headers变量输出类型选择“文件”。这样后面的文档提取节点才能正常接收。6.3 飞书API关键调用细节速查表操作方法路径关键参数获取tenant_access_tokenPOST/open-apis/auth/v3/tenant_access_token/internalapp_id, app_secret下载媒体文件GET/open-apis/drive/v1/medias/{file_token}/downloadAuthorization更新记录PUT/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}fields对象查询单条记录GET/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}无每一次调用都要带Authorization: Bearer token只有获取token的接口例外。调飞书接口时返回体里一般会带code字段code等于0表示成功非0时需要结合msg字段判断具体原因。7. 上线一个月遇到的6个坑和对应的解决办法7.1 坑一扫描版PDF全部解析失败文档提取节点对文字型PDF效果很好但一旦遇到扫描版PDF本质是图片提取出来的纯文本几乎为空。这个问题初期差点让整个流水线失去意义因为不少候选人提交的就是手机扫描的纸质简历。我的解决办法有两种。第一种是让HR收到“提取失败”的通知后手动联系候选人换一份电子版第二种是接一个OCR节点先用OCR把图片中的文字识别出来再进LLM。基于成本和稳定性考虑我先用了第一种后续准备在Dify工作流里加一个结构化的“扫描件判断”逻辑当文本长度低于阈值时提示HR人工介入。7.2 坑二带引号的JSON导致解析崩溃大模型输出JSON时偶尔会在字符串字段内部嵌套英文双引号比如候选人曾在某公司负责““AI平台”建设”这会让json.loads直接报错。我在代码节点里加了正则提取和替换逻辑后基本解决了问题。但如果模型输出的语法太离谱兜底也会失败这时候只能靠“解析失败”状态把记录筛选出来重新触发工作流。7.3 坑三并发上传触发飞书限流HR一次性拖30份简历进表格自动化流程会瞬间发出30个WebhookDify处理的同时还会并发回写飞书Base。此时飞书API容易返回“频率超限”的异常。我后来在Dify里给部分节点加了延时每两个请求之间间隔几百毫秒虽然整体处理速度慢了但稳定性大幅提升。如果简历量特别大更合适的做法是引入队列削峰但在每月几百份的量级下延时完全够用。7.4 坑四Dify回复慢导致自动化流程超时飞书Base自动化流程执行Webhook动作时有个外部系统响应超时限制如果Dify工作流整体执行超过一定时间尤其在大模型节点耗时很高时飞书那边会自动标记失败但Dify这边可能还在正常处理。这会导致一个奇怪的现象结果最终被回写了但飞书自动化流程显示“失败”。解决思路是把自动化流程的动作改成“发送Webhook后立即返回”不等待Dify响应。也就是把Dify的工作流设计成异步处理模式飞书只负责把请求推过去Dify内部跑完后自己回写表格。HR关心的最终结果在表格里能看到就行自动化流程的“状态”字段不再重要。7.5 坑五时间是字符串还是秒级时间戳飞书Base的更新接口中日期、时间类字段一般接收毫秒级时间戳或者符合ISO 8601格式的字符串。如果你从Dify代码节点直接传Python的datetime对象会被序列化成字符串很可能导致字段解析失败。我最后只在表格里保留了纯文本的“解析批次号”没有用时间类型字段彻底绕开了这个问题。7.6 坑六模型幻觉干扰评分稳定大模型打分天然存在随机性。同一个候选人的简历提交十次得到的匹配分可能在72到85之间浮动。对于初筛场景这可以接受但如果把“排序后直接淘汰低分者”作为硬性规则就会引发争议。我调整了提示词要求模型先把硬性条件学历、年限、核心技能的满足情况逐一列出再基于明确依据打分。这样分数浮动范围缩小了很多更重要的是每一条分数都有据可查HR追问时能说清楚为什么给这个分。最后再分享三个实战小技巧第一状态字段务必单独设一个视图。我平时只看“结果视图”但每次上线新提示词或新流程时会在“待处理视图”里放一条测试记录手动触发一遍全流程看日志确认没问题再让HR批量导入。日志里Dify的每个节点输入输出都看得到排查速度非常快。第二给LLM节点加“温度”参数。抽取类任务我把温度调到了0到0.2之间跑出来的JSON结构稳定很多。不要用默认值否则同一份简历可能每次抽出来的“highlight”措辞都不一样。第三至少保留一周的原始JSON日志。飞书Base里我设置了一个隐藏字段“原始返回”Dify回写时把解析成功前的JSON原文存进去。一旦后续要优化提示词或者回溯某个候选人的分数依据直接看这个字段就能复盘不用翻服务端日志。这套流水线正式跑了一个多月最直接的收益是简历初筛时间从人均两小时变成了喝杯咖啡的功夫。HR每天打开结果视图按分数从高到低看摘要和优势标签就行。对于“给谁约面试”这类关键决策我仍然建议保留人工判断但“这份简历值不值得花时间看”这件事已经完全可以交给自动化流水线去完成了。如果你也在处理类似的批量文档筛选需求这套Dify加飞书的组合值得一试。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价