当前位置: 首页 > news >正文

从零搭建:基于Dify工作流整合Ollama与DeepSeek-R1的联网搜索助手

1. 为什么你需要一个自己的联网搜索助手?

不知道你有没有过这样的经历:想查一下最新的技术动态,比如“2024年AI大模型有哪些新突破”,结果问了一圈AI助手,得到的回答要么是几个月前的旧闻,要么就是含糊其辞,因为它“不知道”今天发生了什么。或者,你想规划一次旅行,需要最新的酒店价格和景点开放信息,却发现AI给出的建议可能已经过时了。这就是传统大语言模型最大的痛点——它们被“困”在了训练数据截止的那个时间点,无法获取实时的、动态的网络信息。

这就像你有一个知识渊博但足不出户的朋友,他脑子里装满了2023年以前的百科全书,但对于窗外正在发生的世界,他一无所知。为了解决这个问题,我们通常需要手动打开浏览器搜索,再把结果复制粘贴给AI,过程繁琐又割裂。有没有一种方法,能让AI自己学会“上网”,实时获取信息并为你分析和总结呢?

当然有,而且今天我们就可以亲手搭建一个。这个方案的核心,就是结合三个强大的工具:DifyOllamaDeepSeek-R1,再通过BochaWebSearch这个搜索工具,为AI装上“眼睛”和“耳朵”。Dify是一个低代码的AI应用开发平台,你可以像搭积木一样,用可视化工作流把各个模块连接起来;Ollama让你能在自己的电脑上轻松运行各种开源大模型;而硅基流动提供的DeepSeek-R1,则是一个能力非常强悍的云端模型。最后,BochaWebSearch负责执行联网搜索,把最新的网页内容抓取回来。

我试过不少方案,有的配置复杂,有的费用高昂。而今天要分享的这套组合,最大的优点就是灵活、可控且成本友好。你既可以使用本地的Ollama模型保护隐私,也可以调用强大的云端模型处理复杂任务,还能根据需求随时切换。整个过程几乎不需要写代码,跟着步骤一步步来,小白也能轻松上手。接下来,我就带你从零开始,一步步搭建这个属于你自己的、具备实时信息获取能力的AI搜索助手。

2. 搭建前的准备:环境与账号配置

万事开头难,但准备工作做得好,后面就一路顺畅了。在开始拖动Dify工作流中的节点之前,我们需要先把几个核心“演员”请到舞台上,并给它们安排好位置。

2.1 部署与登录Dify

Dify是我们的“指挥中心”,所有工作流都在这里编排。首先,你需要一个Dify服务。最方便的方式是使用Dify官方提供的云服务,直接注册账号即可。如果你想完全掌控在自己手里,也可以在本地通过Docker部署。这里以本地部署为例,因为它更灵活,且没有网络限制。

假设你已经安装好了Docker和Docker Compose,那么部署Dify就是一行命令的事。打开你的终端,进入一个你喜欢的目录,然后执行:

git clone https://github.com/langgenius/dify.git cd dify/docker docker-compose up -d

等待一阵子,当终端不再滚动新的日志时,就说明部署成功了。接下来,在浏览器中输入http://localhost或者http://127.0.0.1,就能看到Dify的登录界面。第一次访问会进入初始化设置页面,按照提示创建管理员账号即可。

登录成功后,你会进入Dify的主仪表盘。这里就是我们未来创作所有AI应用的大本营。我建议你先花几分钟熟悉一下界面,左侧是导航栏,包括“应用”、“工作流”、“知识库”等核心功能。我们这次的重点,就在“工作流”里。

2.2 配置模型供应商:本地Ollama与云端DeepSeek

模型是我们AI助手的大脑。在这个项目里,我们准备了两颗“大脑”:一颗是本地的,一颗是云端的。这样设计的好处是,你可以根据任务需求灵活切换。处理一些简单的、对隐私要求高的查询,用本地模型;需要强大推理和复杂总结时,就调用云端模型。

首先,配置本地的Ollama。确保你已经在电脑上安装并运行了Ollama。安装过程非常简单,去Ollama官网下载对应系统的安装包,一路下一步就行。安装完成后,在终端里运行ollama run qwen2.5:7b这样的命令,就可以拉取并运行一个模型。Ollama默认的服务地址是http://127.0.0.1:11434

回到Dify,点击左下角的“设置”图标,进入“模型供应商”页面。点击“添加模型供应商”,在列表里找到“Ollama”。在配置页面,唯一需要填写的就是“基础URL”,这里就填入http://127.0.0.1:11434。如果你的Ollama服务跑在另一台机器上,就填写那台机器的IP地址和端口。配置完成后,点击“保存”,Dify就能识别到你本地的Ollama服务了。之后,你就可以在“模型”选项里看到你本地已经拉取的所有模型,比如qwen2.5:7bllama3.2等等。

接着,配置云端的硅基流动DeepSeek。硅基流动是一个提供多种主流模型API服务的平台,DeepSeek-R1是其中性能非常突出的一个模型。首先,你需要访问硅基流动的官网注册一个账号。注册完成后,在个人中心找到“API密钥”管理页面,创建一个新的API Key,并妥善保存下来,它只会显示一次。

回到Dify的“模型供应商”页面,这次选择“硅基流动”。在配置界面,将你刚才复制的API Key粘贴到“API密钥”栏位。其他参数通常保持默认即可。保存之后,Dify就具备了调用DeepSeek-R1模型的能力。这样,我们的“双核大脑”就配置完毕了。在实际工作流中,我们可以自由选择使用哪一个,甚至可以根据条件判断来动态切换,这体现了Dify工作流设计的强大之处。

3. 为助手注入“眼睛”:集成BochaWebSearch工具

模型大脑准备好了,但它还缺少感知外界信息的能力。接下来,我们要集成一个关键的联网搜索工具——BochaWebSearch。你可以把它理解为AI助手的“眼睛”和“搜索引擎”,它负责根据用户的问题,去互联网上抓取最新、最相关的网页内容。

BochaWebSearch提供了清晰的API接口,我们需要将其以“自定义工具”的形式接入Dify。这样,在工作流中,它就能像一个标准的积木块一样被我们调用。这个过程听起来有点技术性,但跟着我做,其实很简单。

首先,在Dify左侧导航栏找到“工具”选项,点击进入后,选择“自定义工具”,然后点击“创建自定义工具”。这里我们需要填写一个OpenAPI格式的配置文档。别被这个词吓到,它其实就是用一种结构化的方式告诉Dify,这个工具叫什么、能做什么、需要什么参数、会返回什么结果。

你可以直接使用以下我提供的配置(这是一个简化版的示例,涵盖了核心功能):

openapi: 3.0.3 info: title: 博查搜索 description: 一个为AI应用提供的中文搜索引擎,能够从海量网页和生态内容源中获取高质量的世界知识。 version: 1.0.0 servers: - url: https://api.bochaai.com/v1 paths: /web-search: post: summary: 从博查搜索全网信息和网页链接,返回结果包括网页标题、URL、网页摘要、网站名称等。 operationId: BochaWebSearch requestBody: content: application/json: schema: type: object properties: query: type: string description: 搜索关键词或语句 summary: type: boolean description: 是否在搜索结果中包含摘要 default: true freshness: type: string description: 搜索指定时间范围内的网页 enum: [“noLimit”, “oneDay”, “oneWeek”, “oneMonth”, “oneYear”] default: “noLimit” count: type: integer description: 返回的搜索结果数量(1-10) default: 10 required: - query responses: ‘200’: description: 成功的搜索响应 content: application/json: schema: # 这里定义了返回数据的复杂结构,为了节省篇幅,结构描述从简。 # 核心是包含一个 `data.webPages.value` 的数组,里面有标题(name)、链接(url)、摘要(summary)等字段。

将上述YAML内容复制到Dify自定义工具的“Schema”配置框中。接下来,你还需要一个BochaWebSearch的API Key。前往其官网,注册账号并创建一个API Key,通常会有一定的免费额度供测试使用。在Dify工具配置的“认证”部分,选择“API Key”,并将密钥填入。记得在“Headers”中设置AuthorizationBearer <你的API Key>

配置完成后,点击“保存并测试”。你可以尝试输入一个简单的查询,比如“今天北京天气”,如果配置正确,你应该能看到返回的结构化搜索结果。至此,你的AI助手就拥有了“视力”,可以主动去互联网上寻找答案了。这个工具节点,将是我们工作流中至关重要的一环,它负责将用户的文字问题,转化为一堆富含信息的网页数据。

4. 构建核心工作流:像连接水管一样连接AI能力

工具和模型都就位了,现在进入最有趣的部分——用Dify的可视化工作流把它们“组装”起来。你可以把工作流想象成一个流水线,用户的问题像一颗原料,经过各个工位的处理,最终变成精美的答案成品。我们这次要搭建的流水线主要包含四个核心工位:开始->BochaWebSearch(搜索)->代码处理(格式化)->LLM(总结回答)->回复(输出)

4.1 创建工作流并设置初始节点

在Dify的“工作流”页面,点击“创建新的工作流”。给它起个名字,比如“我的联网搜索助手”。你会看到一个空白的画布,右侧是节点库。

首先,从节点库拖拽一个“开始”节点到画布上。这个节点代表用户输入的起点。选中它,在右侧配置面板,你可以看到一个“变量”区域。这里我们暂时不需要额外设置,因为用户的问题会通过{{#sys.query#}}这个系统变量自动传递进来。这个节点就像流水线的入口,原料(用户问题)从这里进入。

接下来,我们需要把“原料”送到搜索引擎去查找资料。从节点库找到“工具”分类,将我们刚刚配置好的“BochaWebSearch”节点拖到画布上,放在“开始”节点右侧。然后,从“开始”节点右侧的圆点(输出点)拖出一条线,连接到“BochaWebSearch”节点左侧的圆点(输入点)。这条线就建立了数据流动的通道。

选中“BochaWebSearch”节点进行配置。最关键的是query参数,这里我们需要填入{{#sys.query#}},这样用户输入的问题就会作为搜索关键词传递给Bocha。其他参数如freshness(新鲜度,比如只搜一天内的结果)、count(返回结果数量)可以根据你的需求调整,也可以先保持默认。这样,当工作流运行时,用户的问题就会触发一次真实的网络搜索。

4.2 用代码节点处理原始搜索结果

BochaWebSearch返回的数据是结构化的JSON,包含了标题、链接、摘要等丰富信息,但直接扔给大模型可能不够“整洁”。我们需要一个“预处理”工位,把这些原始数据整理成一段易于模型理解的上下文文本。

从节点库拖拽一个“代码”节点到画布,放在“BochaWebSearch”节点右侧。将两者的输出和输入连接起来。这个节点允许我们编写一小段Python代码,对上游节点的输出进行加工。

点击配置代码节点,语言选择“Python3”。我们需要编写一个函数,来提取和格式化搜索结果。以下是我调试后觉得比较好用的一个版本:

def main(resp: str) -> dict: import json try: response = json.loads(resp) # 层层解析返回的JSON结构,找到网页列表 if “data” in response: data = response[“data”] if “webPages” in data: webPages = data[“webPages”] if “value” in webPages: contexts = webPages[“value”] # 限制最多处理10条结果,避免上下文过长 max_context = min(len(contexts), 10) format_contexts = [] for i in range(max_context): # 将每条结果格式化为一个清晰的文本块,并加上引用编号 formatted_context = f“[[引用:{i+1}]]\n网页标题:{contexts[i][‘name’]}\n网页链接:{contexts[i][‘url’]}\n网页内容:{contexts[i][‘summary’]}\n发布时间:{contexts[i].get(‘dateLastCrawled’, ‘N/A’)}\n网站名称:{contexts[i].get(‘siteName’, ‘N/A’)}” format_contexts.append(formatted_context) # 用两个换行符连接所有格式化后的结果 context = “\n\n”.join(format_contexts) return {“context”: context} return {“context”: “暂无搜索结果”} except Exception as e: return {“context”: f“处理搜索结果时出错: {str(e)}”}

这段代码干了什么呢?它接收BochaWebSearch返回的原始响应(resp),然后像剥洋葱一样,解析出data -> webPages -> value这个数组。数组里的每个元素都是一条搜索结果。接着,它遍历这些结果(最多10条),把每条结果的标题、链接、摘要等信息拼接成一段规整的文字,并在开头加上[[引用:X]]的标记。最后,把所有格式化后的结果用空行隔开,合并成一个大的context字符串输出。

这个context字符串,就是经过清洗、整理后的“参考资料”,它将被喂给下一个工位——大语言模型。代码节点的输出变量名我们设置为context,后面会用到。

4.3 配置大语言模型节点进行智能总结

现在,我们有了用户的问题(sys.query)和丰富的网络参考资料(context),是时候请出我们的大脑——大语言模型来干活了。从节点库拖拽一个“LLM”节点到画布,放在代码节点右侧,并连接起来。

选中LLM节点,在配置面板的“模型”下拉框中,你可以看到之前配置好的Ollama和硅基流动的模型。这里我强烈推荐选择“siliconflow/deepseek-ai/DeepSeek-R1”。DeepSeek-R1在长文本理解、信息整合和遵循指令方面表现非常出色,特别适合处理我们这种“问题+多段参考资料”的输入场景。

模型选好后,最关键的是配置“提示词”。提示词就是指挥模型如何工作的指令。我们需要清晰地告诉它:你的角色是什么,你拥有哪些资料,以及你该如何回答。以下是一个经过精心设计的系统提示词示例,你可以直接复制使用:

# 角色 你是一个由博查搜索精心打造的 AI 搜索助手,能够在网络世界中精准搜索,并以中立客观、新闻式的专业语气为用户答疑解惑。 ## 技能 ### 技能 1: 精准响应用户提问 1. 当用户提出问题时,首先以一个单独的段落简洁直接地回答核心问题,随后通过若干独立的段落详细分析问题的各个方面和细节,确保答案完整且逻辑清晰。 2. 提供的答案应具备中等至较长的篇幅,信息量饱满且紧密关联,但切忌重复用户问题。 3. 结构化地拆解内容,明确表达内部的分类及逻辑关系,并以 markdown 格式提供详尽内容。 ### 技能 2: 在答案中适当地使用引用编号来引证上下文信息 1. 你将获得一组与该问题相关的上下文,每个上下文都以引用编号开头,例如 [[引用:x]],其中 x 是一个数字。请使用上下文进行参考作答,但无需显示引用的编号。 ### 技能 3: 不要盲目地重复上下文,提供扩展的见解和解释 1. 对上下文信息进行分析、综合和评价,提供更深入的见解和解释。 2. 融入你的专业知识和经验,以提供更丰富和有深度的答案。 3. 始终保持对用户问题的敏感度和对信息准确性的追求。 ## 限制 1. 禁止告知用户通过打开链接或访问网站获取答案,除非用户明确要求提供链接。 2. 必须基于上下文信息来回答问题并引用相关内容,然而无需在回应中提及上下文。 3. 只有在必要时,才使用无序列表、有序列表等格式。 4. 只有在必要时,才通过独立段落详细分析问题、总结关键点和主要信息。

接下来,在“用户提示词”部分,我们需要把变量“组装”进去:

以下是上下文: {{#1740023701313.context#}} 以下是用户提问: {{#sys.query#}}

注意,这里的1740023701313.context需要替换成你画布上那个“代码”节点的ID加上.context输出变量。你可以在代码节点的配置面板顶部找到它的ID(一串数字),替换上去即可。这样,模型就能同时看到网络搜索得到的上下文和用户的原始问题了。

最后,在“上下文”设置里,建议勾选“启用上下文”并设置一个合理的token限制(比如8000),以确保有足够的空间容纳搜索返回的长文本。温度(Temperature)参数可以设置为0.7,让回答既有一定创造性,又不会太天马行空。

4.4 完成闭环并测试

将LLM节点的输出,连接到最后一個“回复”节点。回复节点的配置很简单,在“答案”栏填入{{#llm.text#}},这意味着直接把LLM生成的文本作为最终答案返回给用户。

至此,整个工作流的骨架就搭建完成了。你的画布上应该有一条清晰的连线:开始 -> BochaWebSearch -> 代码 -> LLM -> 回复。现在,点击右上角的“保存”,然后点击“发布”。发布后,这个工作流就变成了一个可用的AI应用。

点击“预览”或直接访问应用链接,在聊天框里输入一个需要实时信息的问题,比如“帮我总结一下今天科技领域的主要新闻”。稍等片刻,你会看到助手首先会触发搜索(这可能需要几秒钟),然后基于搜索到的新闻链接,生成一份结构清晰、带有引用来源的总结报告。第一次看到它成功运行并给出带有时效性的答案时,那种成就感是非常棒的。

5. 进阶技巧与避坑指南

基础流程跑通后,我们可以玩点更花的,让这个助手变得更聪明、更强大。同时,我也分享几个我踩过的坑,帮你节省时间。

5.1 实现模型的热切换与路由

你可能会想:有时候问题简单,用本地Ollama模型快又省;有时候问题复杂,需要DeepSeek-R1出马。能不能自动判断?Dify工作流中的“条件判断”节点可以帮你实现。你可以在BochaWebSearch节点之后,添加一个“条件判断”节点。判断逻辑可以基于搜索结果的条数(如果结果很少,可能问题简单),或者基于用户问题的长度、关键词(例如包含“总结”、“分析”等词用DeepSeek)。然后,根据判断结果,将流程导向连接了Ollama模型的LLM节点分支,或者连接了DeepSeek-R1的LLM节点分支,最后再汇聚到同一个回复节点。这就实现了智能路由,让合适的模型处理合适的问题。

5.2 优化搜索策略与结果过滤

默认的搜索可能返回的信息比较杂。你可以通过调整BochaWebSearch节点的参数来优化。freshness参数非常有用,对于查询新闻、股价等时效性强的信息,设置为oneDay可以确保结果是最新的。count参数控制返回数量,不是越多越好,太多会导致上下文过长,影响模型处理速度和效果,一般5-10条足矣。

此外,你还可以在代码节点中增加更复杂的过滤逻辑。比如,只选择来自特定权威网站(如域名包含github.com,arxiv.org)的结果,或者根据摘要中的关键词进行排序和筛选。这需要你稍微修改一下之前的Python代码,增加一些条件判断。这样处理后的上下文质量更高,模型的回答也会更精准。

5.3 处理常见错误与稳定性保障

在实际使用中,可能会遇到一些问题。一个是搜索超时或失败。网络搜索API并不总是稳定的。为了提升体验,你可以在代码节点中加入异常捕获和重试机制,或者在工作流中添加一个“分支”:如果搜索节点返回错误,则直接跳过一个备用的LLM节点,让模型基于自身知识库回答,并告知用户“暂时无法获取实时信息”。

另一个是上下文过长。如果一次搜索返回了太多、太长的网页摘要,可能会超过模型的最大上下文长度。除了前面提到的限制结果数量,你还可以在代码节点中对每个摘要进行截断,比如只保留前200个字符。更高级的做法是,先让一个小模型(如Ollama上的小参数模型)对搜索结果进行初步筛选和摘要,再将精简后的上下文交给大模型做最终总结,这种“两级处理”模式效率更高。

最后,记得为你的应用设置一个友好的开场白,在Dify应用设置的“提示词编排”部分,可以写一句:“我是一个联网搜索助手,可以为您查询最新的网络信息。” 这能让用户立刻明白它的能力边界。经过这些优化,你的助手就不再是一个简单的原型,而是一个真正可靠、实用的生产力工具了。

http://www.cnnetsun.cn/news/1244182.html

相关文章:

  • SEER‘S EYE 预言家之眼部署指南:Ubuntu 20.04系统环境快速搭建
  • 黑丝空姐-造相Z-Turbo技术社区实践:在CSDN分享模型部署与创新应用
  • 扣子(Coze)案例教程:打造你的AI老黄历视频生成器
  • 若依权限系统集成PageOffice:实现前后端分离下的在线文档协同
  • LeagueAkari:提升英雄联盟游戏效率的开源工具解决方案
  • Canal vs mysql-binlog-connector:如何选择最适合你的MySQL数据同步方案?
  • Qml地图开发进阶(一):MapQuickItem与动态图元绘制
  • 仅限PHP 8.9.4+可用!基于JIT-aware mmap预加载的大文件随机读取方案(基准测试:seek延迟从42ms降至0.8ms)
  • 告别手动配置:使用CMake与VSCode构建现代化C++开发环境
  • 开源工具百度网盘直链解析实现满速下载的技术方案
  • 掌握NVIDIA Profile Inspector:从入门到精通的显卡参数调校指南
  • STM32G47x FDCAN外设配置与波特率计算实战指南
  • 别再只用饼图了!用Echarts旭日图可视化你的组织架构与预算分配
  • 突破游戏帧率限制:OpenSpeedy变速工具革新玩家体验,卡顿降低70%
  • PP-DocLayoutV3与Python爬虫结合实战:自动化文档解析与数据提取
  • 小白也能懂:Open-AutoGLM工作原理揭秘,截图-分析-执行三步走
  • Aspen Plus V14 从零到一:手把手安装指南与避坑实战
  • wan2.1-vae开源协议解读:Apache 2.0许可下商用/修改/分发边界说明
  • Navicat16/17数据库密码安全解析与实战解密指南
  • PotPlayer字幕翻译插件:突破语言壁垒的4个实战技巧
  • GPU显存友好型部署:Nano-Banana软萌拆拆屋SDXL优化实践
  • RNA Club | 解码CRISPR-Cas与噬菌体的进化博弈:从Anti-CRISPR机制到基因编辑新策略
  • Phi-4-reasoning-vision-15B保姆级教程:模型版本升级与向后兼容验证
  • RISC-V USB PD诱骗器:五档电压主动协商与高精度功率监测
  • Docker中MySQL连接Navicat报错2003排查指南:从容器状态到网络配置
  • RexUniNLU小白教程:3步完成用户评论批量情感分类
  • Z-Image-Turbo WebUI功能体验:预设尺寸、CFG调节、随机种子使用技巧
  • Android 12 蓝牙权限适配指南:从基础到实战
  • WuliArt Qwen-Image Turbo一文详解:BFloat16数值稳定性对文生图质量的影响
  • Z-Image-Turbo-rinaiqiao-huiyewunv保姆级教程:Streamlit容器边框设计与响应式布局技巧