Dify 深度玩法(四):RAG 做到什么程度才算到位
Dify 深度玩法(四):RAG 做到什么程度才算到位
上一篇:节点自定义的五个层级。 自托管 Dify 的 RAG 不是"上传文档然后问答",而是一条每一段都能调参的流水线,且没有云版的容量阉割。
全链路:入库与查询
平台能力是现成的。效果差异来自三个你自己做的决定:分块策略、检索模式、元数据设计。
效果的四层阶梯
| 层次 | 做出来的效果 | 依赖能力 |
|---|---|---|
| 1. 基础问答 | 回答带引用来源,知识库里没有就明确说不知道 | 混合检索 + 重排 + 阈值 |
| 2. 精准知识库 | 长文档问答不丢上下文;检索自动限定在某类文档 | 父子分段 + 元数据过滤 |
| 3. 可编程检索流水线 | 查询改写、分类路由、多库检索、生成前校验全部画进画布 | RAG 流水线 / Chatflow |
| 4. 外挂检索引擎 | Dify 只当编排层,检索打到你自己写的 API(ES、数据库、自建向量服务) | 外部知识库 API |
第 2、4 层是自托管的意义所在:云版免费额度装不下,而外部知识库接口意味着可以整体绕开内置向量库。
Dify 深度玩法(三):节点自定义的五个层级
Dify 深度玩法(三):节点自定义的五个层级
上一篇:部署选型与模型 Key。 进了画布,第一个问题是"这东西到底能改多深"。答案是分层看:参数、逻辑、数据流三层几乎不设限;节点类型可靠插件扩展;硬边界只有两处。
五个层级总览
L1 参数级:每个节点都有一层配置
- LLM 节点:每个节点独立选模型、独立调参数(温度、最大输出等),提示词模板可引用任意上游变量,支持结构化输出、视觉输入、会话记忆。
- 知识检索节点:可挂多个知识库,检索模式、返回条数、相似度阈值、重排模型逐项可配。
- 问题分类器 / 参数提取器:分类类别和抽取字段完全由你定义,抽取方式可选函数调用或提示词驱动。
这一层覆盖了八成日常需求,特点是"改配置不改逻辑"。
L2 逻辑级:两个万能逃生门
Code 节点(Python 3.10+ 或 Node.js 18+)负责任意数据变换。一个真实可用的例子——对抓取结果做归一化去重:
Dify 深度玩法(二):云版还是自托管?部署决策与模型 Key 清单
Dify 深度玩法(二):云版还是自托管?部署决策与模型 Key 清单
上一篇:Dify 适合做什么。 本篇回答第二个实际决策:在哪跑、接什么模型。
先澄清一个常见误解
很多人以为云版免费额度限制的是"调用量"。真实情况是:自带 API Key 的调用不消耗 Dify 的 message credits(credits 只在使用 Dify 内置供应商时消耗)。云版免费版(Sandbox)真正的瓶颈是:
| 维度 | 云版 Sandbox(免费) | 自托管 Community |
|---|---|---|
| 应用数 | 5 个 | 不限 |
| 知识库 | 50 篇文档 / 50 MB | 取决于你的磁盘 |
| 本地模型(llama.cpp / Ollama) | 访问不到你的 localhost | 容器内直连 |
| 费用 | 0(够用要升级到约 59 美元/月) | 0(电费与磁盘) |
| 维护 | 无 | 升级需读 release note、改环境配置后重启 |
结论很直接:多项目 + RAG 的组合,云版免费版装不下。应用数和知识库容量这两个上限,恰好卡在个人开发者的典型需求上。
三阶段部署路径
不建议二选一,建议分三步走:
第 1 步不要投入任何东西——云版只用来确认"画布的工作方式你是否接受"。第 2 步才是正式开发环境。第 3 步等真的要给别人用时再做,因为自托管应用可以导出 DSL 迁移,前期投入不会浪费。
Dify 深度玩法(一):它适合做什么,不适合做什么
Dify 深度玩法(一):它适合做什么,不适合做什么
本系列共五篇,基于 2026 年的 Dify(含新版 Agent 与 MCP 能力)整理自实际调研与项目设计。 这一篇先回答最容易被跳过的问题:什么项目该用 Dify,什么项目用了反而更慢。
一句话定位
Dify 是一个 LLMOps 平台:把「可视化编排 + 知识库 RAG + Agent + 一键发布(Web App / API / 嵌入组件)」装进同一个画布。它与 LangChain 这类代码框架的本质区别是——Dify 是产品,LangChain 是框架。框架给你最大自由,产品给你最快速度,代价是边界由平台划定。
三条判断标准
一个项目"适合 Dify",通常同时满足三条:
- 逻辑主体是 IO + 数据整形 + LLM 判断。抓数据、清洗、让模型打分或判定、输出文本——这条链路是 Dify 节点的母语。
- 需要快速拿到可调用的出口。你需要在几小时内拥有一个能点开的 Web App、一个 REST API、一个可嵌入的聊天组件,而不是先写两周前后端。
- 改提示词的频率远高于改代码的频率。Dify 上改一个 LLM 节点的 prompt 是秒级的,不需要重新发版。如果你的项目半年才改一次提示词,这个优势归零。
反过来,满足不了这三条的,用 Dify 通常更慢。下面这张决策图可以直接对着用:
场景对照表
| 场景 | 用 Dify | 原因 |
|---|---|---|
| 多源抓取 → 清洗 → LLM 打分 → 输出日报 | ✅ | 典型的 IO + LLM 链路,改数据源不动代码 |
| 文档知识库问答(RAG) | ✅ | 分块、检索、重排、引用都是现成节点 |
| 一次性深度调研报告生成 | ✅ | 多 Agent 分工 + 引用校验节点 |
| 需要快速给客户演示的垂直领域助手 | ✅ | Web App 与 API 一键发布 |
| 高频低延迟 API(P95 要求数百毫秒内) | ❌ | 每个节点都有额外开销与队列 |
| 视频渲染、大规模数值计算 | ❌ | 沙箱 30 秒超时 + 内存上限,干不了重活 |
| 复杂有状态业务流程(事务、回滚、幂等) | ❌ | 声明式分支表达不了状态机 |
| 逻辑需要严格 code review 与版本控制 | ⚠️ | 工作流导出为 YAML,diff 可读性差 |
关于"拖拉拽"的真实配比
一个常见误解是"用 Dify = 纯拖拽"。实际项目里有效的配比是约八成拖拽、两成 Code 节点:
Agent 开发实践:基于 simple-agent 的循环构建与工具调用
在 AI Agent 的开发中,一个健壮的 Loop 循环(Agent Loop)是其处理复杂任务的核心。simple-agent 作为一款轻量级框架,通过其简洁的接口将 LLM、工具(Tools)和状态(Context)有机结合。
本文将调研 simple-agent 的核心接口,构建一套完备的 Agent Loop 示例,并解析其背后的设计逻辑。
核心接口分析
simple-agent 的设计哲学是“去重型化”,其核心接口围绕着 Agent 类展开:
Agent()初始化:支持自定义 LLM 配置(通过 LiteLLM 支持 100+ 模型)、System Prompt 以及工具目录。run(task):单轮任务执行,适合一次性的问答或任务。chat(message):多轮会话管理,自动维护 Context 状态,这是实现“Agent 记忆”的关键。- Skills System:支持 Tier 1(元数据)到 Tier 2(指令)的渐进式加载,有效减少 token 消耗。
完备的 Agent Loop 示例
以下代码展示了一个具备工具调用与上下文感知的 Agent 运行逻辑:
from simple_agent import SimpleAgent
# 1. 初始化:设置模型与行为约束
agent = SimpleAgent(
model="openrouter/anthropic/claude-3.5-sonnet",
system_prompt="你是一个能够执行网络诊断的专业 AI 助理。",
enable_skills=True
)
# 2. 模拟真实 Agent Loop
def run_agent_loop(task: str):
print(f"--- 任务开始: {task} ---")
# 获取初始结果
response = agent.run(task)
# 3. 循环判断与迭代(模拟生产逻辑)
iterations = 0
while not response['success'] and iterations < 5:
print(f"迭代 {iterations}: 尝试自我修正...")
response = agent.chat("请根据之前的错误重新规划你的工具调用。")
iterations += 1
return response['result']
# 执行
result = run_agent_loop("检查 google.com 的连接性,并根据结果提供建议")
print(f"最终结果: {result}")
关键技术解读
1. 状态维持与“内存”
LLM 本身是无状态的,Agent 的“记忆”完全依赖于 SimpleAgent 类内部的对话历史管理。在 chat() 接口调用时,框架会自动把最新的交互追加到历史列表中,并重新作为整个上下文发送给 LLM。这种实现方式确保了 Agent 的一致性。
一份基座,N 套人格:LoRA 热插拔的原理、接口与真实成本
一份基座,N 套人格:LoRA 热插拔的原理、接口与真实成本
如果你曾经为"想要三个不同风格/不同领域的模型"而准备下载三份模型文件,那这篇文章能帮你省下大量磁盘、显存和等待时间。
核心结论先给出:一份基座模型 + 若干个几十 MB 的 LoRA 适配器,可以在运行时自由切换甚至叠加,不重启、不重新导出、不复制大文件。 在生产环境里,这套做法已经有人把每月的 GPU 成本从约 2.4 万美元降到约 1200 美元。
一、LoRA 是什么:给大模型贴一张"专用贴纸"
微调(Fine-tuning)传统上指:拿一份预训练模型,用你自己的数据继续训练,得到一份完整的新模型文件。问题很明显——一个 8B 模型就是 16 GB,你想要三个风格,就要存三份 48 GB,跑起来还要三份显存。
LoRA(Low-Rank Adaptation,低秩适配)的做法完全不同。它发现了一个经验规律:模型从"通用"变成"某个专用领域",权重需要改变的部分其实很少。于是它不动原来的权重,而是额外学两个很小的矩阵。
用数学写出来非常简单:
原始输出: y = x · W
加上 LoRA: y = x · W + scale · x · A · B
其中 W 是原来那个巨大的权重矩阵(冻结、不动),而 A 和 B 是两个"瘦长"的小矩阵。它们的尺寸是刻意设计成很窄的——中间那个很窄的维度就是 rank(秩),通常取 16 到 64。
它为什么能这么小?举个例子:一个 8B 模型在 rank 16 下的可训练参数约 1500 万,而模型本身有 80 亿冻结参数——你只训练了不到 0.2% 的参数,最终产物就是几千万个数字,落到磁盘上大约 40 MB(rank 16)。
让 2B 当侦察兵:投机解码的原理、实测数据与失效边界
让 2B 当侦察兵:投机解码的原理、实测数据与失效边界
上一篇我们提到,2B 小模型最"值钱"的用法之一是给大模型当草稿机。这个技术的正式名字叫投机解码(Speculative Decoding)。它的效果相当戏剧化:有人实测把 27B 模型的生成速度从 25 tok/s 提到 45 tok/s,也有人实测把 60 tok/s 掉到 45 tok/s——用的是同一个技术。
本文面向没有推理优化背景的读者,先讲清"为什么能加速",再讲清"为什么有时反而变慢",中间穿插多组真实实测数据。
一、先搞懂一个反直觉的事实:大模型生成慢,不是因为算不过来
这是理解投机解码的唯一前提。
大模型生成文字是一个字一个字往外蹦的(术语叫自回归)。每蹦一个字,都要把整个模型的全部权重从显存里完整读一遍。以 27B 模型 Q4 量化为例,权重约 16 GB——也就是说,每生成一个字,就要搬运 16 GB 数据。
这带来一个关键结论:瓶颈在内存带宽,不在计算能力。显卡的计算单元绝大部分时间在空转等数据。用一张带宽 936 GB/s 的 RTX 3090 举例,理论上限就是 936 ÷ 16 ≈ 58 tok/s,无论这张卡的算力有多强。
所以加速的方向有两条:
- 减少要搬运的数据量(量化、用小模型)——代价是质量。
- 让空转的算力干点活——这正是投机解码的思路,且不损失任何质量。
二、核心思路:让便宜的小模型去"猜",让贵的大模型去"批改"
打个比方。大模型是个写文章很慢但水平很高的资深编辑,小模型是个打字飞快但水平一般的实习生。
- 传统方式:编辑一个字一个字亲自写,写一个字想一下,慢。
- 投机解码:实习生先一口气猜出接下来 5 个字,编辑拿过来一次性扫一眼——“前 3 个对,第 4 个不对”。于是前 3 个字直接采纳(几乎白赚),第 4 个字由编辑自己改,第 5 个字扔掉重来。
关键在于:编辑一次性检查 5 个字的成本,和检查 1 个字的成本几乎一样。因为权重的搬运量在一次前向传播里是固定的,检查 5 个 token 只是把这条数据多算几遍而已——而算力本来就是空闲的。
curl 不止是下载工具:AI 与 Agent 开发中的十二类实战场景
curl 不止是下载工具:AI 与 Agent 开发中的十二类实战场景
多数人学 curl 的第一课是"下载文件",此后便把它归类为 wget 的同类。但在 AI 与 Agent 工程中,curl 的角色完全不同:它是唯一一个在协议层完全透明、零依赖、可在任何环境逐字复现的 HTTP 客户端。当需要回答"这个模型接口到底返回了什么"“延迟究竟卡在哪一段"“Agent 的工具调用为什么静默失败"时,curl 往往比任何 SDK 都更快给出答案——因为它不隐藏任何东西。
本文以 curl 8.22.0(2026-09-02 发布,第 276 个版本,命令行选项累计 278 个)为基线,梳理十二类高频场景。所有命令均可直接粘贴执行,只需替换端点与凭据。
一、LLM 接口调试的四个基本动作
1.1 最小可复现调用
--json(7.82.0 引入)是单次调用最省事的写法,它等价于同时做三件事:把数据作为 --data-binary 发送、设置 Content-Type: application/json、设置 Accept: application/json。
curl -sS https://api.deepseek.com/chat/completions \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
--json '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "只回复 OK"}],
"temperature": 0
}' \
-w '\n[%{http_code} | %{time_total}s | %{size_download}B]\n'
三点值得强调:
别把 2B 当小号 GPT-4:llama.cpp + Qwen 2B 的六种实战玩法
别把 2B 当小号 GPT-4:llama.cpp + Qwen 2B 的六种实战玩法
在本地跑一个 2B 级别的模型(Qwen2.5-1.5B、Qwen3-1.7B 这一类),最常见的失望是「它连个像样的回答都给不出来」。于是很容易得出一个结论:小模型没用,还得上 32B 甚至 72B。
这个结论错在前提。2B 的定位从来不是"小号 GPT-4",而是流水线里一个廉价、快速、输出确定的专用零件。
在一台普通笔记本上,Qwen 2B(Q4_K_M 量化)的生成速度可以轻松跑到 30 tokens/s 以上,显存占用不到 2GB。这意味着它一秒能吞下几十条请求。真正的技术含量不在于它有多聪明,而在于你如何把任务切到它擅长的那一格。
一句话概括本文的判断:不要让小模型去"思考",要让它去"填空"。
先确认你的跑法
下文所有玩法都建立在 llama-server 上——它提供 OpenAI 兼容接口,任何现成的 SDK 都能直接接。一个够用的启动命令:
./llama-server \
-m models/Qwen2.5-1.5B-Instruct-Q4_K_M.gguf \
-c 4096 \
-np 8 --cont-batching \
--jinja \
--host 127.0.0.1 --port 8080
几个参数值得单独说明:
| 参数 | 作用 |
|---|---|
-c | 上下文长度,小模型不要盲目开大 |
-np --cont-batching | 并行槽位 + 连续批处理,是批量吞吐的关键 |
--jinja | 启用模型自带对话模板,工具调用能力依赖它 |
-ctk q8_0 -ctv q8_0 | KV Cache 量化,长上下文时能省一半显存 |
--mmproj xxx.gguf | 加载视觉投影层,进入多模态模式 |
玩法一:语法约束输出器 —— 最高杠杆的一招
llama.cpp 原生支持 GBNF 语法与 JSON Schema 约束解码。这是它相对于 vLLM、Ollama 最显著的差异点,也是让 2B 从"勉强能用"跳到"近乎可靠"的关键。
从自动化到智能化:Playwright 全栈进阶指南
从自动化到智能化:Playwright 全栈进阶指南
Playwright 已经超越了传统的自动化测试框架,成为了 Web 浏览器协议栈的最强控制端。无论是常规的端到端测试,还是赋予 AI Agent 真实世界的“双手”,Playwright 都是必不可少的工具。
以下是 Playwright 从零到 AI 代理的进阶路线图。
目录
- 环境搭建与架构初探
- 定位器与交互艺术
- 异步测试与高级等待机制
- AI 代理与浏览器控制 (MCP)
- CI/CD 与多环境适配
1. 环境搭建与架构初探
Playwright 基于 WebKit、Chromium 和 Firefox 的原生 CDP(Chrome DevTools Protocol),相比 Selenium 具有更高的稳定性和并发性能。
- 初始化:
npm init playwright@latest或 Python 下pip install playwright - 关键配置:理解配置文件中的
projects(多浏览器并行)与use(全局断言/超时设置)。
2. 定位器与交互艺术
拒绝 XPath,全面拥抱 Web-First Locators。
- 推荐使用:
getByRole,getByLabel,getByPlaceholder,getByTestId。 - 交互逻辑:
click,fill,press均具备自动等待功能,有效减少了手动sleep的“代码异味”。
3. 异步测试与高级等待机制
- 事件驱动:利用
page.waitForEvent和page.waitForResponse精准监控 Web 交互流。 - 状态断言:使用
expect工具链进行原子化断言(如toBeVisible)。 - 网络拦截:使用
page.route进行 API Mock 或异常注入,模拟复杂的后端行为。
4. AI 代理与浏览器控制 (MCP)
这是 Playwright 进阶的巅峰:将浏览器控制权交给 LLM。