做AI应用的朋友应该都有同感:单聊机器人谁都会搭,但要让一个智能体真正承担“研究”这种活,难度完全不在一个量级。研究意味着它要自己找线索、筛信息、抓原文、读内容、再组织成结论,链条长且每一步都容易断。我最近基于 Dify 把 FireCrawl 和百度搜索整合进了一个工作流,算是把这条链完整跑通了,做出来的东西可以当“全能研究助手”用。这篇就把整套思路、配置细节、踩坑记录都摊开来讲,适合正在折腾 Dify 工作流、想给智能体加“联网研究”能力的朋友参考。
1. 从需求到方案:为什么这三样东西要搭在一起
1.1 研究助手到底缺什么
先想清楚一个问题:普通聊天机器人缺的是什么?缺的是“新鲜信息”和“可验证的出处”。大模型的知识截止日期是训练时决定的,你问它“那款开源模型这周发布了什么新版本”,它大概率只会编一个不存在的答案。所以要让智能体具备研究能力,第一件事就是给它接上搜索。
但只接搜索还不够。搜索结果页给的是链接和摘要,摘要那几十个字根本带不动深度问题的回答。你真正需要的是点进链接、把正文抓出来、喂给模型读。这一步在技术圈叫“网页抓取与内容提取”,听着简单,实际坑很多:有的页面是动态渲染的,普通请求拿不到正文;有的页面反爬严重;有的页面内容混着导航、广告、弹窗,抓回来一堆垃圾。
所以研究助手的完整链路应该是这样四段:搜索发现线索、筛选有效链接、抓取页面正文、归纳组织输出。缺任何一环,这个助手都会变成“一本正经地胡说八道”。
1.2 三个工具的分工逻辑
这套方案里,三个工具各管一段链路。
Dify 是编排中枢。它在整个流程里扮演“厨房”的角色,搜索、抓取、分析都是食材和工序,Dify 负责把流程串成一条可复用的自动化流水线,同时提供可视化调试界面,让我能看每一步的输入输出。
百度搜索解决的是“去哪里找”的问题。虽然 Dify 官方工具里已经带了 Bing、DuckDuckGo 这类搜索能力,但做中文场景的研究,百度的覆盖度和时效性更适合国内用户习惯。我不需要跟 LLM 说“帮我搜英文资料”,直接中文一问,搜索结果就是中文世界最相关的那些页面。
FireCrawl 解决的是“拿到链接之后怎么读”的问题。它是一个专门做网页抓取的服务,能把任意 URL 转成干净的 Markdown,支持动态渲染页面,还能整站爬取。相比自写 requests 加 BeautifulSoup 的方案,FireCrawl 免去了处理验证码、渲染引擎、页面解析这套脏活累活,在我这个工作流里是最省心的一环。
1.3 为什么不推荐其他方案
可能会有人问:直接用 Dify 自带的工具不就行了?我用下来感觉有几个具体短板:一是 Dify 内置搜索工具基本是国外搜索引擎或 SerpAPI 这类聚合服务,中文搜索结果质量和国内访问稳定性都一般;二是内置工具返回的结果数据没经过定制化清洗,链路里少了“提炼有效链接”这一步,后面的抓取质量就全靠运气。
也有人会提议自己写 Scrapy 爬虫做抓取服务,然后接进 Dify 的 API 工具。这条路不是不行,但维护成本高,对方网站一改结构就要跟着改代码,动态页面还得维护无头浏览器环境。FireCrawl 直接把这件事封装成了“传一个 URL,返回干净 Markdown”,省掉的运维时间足够把精力放在更核心的提示词和流程设计上。
2. 动手前的准备工作:环境、密钥和前置配置
2.1 Dify 环境与版本说明
这套工作流我是在最近升级过的 Dify 社区版上跑的。社区版迭代速度相当快,新版本对工作流可视化、知识点管理体验优化了不少。如果你还没有环境,官方推荐的做法是用 Docker 部署,一条 docker compose 命令就能起服务。国内拉镜像偶尔会失败,解决方案很朴素:给 Docker 配置镜像加速器,然后重新拉取。
启动完记得先去“系统设置”里配置模型供应商。这个很关键,工作流里所有 LLM 节点都要依赖模型服务。我的选择是配了一个支持函数调用的模型作为“主模型”,因为后面要干搜索词生成、内容提取、总结归纳这些不同类型的任务,一个稳定的主模型能减少很多切换成本。模型配好后可以顺手建一个测试应用,随便跑个对话确认链路通畅了再往下搭。
要提一嘴多租户:Dify 社区版现在支持创建多个工作空间了。我帮团队搭这套工作流的时候,给每个成员分配了独立空间,权限隔离很干净,数据也不会互相串。如果你是个人玩,单空间完全够用,但团队协作场景强烈建议用多租户能力,方便后期管理和审计。
2.2 FireCrawl 的两种接入方式
FireCrawl 想用好,第一步是拿到 API Key。你去官网注册后,后台会给你一个密钥,同时送一些免费额度。免费额度拿来做测试、搭 prototype 足够了,真跑大量抓取任务再考虑付费套餐。
接入 Dify 有两条路。第一条是用 Dify 的“自定义工具”功能,把 FireCrawl 的 OpenAPI schema 填进去。Dify 会自动解析接口定义,生成一个可视化工具节点,这样在 workflow 里就可以像拖拽官方工具一样拖一个“抓取”节点出来。这是我最推荐的方式,配置一次,全局复用。第二条路是直接用“HTTP 请求”节点手动调 FireCrawl 的 API。好处是灵活,坏处是每次都要写 URL、Header、Body,工作流里多条分支时会显得很啰嗦。
我的建议是两条路搭配着用:搜索抓取这种高频操作用自定义工具节点,偶尔调试的时候用 HTTP 请求节点直接看原始返回,排查问题更快。
2.3 百度搜索的接入思路
Dify 没有现成的“百度搜索”工具,所以这里得动点脑筋。我的方案是:让 FireCrawl 去抓百度搜索结果页,再把抓回来的页面内容交给 LLM 提取出真实的文章链接。也就是说,FireCrawl 在流程里承担了双重职责:既是搜索结果页抓取器,也是具体文章页抓取器。
百度搜索结果页的 URL 格式很简单:https://www.baidu.com/s?wd=搜索词。加密参数wd后面接 query,再补一个rn=20就能一页拿 20 条结果。FireCrawl 抓这个页面不需要额外处理,它交付的 Markdown 里通常包含了每条结果的标题、摘要和链接,后续让 LLM 按规则解析就行。
这里有个魔鬼细节:百度结果里的跳转链接往往是加密重定向 URL,直接抓那个链接大概率拿到一堆 JS 脚本而不是原文。所以我在 LLM 解析节点里专门加了一条指令——提取结果时跳过所有以/link?开头的重定向链接,尽量保留真实站点的 URL。如果不加这条,到了 FireCrawl 抓取正文那一步错误率会非常高。
2.4 知识库要不要一起接进来
如果你做的研究助手需要结合自己团队的资料库,我建议在搭好搜索流程之后,把 Dify 知识库也融进来。我个人的习惯是,把经常用的内部文档、此前抓取过的优质文章全部灌进知识库,然后让工作流判定一个问题“是搜新东西”还是“应该先翻资料库”。这个判定逻辑放在意图解析节点里,一句话提示词就能搞定。
知识库有一个必须注意的坑:检索效果差往往不是 Embedding 模型的问题,而是分段策略和召回参数没调好。我遇到过明明文档里有的内容,检索就是召回不出来的情况,最后发现是 TopK 设置太小、段落切得太碎。工作流里接知识库的时候,记得先做几个测试 query,确认召回命中率再往生产上推。
3. 核心工作流实现:从搜索词到研究报告
3.1 整体流程拆解
这个工作流我用的是 Dify 的聊天流模式,因为研究问题通常需要多轮追问,聊天流能保留上下文。完整链路如下:
- 开始节点接收用户输入
- 意图解析节点判断这个问题走“本地知识库”还是“联网检索”
- 搜索词生成节点把口语化问题改写成适合百度的搜索词
- 代码节点对搜索词做 URL 编码,拼出百度搜索结果页地址
- HTTP 请求节点(或 FireCrawl 工具)抓取搜索结果页
- LLM 解析节点从搜索结果中提取候选链接清单和摘要
- 链接筛选节点按相关性排序,选择最优的 2 到 3 个链接
- FireCrawl 工具节点依次抓取这些文章的正文
- LLM 综合分析节点结合所有正文内容和原始问题生成研究报告
- 结构化输出节点以 Markdown 格式返回最终答案
这条链路每一步的输入输出都环环相扣,Dify 可视化面板里可以清楚看到每个节点的数据流转,调试时非常直观。
3.2 关键节点配置实录
先看意图解析节点。我只用了模型节点,没有用分类器,因为简单场景下提示词就够。提示词大概是这样的:判断用户问题是否需要最新信息、外部数据或特定事实,若是则调用联网检索,否则使用本地知识库。
然后是搜索词生成节点。默认用户输入的问题是口语化的“帮我查一下最近国产大模型 API 哪家便宜”,这个不能直接当搜索词用,搜索词应该是“国产大模型 API 价格对比”。所以我在模型节点里给它一个模板:从问题中提取核心名词和限定词,压缩成 2 到 5 个关键词组合,不要加修饰语。
真正有意思的是代码节点。Dify 的代码节点支持 Python,我用它来做 URL 编码,省得每次都让 LLM 去编码容易出错。代码很简单:
import urllib.parse def main(keyword: str) -> dict: encoded_keyword = urllib.parse.quote(keyword) url = f"https://www.baidu.com/s?wd={encoded_keyword}&rn=20" return {"url": url, "keyword": keyword}这里编码一定要在代码节点里做。如果直接拼 URL,中文搜索词不会被浏览器或 HTTP 客户端自动编码,FireCrawl 拿到的 URL 是非法请求,根本抓不到结果。这个小点是我调试时踩过最笨的坑,写出来提醒大家。
搜索结果抓取我用的是 HTTP 请求节点,直接 GET 上面拼好的 URL,不需要额外 Header。返回的内容如果是 JSON 格式,里面会有 markdown 字段,后续解析节点就从这里取数据。
接下来是链接解析节点。这里我让 LLM 从抓回来的 Markdown 中按规则提取真实站点链接。提示词里给了非常明确的格式要求:
[ { "title": "文章标题", "url": "文章真实URL", "summary": "摘要内容", "source": "站点名称" } ]同时告诉它,要去掉百度自己的产品入口和广告区,只保留自然搜索结果。这一步做出来的候选清单质量,直接决定了后面抓正文的效果。
最后是 FireCrawl 抓取正文节点。我配置了onlyMainContent,这个参数很关键——它告诉 FireCrawl 只返回页面主体内容,把导航、页脚、弹窗这些无关信息全扔掉。实测下来,打开的页面哪怕挂了一堆推荐位广告,返回的 Markdown 依然很干净,LLM 读起来舒服多了。
3.3 提示词:研究助手的灵魂
这套工作流里,提示词占的比重比想象中大。我写了几个版本才调到满意的状态,核心感受是“每个节点只让 LLM 干一件事”。
意图解析节点不要让它输出长篇大论,只输出一个字段。搜索词生成节点输出纯字符串,不给解释。链接筛选节点输出 JSON 数组,且要求必须给每个链接打相关性分数。综合分析节点输出一份结构化报告。这样设计的理由是:模型在单一、明确的任务上更稳定,输出格式越简单,越不容易发生解析错误。
综合分析节点是整个工作流的收口,我给它设计的输出模板是这样的:
- 研究结论:用 200 字以内概括核心结论
- 关键发现:列出 3 到 5 个对结论有直接支撑的事实点,每个要点后标注来源
- 争议与差异:如果来源之间观点不一致,明确指出来
- 补充信息:基于搜索内容,列出值得进一步阅读的扩展方向
- 参考资料:以带链接列表的形式附上引用来源
这个输出结构是我反复试用后确定的。研究助手最怕的就是只给一个干瘪结论,没有出处、没有前因后果。上面这套结构基本能让用户拿着答案去回溯原文,判断信息的可信度。
3.4 参数调优:一次完整的实测记录
参数方面,我把 Search 节点的抓取深度设成只抓第一页,也就是 20 条搜索结果。因为经过验证,第一页已经能覆盖大多数研究问题的有效线索,抓更多页反而引入更多噪音,也消耗更多 FireCrawl 额度。FireCrawl 抓正文时设置只返回 Markdown 文本,不要截图,不要 PDF 转换,速度会快非常多。
LLM 节点的温度参数我也做了区分:搜索词生成用低温度,确保关键词稳定性;内容提取用更低温度,防止模型在抽取链接时“创造性发挥”;综合分析用中等温度,让文章有一定归纳自由度。具体值是 0.3、0.1、0.5,大家可以根据自己用的模型微调。
实测案例我把问题定为“帮我调研一下最近国内开源大模型的许可证变化”,整个工作流跑下来耗时二十几秒,抓取了 3 篇相关文章正文,最终报告里正确列出了许可证类型差异、社区争议点、以及各家的官方公告出处。相比我之前用“让 LLM 直接凭记忆回答”,这份报告的可信度高了一个层次。
4. 常见问题与排查技巧实录
4.1 高频报错与解决办法
搭建过程中我整理了一张问题表,基本把能踩的坑都踩了一遍:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 百度搜索结果为空 | 搜索词未 URL 编码 | 加代码节点转码 |
| FireCrawl 抓取超时 | 目标站点响应慢 | 调大 timeout 参数,减少并发 |
| 返回内容全是导航和广告 | 没开 onlyMainContent | 请求参数加上 onlyMainContent=true |
| LLM 提取链接出现截断 | 返回内容超过上下文 | 先截断前 5000 字符再送 LLM |
| 知识库检索不召回 | 分段策略/TopK 设置不合理 | 调 TopK,检查分段重叠 |
| 抓取正文包含大量无用 JS 片段 | 目标页面是动态渲染 | 检查 FireCrawl 返回格式,必要时启用 wait_for |
| 多租户空间看不到自定义工具 | 工具没有跨空间共享 | 在工具管理里设为公开或复制到目标空间 |
前三个问题出现频率最高,基本占了调试时间的七成。特别是超时问题,有些站点本身响应就慢,FireCrawl 默认超时时间不能满足业务场景,我统一在配置里加到了 60 秒,抓取成功率明显提升。
4.2 从“能跑”到“好用”:几个细节打磨
链路跑通之后,我花了整整一个下午做细节打磨。第一个细节是链接去重。百度搜索结果里经常会出现同一个站的多个页面,或者转载内容高度相似的情况。我在筛选节点里让 LLM 对比标题和摘要,把相似度高的结果合并,只保留最完整的那个,避免重复内容反复抓取浪费额度。
第二个细节是来源可信度标注。我把source字段的赋值做了约束,让 LLM 尽量识别出站点类型(官方站点、新闻媒体、个人博客、论坛问答),然后在综合分析节点里按可信度给来源排序。官方公告排第一,个人博客和论坛内容只能作为补充参考,不会喧宾夺主。
第三个细节和安全相关:脚本类内容、验证码页面、非法内容站点,在 FireCrawl 抓取之前就该被拦掉。我在链接筛选节点里加了一条过滤规则,指定站点类型直接剔除,既能节约额度,也避免模型读入垃圾信息影响判断。
4.3 多轮对话场景的特别处理
聊天流的好处是能多轮追问,但这也带来了新问题:第二轮提问时,上一轮的搜索结果会留在上下文里,容易造成混乱。我做了个比较笨但有效的处理:每个新问题进来时,都让意图解析节点先修正上下文,把“上一轮已经回答过”的信息压缩成一句话埋进新提示词,而不是让模型读完整历史。
实测下来效果不错,连续问三个相关问题时,模型能区分哪些信息是新搜索来的,哪些是之前已经确认过的,不会答非所问。Dify 的对话历史变量在这里起了很大作用,建议认真研究一下它的作用域和生命周期。
5. 这套工作流还能怎么玩:扩展与进阶
5.1 定时监控与自动入库
研究助手模式搭好之后,最自然的扩展是“定时监控”。Dify 的定时触发能力可以实现这种场景:每天早上自动搜一遍你关注的竞品动态或行业关键词,抓取文章,汇总出一份简报推送给你。配合知识库流水线,还可以把每天抓取的优质内容自动写入知识库,形成个人专属资料池,越用越聪明。
我已经开始这样玩了,本质上就是把一次性的“研究”变成习惯性的“监视”。时间久了积累下来的知识库,再配合问答系统,就是一套私有版的行业情报中心。
5.2 与其他工具的联动
Dify 的开放接口让这套工作流能很方便地嵌进其他系统。比如把工作流发布为 API 后,接到企业微信机器人里,同事在工作群里直接 @ 机器人发问题,就能收到研究报告。群机器人的问题往往五花八门,正好是这套链路最擅长的场景。
搜索范围也不局限于百度。FireCrawl 本身支持抓任意网页和搜索源,你可以并行加一个技术社区搜索、博客搜索,多个源的结果在综合分析节点里做交叉验证,结论会更扎实。注意控制并发数量,别让 FireCrawl 同时请求太多页面,容易被限流。
5.3 关于版本更新的提示
Dify 更新频率快,如果你用的是旧版本,建议升级后先跑一遍现有工作流,确认节点行为没有变化再继续生产使用。我遇到过升级后自定义工具的鉴权 Header 格式变了,导致 HTTP 请求 401,排查了半小时才发现是版本兼容问题。多看更新日志,升级前先备份数据库和 docker-compose 配置,稳字当头。
最后分享一点个人心得
这套工作流跑通之后,我最大的体会是:研究助手真正难的不是模型能力,而是流程设计。模型再聪明,上游搜索乱七八糟、抓取断断续续,输出一样一塌糊涂。Dify 的价值就在于把流程可视化,让每一步都能人工干预和调试。我建议刚上手的朋友别急着追新功能,先把自己最常用的一个研究场景完整跑通,哪怕一开始丑一点、慢一点,等链路通了再逐步优化也不迟。搜索引擎和抓取服务还会有更多新选择,但只要流程骨架搭对了,后面换工具、加来源都是顺手的事。