华为云Flexus+DeepSeek征文|Dify 构建企业级联网搜索 Agent:查询改写、多源检索与引用溯源实战

一、引言:为什么你需要一个"会搜会引"的 Agent

大模型的知识是"静态"的------它的训练数据截止于某个时间点,无法回答"昨天发布的新版本有什么变化""本月发生的行业事件"这类时效性问题。更麻烦的是,模型在不确定时会一本正经地编造:把不存在的 API 参数写得像模像样,把过时的接口路径当成现役标准。这就是行业里常说的"幻觉"(Hallucination)。

解决这个问题的主流方案是 RAG(检索增强生成),但传统 RAG 只检索私有知识库,覆盖的是企业内部文档。当问题超出知识库范围------比如竞品动态、最新法规、技术趋势------检索器就"无米下锅"了。

联网搜索 Agent (Web Search Agent)正是为补上这块拼图而生:它把搜索引擎当作动态知识源,让大模型在回答前先"上网查证",再基于检索结果组织答案,并逐条标注引用来源。这不只是把搜索 API 接到对话里那么简单,一套生产级方案要解决四个关键问题:

  1. 查询改写:用户口语化提问如何变成搜索引擎友好的查询词?
  2. 多源检索:单一搜索源覆盖率不够、结果质量不稳定怎么办?
  3. 相关性过滤:搜索结果鱼龙混杂,如何只保留高质量片段?
  4. 引用溯源:回答的每一句话,如何回追到可验证的来源?

本文基于华为云 MaaS 平台的 DeepSeek-V3/R1 商用推理服务 + Flexus X 实例一键部署的 Dify 平台,从零构建一个带引用溯源的企业级联网搜索 Agent。全文约 5500 字,所有工作流节点配置、Prompt 模板和 Python 代码均可直接复用,希望帮你建立一套属于自己的搜索 Agent 工程方法论。

本文为华为云 Flexus+DeepSeek 征文投稿,基于 MaaS 平台 DeepSeek 商用服务与 Flexus X 一键部署 Dify 方案的真实开发实践整理。


二、整体架构:搜索 Agent 的四层流水线

在动手之前,先明确目标形态。我们要构建的联网搜索 Agent,输入是用户的一句话提问,输出是一段123 角标引用、文末附来源列表的回答。它跑在 Dify 工作流(Workflow)上,整体是一条四层流水线:

复制代码
用户提问
   │
   ▼
┌─────────────────────────────────────────────────┐
│ 第 1 层:查询理解与改写(LLM 节点)                 │
│ 口语 → 结构化查询:主查询 + 时间限定 + 关键词扩展    │
└──────────────────────┬──────────────────────────┘
                       ▼
┌─────────────────────────────────────────────────┐
│ 第 2 层:多源检索(代码节点 / HTTP 节点)           │
│ 搜索引擎A ─┐                                      │
│ 搜索引擎B ─┼─→ 合并去重 → 片段切分 → 打分排序       │
│ 内部知识库 ┘                                      │
└──────────────────────┬──────────────────────────┘
                       ▼
┌─────────────────────────────────────────────────┐
│ 第 3 层:相关性重排(LLM 节点)                    │
│ 逐条判断:与问题相关?来源权威?时间是否过时?      │
└──────────────────────┬──────────────────────────┘
                       ▼
┌─────────────────────────────────────────────────┐
│ 第 4 层:生成与溯源(LLM 节点 + 模板)             │
│ 基于入选片段回答,句末标注 [n],文末附来源清单      │
└─────────────────────────────────────────────────┘
                       ▼
                   带引用的回答

这套流水线有两个设计要点:

  • 每一层都是独立节点,可以单独调试、单独替换。比如第 2 层今天接的是搜索引擎 A,明天想换成自建检索服务,只改一个节点。
  • 第 3 层重排是灵魂。很多搜索 Agent 效果差,不是模型不行,而是"垃圾进、垃圾出"------搜索结果没过滤就塞给大模型,模型再强也答不好。重排层决定了回答质量的上限。

三、地基:MaaS DeepSeek 接入与 Flexus X 上的 Dify

3.1 开通 MaaS 商用推理服务

华为云 ModelArts Studio(MaaS)平台提供 DeepSeek-V3/R1 的商用级推理服务,按 token 计费、开箱即用。开通流程三步走:

  1. 登录华为云控制台,进入 ModelArts Studio 的"模型推理-在线推理"模块;
  2. 选择"商用服务",开通 DeepSeek-V3(通用对话/工具调用)和 DeepSeek-R1(复杂推理/数学代码)两个模型;
  3. 在"API 凭证"页获取 API Key 与 Endpoint 地址。

MaaS 提供 OpenAI 兼容接口,这意味着一行代码即可替换调用端:

复制代码
from openai import OpenAI

client = OpenAI(
    api_key="your-maas-api-key",
    base_url="https://infer-modelarts.xxx.myhuaweicloud.com/v1"
)

resp = client.chat.completions.create(
    model="DeepSeek-V3",
    messages=[{"role": "user", "content": "你好"}],
    temperature=0.3,
)

在我们这套架构中,DeepSeek-V3 负责查询改写、相关性判断、回答生成 (它指令遵循能力强、延迟低),DeepSeek-R1 负责复杂推理型问题(比如"比较两家云厂商最新定价策略的差异"),通过 Dify 的模型路由按需切换。

3.2 Flexus X 一键部署 Dify

Dify 是开源的 LLM 应用开发平台,提供可视化工作流编排、知识库、Agent、观测等能力。使用华为云"快速搭建 Dify-LLM 应用开发平台"方案,在 Flexus X 实例上可以分钟级完成部署:

复制代码
# 拉取部署方案(华为云实现中心一键部署,也可手动 docker compose)
git clone https://github.com/huaweicloud/dify-deploy-solution.git
cd dify-deploy-solution

# 1. 准备环境变量(填 MaaS 的 key 与 endpoint)
cp .env.example .env
sed -i 's/^OPENAI_API_KEY=.*/OPENAI_API_KEY=your-maas-key/' .env
sed -i 's|^OPENAI_API_BASE=.*|OPENAI_API_BASE=https://infer-modelarts.xxx.myhuaweicloud.com/v1|' .env

# 2. 启动整套服务(API/Worker/Web/DB/Redis/向量库)
docker compose up -d

# 3. 验证
curl -s http://localhost/health | jq .

Flexus X 实例的柔性算力配置让资源选型很灵活:我们的搜索 Agent 属于 IO 密集 + 轻计算负载,选 4vCPU/8GB 规格即可;如果后续要接向量检索做"联网+私有知识库"混合问答,再平滑升配到 8vCPU/16GB。相比固定配比的传统规格,这种"按需柔性"在成本上更可控------测试期用完即可降配或释放,避免资源闲置浪费。

成本提醒:一键部署方案为按需计费,开通即计费,测试完毕务必删除资源,避免产生非预期费用。

3.3 在 Dify 中配置模型供应商

在 Dify 后台「设置-模型供应商」中新增 OpenAI-API-Compatible 供应商,填入:

配置项
API Key MaaS 平台获取的密钥
API Base URL MaaS 的 OpenAI 兼容 Endpoint
模型 DeepSeek-V3 / DeepSeek-R1(按需勾选)

配置完成后,Dify 工作流的 LLM 节点即可直接选用这两个模型,后续所有 Prompt 工程都在可视化界面里完成。


四、核心组件一:查询改写(Query Rewriting)

4.1 为什么不能直接拿用户原话去搜

用户在对话框里的表达和搜索引擎能消化的查询,完全是两种语言:

用户原话 问题
"那个华为新出的服务器咋样?" 口语化、指代不明(哪个服务器?)
"2026 年 AI 芯片市场格局" 缺少时间限定,搜出来一堆旧文
"帮我查查 DeepSeek 最近有啥动作" 意图模糊(发布?融资?开源?)

直接把原话丢给搜索引擎,召回结果往往答非所问。查询改写的目标,是把模糊的用户意图翻译成 1-3 条高质量查询词

4.2 改写 Prompt 设计

在 Dify 工作流中新建一个 LLM 节点,模型选 DeepSeek-V3,使用如下系统提示词:

复制代码
你是一名搜索查询专家。你的任务是把用户的问题改写为适合搜索引擎的查询。

要求:
1. 输出 1-3 条查询,每条一行,不要编号
2. 如果原问题包含口语词,改写为标准书面表达
3. 补充必要的限定词:时间(如"2026年")、地域(如"中国市场")、对象全称
4. 如果问题涉及对比(A vs B),分别输出针对 A 和 B 的查询
5. 只输出查询语句本身,不要任何解释

用户问题:{{question}}

示例效果:

复制代码
用户:那个新的云服务器比老的好在哪?
改写:
2026年 华为云 Flexus X 实例 与 上一代云服务器 对比
Flexus X 实例 性能 优势 评测

4.3 时间感知改写(进阶)

对于时效性问题,可以在改写时注入"当前时间",让模型自动加时间限定:

复制代码
当前日期:{{current_date}}(由 Dify 的"当前时间"节点注入)

规则:如果用户问题涉及"最新""最近""今年"等时效词,在查询中追加
"{{current_date 所在年份}}";如果问题本身带明确时间,保留原时间。

这一步能显著提升时效性问题的召回质量------搜索"2026年AI芯片市场格局"和搜索"AI芯片市场格局",返回的结果时效性完全不同。


五、核心组件二:多源检索(Multi-Source Retrieval)

5.1 为什么要多源

单靠一个搜索引擎,结果集通常存在三个问题:

  • 覆盖盲区:技术问答类内容在开发者社区(CSDN、GitHub、Stack Overflow)质量最高,但通用搜索引擎排序未必优先;
  • 时效滞后:搜索引擎索引有延迟,最新发布的信息搜不到;
  • 单一偏见:某搜索引擎对某些站点降权或过滤,导致系统性漏检。

多源检索的做法是:同时查询 2-3 个互补源,合并去重后再统一打分。我们的方案采用"搜索引擎 + 开发者社区 API + 内部知识库"三源结构:

类型 覆盖优势
源 A:Bing Web Search API 通用网页搜索 广覆盖、时效好
源 B:CSDN / GitHub 搜索 垂直社区搜索 技术内容质量高、代码可执行
源 C:Dify 知识库(可选) 向量检索 企业内部资料、私有文档

5.2 代码节点实现多源检索

Dify 的"代码节点"(Python 3)里可以并发调用多个搜索源。核心实现:

复制代码
import requests, json, hashlib

def search_bing(query, key, count=5):
    """Bing Web Search API"""
    url = "https://api.bing.microsoft.com/v7.0/search"
    r = requests.get(url, params={"q": query, "count": count},
                     headers={"Ocp-Apim-Subscription-Key": key}, timeout=8)
    return [{"title": x["name"], "url": x["url"],
             "snippet": x.get("snippet", ""),
             "source": "bing"} for x in r.json().get("webPages", {}).get("value", [])]

def search_github(query, token, count=5):
    """GitHub 仓库/代码搜索"""
    url = "https://api.github.com/search/repositories"
    r = requests.get(url, params={"q": query, "per_page": count},
                     headers={"Authorization": f"token {token}"}, timeout=8)
    return [{"title": x["full_name"], "url": x["html_url"],
             "snippet": (x.get("description") or ""),
             "source": "github"} for x in r.json().get("items", [])]

def main(query: str, bing_key: str, gh_token: str) -> dict:
    """并发调用多源,合并去重后输出"""
    import concurrent.futures
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as ex:
        f1 = ex.submit(search_bing, query, bing_key)
        f2 = ex.submit(search_github, query, gh_token)
        bing, github = f1.result(), f2.result()
    # 合并 + 按 URL 去重(保留第一个出现的结果)
    seen, merged = set(), []
    for item in bing + github:
        h = hashlib.md5(item["url"].encode()).hexdigest()
        if h in seen:
            continue
        seen.add(h)
        merged.append(item)
    # 简单切分:片段超过 300 字符则截断
    for it in merged:
        it["snippet"] = it["snippet"][:300]
    return {"results": json.dumps(merged, ensure_ascii=False)}

要点说明:

  • 并发而非串行 :多源检索的目的是"快",用 ThreadPoolExecutor 让各源并行查询,总耗时≈最慢的源;
  • 按 URL 去重:不同源可能返回同一篇文章,用 URL 的 MD5 去重,避免重复内容撑爆上下文;
  • 超时兜底:每个请求 8 秒超时,某源故障时自动跳过,不让单点拖垮整体。

5.3 可选:接入内部知识库

如果希望 Agent 在"联网查不到"时回退到企业内部资料,把 Dify 知识库的检索结果也并入合并列表即可。Dify 的知识检索节点支持 Rerank 模型,与联网结果统一进入第 3 层重排,实现"外部公网 + 内部私网"的混合检索------这也是活动的加分方向(企业知识库 + 联网搜索助手的组合能力)。


六、核心组件三:相关性重排(Re-ranking)

6.1 为什么需要重排

多源合并后的结果可能有 10-15 条,但真正与用户问题相关的可能只有 3-4 条。搜索引擎的排序逻辑(PageRank、点击率等)与"是否回答得了当前问题"不是一回事。直接全量塞给大模型,有两个坏处:

  1. 上下文污染:不相关片段会干扰模型判断,甚至被错误引用;
  2. Token 成本浪费:每多塞 1000 token,生成成本就高一分。

重排层的职责:逐条打分,只保留高相关片段

6.2 LLM 重排 vs 向量重排

方式 优点 缺点
LLM 重排(DeepSeek-V3) 理解语义、能判断"是否回答了问题" 慢(每条都要过模型)、贵
向量 Rerank 模型 快、便宜 只做语义相似度,不理解"问题意图"

生产实践中常用两段式:先用便宜的向量/BM25 粗筛(Top 20 → Top 10),再用 LLM 精排(Top 10 → Top 4)。本文演示 LLM 精排,因为它还能顺带完成"时效性判断"和"来源权威性判断",一举三得。

6.3 重排 Prompt 模板

复制代码
你是搜索结果评估专家。请判断以下搜索结果是否与用户问题相关,并打分。

用户问题:{{question}}

判断标准:
- 相关度(0-10):是否直接回答了问题或包含关键信息
- 时效性(0-10):信息是否过时(问题涉及时效则权重加倍)
- 权威性(0-10):来源是否可信(官方文档>技术社区>个人博客>营销软文)

输出格式(严格 JSON):
{"items": [{"index": 0, "score": 8.5, "keep": true, "reason": "一句话理由"}]}

只保留 score >= 7 的结果,其他 keep 设为 false。

搜索结果:
{{search_results}}

在 Dify 中,这个 LLM 节点的输出接一个代码节点解析 JSON,过滤出 keep=true 的条目,拼装成"精选片段列表",供第 4 层生成使用。


七、核心组件四:回答生成与引用溯源

7.1 生成时如何"绑定"引用

这是搜索 Agent 与普通 RAG 问答最大的区别:回答必须可验证。实现方法是给每个入选片段分配一个稳定编号,并要求模型在回答中显式引用:

复制代码
系统提示词(关键部分):

你将基于下面的"参考资料"回答用户问题。规则:
1. 每个参考资料有固定编号 [1][2][3]...
2. 回答中引用某个资料时,在该句末尾标注对应编号,如"......华为云Flexus X实例采用柔性算力架构[1]"
3. 一个句子若综合多个资料,标注多个编号,如 [1][3]
4. 参考资料中没有的信息,明确回答"资料中未提及",禁止编造
5. 回答最后附"参考资料"列表:编号 + 标题 + URL

参考资料:
[1] 标题:xxx | URL:https://... | 内容:...
[2] 标题:xxx | URL:https://... | 内容:...

用 Dify 的"模板节点"把精选片段自动格式化为上面的 [n] 编号格式,再传给 LLM 节点。编号与 URL 的映射在模板节点中固化,生成节点只负责引用编号,这样无论模型怎么发挥,来源列表都不会出错。

7.2 防幻觉的兜底设计

光有提示词还不够,还要加两道工程兜底:

  1. 无引用惩罚 :工作流里加一个"后处理代码节点",正则检查回答中是否包含 \[\d+\] 引用标记。若完全无引用,说明模型在自由发挥,直接丢弃该回答、改用更保守的模板:"抱歉,未能检索到足够可信的资料"。

    import re
    def main(answer: str) -> dict:
    has_ref = bool(re.search(r"\d+", answer))
    return {"pass": has_ref, "answer": answer if has_ref else ""}

  2. 来源白名单:在重排层对 URL 域名做白名单加权(官方文档域名加分),对营销软文域名降权,从源头降低被低质内容污染的概率。

7.3 复杂问题路由到 R1

当问题属于"多条件对比、数学计算、逻辑推理"类型时,把问题交给 DeepSeek-R1(思维链推理更强):

复制代码
路由规则(放在工作流的条件分支节点):
- 若问题包含"对比/区别/差异/哪个更好/为什么" → 走 R1 推理分支
- 否则 → 走 V3 快速回答分支

R1 分支在生成时额外注入一条指令:"请先梳理对比维度,再基于参考资料逐维度对比,每个维度结论后标注引用编号。"R1 的长思维链在这里的价值是:把"搜索到的零散事实"组织成"结构化的对比结论",而不是罗列一堆互相矛盾的片段。


八、端到端工作流编排与效果演示

8.1 Dify 工作流节点清单

把以上组件在 Dify 可视化画布中串起来,完整节点清单如下:

序号 节点类型 作用
1 开始 接收用户输入 question
2 当前时间 注入 current_date(供时效改写)
3 LLM 查询改写(DeepSeek-V3)
4 代码 多源检索(Bing + GitHub,并发 + 去重)
5 代码 片段切分与格式化
6 LLM 相关性重排(DeepSeek-V3,输出 JSON)
7 代码 解析重排结果,过滤低分条目
8 模板 生成带 n 编号的参考资料块
9 条件分支 复杂问题路由(V3 / R1)
10 LLM 生成回答(带引用标注)
11 代码 引用校验(无引用则兜底)
12 结束 返回最终回答 + 参考资料列表

8.2 实测效果

在 Flexus X 实例部署的 Dify 平台上,对搜索 Agent 进行一组典型测试:

提问:"2026 年上半年,国产大模型市场有哪些值得关注的新发布?"

改写层输出

复制代码
2026年上半年 国产大模型 新发布 盘点
2026年 中国 大模型 厂商 发布 汇总

重排后保留的片段 (示意):

  • 1 来源:某科技媒体 2026-06 报道《上半年国产大模型发布盘点》

  • 2 来源:某厂商官网公告(2026-05)

  • 3 来源:CSDN 技术社区讨论帖(2026-06)

最终回答(节选):

2026 年上半年国产大模型市场保持高密度发布节奏。基础模型层面,多家厂商在长上下文与推理效率上展开竞争,例如某厂商于 5 月发布的旗舰模型将上下文窗口提升至 256K2;开源生态方面,社区对轻量化小模型的关注度明显上升1。值得注意的是,行业重心正从"参数竞赛"转向"推理成本与落地效率",多家厂商同步发布了配套的推理优化工具链3。资料中未提及具体市场份额数据,如需该数据可进一步检索行业报告。

可以看到:每个结论都有编号对应,无法证实的部分明确标注"资料中未提及"------这正是联网搜索 Agent 区别于"裸聊大模型"的核心价值。

8.3 延迟与成本实测参考

阶段 耗时(参考) 说明
查询改写 ~0.8s V3 短输出,一次调用
多源检索 ~1.5s 并发执行,受最慢源限制
相关性重排 ~2.0s 10 条片段逐条判断
回答生成 ~3-5s 流式输出,与答案长度相关
端到端 ~8-10s 首次回答延迟(不含流式渲染)

成本侧,一次完整问答的 token 消耗约为:改写 200 + 重排 1500 + 生成 1500 ≈ 3200 token(含输入输出),按 MaaS 商用服务单价折算单次问答成本在几分钱量级------这也是"MaaS 按量付费"模式在搜索 Agent 这类"低频但高质量"场景下的成本优势。


九、踩坑指南:四个高频问题

9.1 搜索结果"答非所问"

现象 :改写后的查询与原问题偏离。

排查:先单独看改写层输出------这是 Dify 工作流可观测性的用武之地,每个节点都能看到输入输出。若改写失败,多半是 Prompt 中示例不足,给改写节点补充 2-3 个"口语→查询"的 few-shot 示例即可。

9.2 引用编号错乱

现象 :回答中的 1 与文末来源对不上。

根因 :生成节点直接拿到了原始列表,而不是编号格式化后的模板。

修复:确保生成节点只读取"模板节点"的输出,且模板节点中编号与 URL 的映射顺序保持稳定(不要在同一工作流里对列表排序)。

9.3 某搜索源频繁超时

现象 :端到端延迟飙到 30s+。

根因 :某源 API 不稳定,拖慢整体。

修复:代码节点中给每个源独立 try/except,超时直接返回空列表并记录日志;同时把"并发数"与"超时时间"设为工作流变量,便于线上调参。

9.4 回答太长、超出预算

现象 :生成 token 超支。

修复 :在 LLM 节点设置 max_tokens 上限(如 1500),并在提示词中限定"回答控制在 300 字以内,结论先行"。对搜索问答场景,短而准 远胜于长而全


十、总结与延伸

本文基于华为云 MaaS 平台的 DeepSeek 商用推理服务和 Flexus X 一键部署的 Dify 平台,从零构建了企业级联网搜索 Agent。回顾四个核心组件:

  1. 查询改写------把口语翻译成搜索引擎听得懂的话,附时间感知;
  2. 多源检索------通用搜索 + 垂直社区 + 内部知识库,并发合并去重;
  3. 相关性重排------LLM 逐条打分,只留高相关、高时效、高权威的片段;
  4. 引用溯源------编号绑定来源,无引用即兜底,让回答可验证、可追溯。

这套架构的最大价值不是"能上网搜",而是**"每一步都可观测、可替换、可兜底"**------每一层都是独立节点,出了问题能精确定位;每一层都有降级方案,单点故障不会拖垮整体。

延伸方向(也是继续探索的空间):

  • 联网 + 私有知识库混合问答:把 Dify 知识库检索并入多源层,实现"公网查证 + 私网补全";
  • 搜索记忆与追问:接入对话历史,让 Agent 能基于上文追问("再具体说说第二家的方案");
  • 定时自动检索:用 Dify 的定时触发能力,让 Agent 周期性抓取竞品动态并生成摘要报告;
  • 结果聚类与去重增强:引入向量聚类,把多个来源对同一事件的报道合并成"综合结论",减少信息冗余。

搜索 Agent 的工程本质,是在"模型的生成能力"和"世界的实时信息"之间架一座可验证的桥。桥的每一根梁柱------改写、检索、重排、溯源------都是可以独立打磨的工程组件,也是拉开普通 Demo 与生产系统差距的地方。


DeepSeek 实战指南系列 🔗 从零手写 DeepSeek 推理优化 | MaaS 平台 DeepSeek 部署全攻略 | DeepSeek R1 + Dify Agent 企业级实战

Dify 实战系列 🔗 Dify 知识库问答 Agent 从零搭建 | Flexus X 实例性能深度评测

相关推荐
江苏汉软1 小时前
汉软 MES解决方案引领航空航天制造精准智造新时代
人工智能·制造
七夜zippoe1 小时前
DolphinDB 能耗统计分析实战:报表生成、同比环比与定额对比
人工智能·算法·dolphindb·报表生成·能耗统计·定额对比
云端漫步19871 小时前
HarmonyOS NEXT AI 智能生活助手:AI 待办事项生成
人工智能·华为·生活·harmonyos
武子康1 小时前
开放权重不是唯一控制权:Kimi K3、Tencent Hy3 与 ByteDance Seed 的九项交付比较
人工智能·llm·agent
Zzj_tju1 小时前
Instruction Tuning 论文精读路线:从 Supervised Fine-Tuning 到 Instruction Following
人工智能·笔记·学习·语言模型·自然语言处理
2601_960906721 小时前
AI研发加速中式及泛亚洲
人工智能·vscode·macos·sublime text·phpstorm
为啥全要学1 小时前
在大语言模型上使用 PPO 算法
人工智能·算法·语言模型
studyrunner1 小时前
【AI开源】Buzz 实战教程:搭建人类与多 AI Agent 协同工作的自托管工作区
人工智能·开源