Dify 深度玩法(五):Agent、MCP 与一个完整实战
Dify 深度玩法(五):Agent、MCP 与一个完整实战
上一篇:RAG 深度玩法。 本篇是收官:先讲清 Agent 与 Workflow 的分工原则,再讲 MCP 的实际价值,最后把整个系列串成一个跑得通的真实项目——博客勘误官。
Agent 与 Workflow:谁管什么
新版 Dify 的 Agent 带来了 Linux 沙箱与技能(Skills)体系:Agent 可以在隔离环境里执行命令、管理文件、按需安装依赖。能力变强之后,最重要的设计原则反而是克制:
- Agent 管判断:任务路径开放的环节——自己决定查什么、跑哪个脚本、怎么补证据;
- Workflow 管编排:触发、顺序、分支、审批门、重试、归档——所有需要确定性的环节。
反例是"一个 Agent 干全部":触发它自己定、写操作它自己批、失败它自己咽——这类流程出问题时你连现场都还原不了。自主性是成本,不是默认值。
不仅是日志:构建企业级 Agent 的全链路可观测性
不仅是日志:构建企业级 Agent 的全链路可观测性
在企业级应用中,Agent 不再是一个黑盒模型,而是一个需要被持续审视的决策系统。如果 Agent 的决策链路不可见,其执行失控的风险将成倍增加。
1. 可观测性的分层设计
我们必须将 Agent 的运行视为三个不同维度的流:
- 执行层 (Action Layer):系统指标(CPU/内存/网络/IO)。这是最底层的基础保障,通过
htop/eBPF等工具获取。 - 交互层 (Interaction Layer):MCP 工具调用记录。记录所有 Tool 的输入、输出参数及执行耗时。
- 认知层 (Cognitive Layer):模型推理过程。记录 Prompt 上下文、思考过程(Thought)及最终决策逻辑。
2. 三阶段观测策略
企业级 Agent 应在不同生命周期注入观测点:
第一阶段:感知 (Perception)
- 观测重点:输入清洗后的上下文数据质量。
- 策略:记录原始 Prompt 到优化后的 Prompt 的转换差值,评估输入信息的信噪比。
第二阶段:决策 (Decision)
- 观测重点:模型意图与规划路径。
- 策略:使用“追踪标记” (Tracing Markers) 记录模型在复杂任务分解过程中的逻辑分支。建议将决策链序列化为 JSON 存储,支持后续复盘。
第三阶段:执行 (Execution)
- 观测重点:工具调用成功率与异常处理。
- 策略:标准化 MCP 接口。通过 MCP 封装所有外部工具调用,注入拦截器记录
request_id,实现从决策到内核级系统调用的全链路追踪。
3. 企业级参考架构:基于 MCP 的观测流
在复杂环境中,不要直接在 Agent 中硬编码观测逻辑,推荐采用**“旁路观测”**模式:
- 接口标准化 (MCP Wrapper):利用 MCP 协议作为 Agent 与外部世界的标准接口,所有 Tool 调用统一接入该层,自动注入
Correlation-ID。 - 异步数据流:观测数据不应同步发送(避免阻塞 Agent 决策)。使用 Unix Domain Socket 将 JSON 格式的指标流实时推送到 Sidecar 进程,由 Sidecar 负责数据的聚合与上报(至 Prometheus/Jaeger)。
- 决策快照:在发生错误(如 Tool 返回 Error)时,自动触发“现场快照”,记录当前的 Prompt、工具参数、中间变量、以及系统栈信息,供研发离线回溯。
// 企业级观测接口示例 (标准化 JSON)
{
"request_id": "req_550e8400-e29b",
"component": "tool_executor",
"action": "execute_tool",
"tool_name": "docker_compose_up",
"status": "failure",
"metadata": {
"latency_ms": 1245,
"system_load": "0.85",
"trace_parent": "trace_a9928"
},
"error_msg": "Timeout after 1000ms"
}
4. 故障演练:故障降级策略
一旦观测系统检测到异常:
Luck Ops MCP:把 Lark 多云运维做成成熟 Agent 可接入的标准工具
当一个个人 Agent 同时负责聊天、记忆、博客、Lark 卡片、多云 VPS、SSH、systemd、Docker、审批和审计时,最先出现的问题不是模型不够聪明,而是边界越来越难解释。
继续给 Agent 增加工具,最终会得到另一个通用 Agent;改用成熟 Agent,又可能丢掉已经验证过的运维安全能力。
更好的拆法是:
保留 Lark 多云运维的专业能力,但把它从通用 Agent 中抽出来,做成独立的
luck-ops-mcp。
Hermes、OpenClaw、Codex 或其他 MCP Client 负责理解用户意图;luck-ops-mcp 只负责资产、权限、审批、执行和审计。
产品边界
luck-ops-mcp 负责:
- AWS、GCP、Azure 等目标目录;
- 主机、资源、服务和日志查询;
- 固定、登记过的运维操作;
- 用户、目标、服务和操作权限;
- Lark 人工审批;
- 执行前置条件、结果验证和回滚说明;
- 操作状态和审计记录。
它不负责:
- 通用聊天;
- Agent 推理和任务规划;
- 博客写作、英语学习和知识问答;
- Agent 长期对话记忆;
- 任意远程 Shell;
- 根据模型临时生成系统命令。
这样可以把系统分成三层:
交互层:Lark / Web / CLI
推理层:Hermes / OpenClaw / 其他成熟 Agent
执行层:luck-ops-mcp / vps_sysops
其中只有执行层持有运维凭据,推理层永远不是最终授权者。
为什么适合 MCP
MCP 把上下文和动作分成 Resources 与 Tools:稳定、可读的资产适合 Resources,会产生行为的操作适合 Tools。客户端可以通过标准协议发现 schema,而不需要为每个 Agent 重写插件。
轻量个人助理 Agent 选型:Hermes、OpenClaw、nanobot 与开发框架怎么选
我曾经把个人助理的每一层都自己实现:Lark WebSocket、卡片、Agent Loop、Goal Runtime、记忆、定时任务、多模型 fallback、工具审批和多云 VPS 运维。
这样做最大的收益是理解了边界,最大的代价也是边界——一旦通用 Agent 能力持续扩张,维护一个个人助手就会逐渐变成维护一个框架。
更合理的方向是:
成熟 Agent 负责通用助理能力
标准 MCP 负责专业工具
服务端策略负责最终安全边界
但“成熟”和“轻量”不能只看项目介绍。这篇文章使用同一组需求评估 2026 年几类主流选择。
我的真实需求
这不是通用 Agent 排行榜。目标环境是一台低资源 VPS,主要服务一个人:
- 通过 Lark 私聊和群聊使用;
- 处理问答、翻译、摘要、Idea、纪要和博客;
- 保存少量长期偏好与会话历史;
- 支持定时提醒和主动推送;
- 通过 MCP 接入 GitHub、知识库和多云运维;
- 模型不可用时,核心运维控制面仍然可查询;
- 重启、备份、恢复和发布等动作必须人工批准;
- 使用远程模型,不在小 VPS 上运行本地大模型。
基于这些约束,我把候选分成两类:
成品助理:Hermes Agent / OpenClaw / nanobot
开发框架:OpenAI Agents SDK / PydanticAI / Agno / LangGraph
成品助理的优势是少造渠道、记忆和调度;框架的优势是运行时可控,但应用外壳仍要自己写。
先定义“成熟”
一个仓库更新频繁、Star 很多,不等于适合长期运行。我更关心:
- 配置和升级有没有稳定入口;
- 会话和任务能否在重启后恢复;
- 渠道是否处理去重、重连和用户隔离;
- MCP 是否支持过滤、超时和失败降级;
- 高风险工具是否有确定性权限边界;
- 日志、健康检查、备份和回滚是否可操作;
- 安全修复是否持续发布;
- 能否关闭不需要的工具,而不是默认把整台主机交给模型。
个人助理生态仍然变化很快。这里的“成熟”是相对成熟,不等于 systemd、SQLite 或 Ansible 那样经过多年稳定周期。
极简 Agent 实用测试基准:别再只看能不能跑起来
很多项目把“轻量”写在 README 里,但这个词经常只代表安装命令短、核心代码少,或者演示时能在一台小机器上启动。
对一个需要 24 小时在线的个人助理来说,这些都不够。真正的问题是:它空闲时占多少资源?连续调用工具后会不会涨内存?断网、重启、模型限额和审批暂停之后还能不能回来?
因此我给“极简 Agent”定义了一套实用测试基准。它不评模型知识,也不追求实验室里的漂亮分数,只回答一个工程问题:
这个 Agent 能不能在低资源 VPS 上,长期、稳定、安全地替一个人处理真实任务?
极简不是一个内存数字
一个个人 Agent 至少包含四层:
消息入口 → Agent Runtime → 外部模型 → 工具与状态
只统计 Agent 主进程的 RSS,会漏掉浏览器、Node bridge、MCP 子进程、后台 worker 和模型代理。只统计空闲内存,也会漏掉长上下文、文件解析和工具输出带来的峰值。
所以“轻量”应该同时满足:
- 常驻资源低;
- 任务峰值有上限;
- 空闲后能够回落;
- 不产生孤儿进程;
- 重启后能恢复必要状态;
- 失败不会演变成无限重试;
- 高风险动作不会绕过审批。
测试环境必须先固定
不同机器、Python/Node 版本和模型端点会显著影响结果。每次测试至少记录:
host:
cpu: 2 vCPU
memory: 1 GiB
swap: 1 GiB
os: Ubuntu 24.04
runtime:
version: git commit / release tag
language: Python 3.12 / Node 26 / Go 1.x
model:
endpoint: remote OpenAI-compatible
model: fixed model id
context_window: fixed
features:
channel: Lark WebSocket
memory: SQLite or files
mcp_servers: [luck-ops]
browser: disabled
不要一边测 Agent A 的最小配置,一边给 Agent B 打开浏览器、语音和十个插件。功能集合必须一致,模型也必须一致。
DeepSeek Harness 解读(三):会话、记忆与上下文压缩
这是 DSH 系列的第三篇。很多 Agent 都声称支持“记忆”,但这个词往往同时指会话保存、上下文压缩、跨会话召回和目标续跑。DSH 的有趣之处,是把这些问题明确拆开了。
先把“记忆”拆成五件事
Session Persistence 保存发生过什么
Context History 决定模型当前看到什么
Compaction 压缩当前可见历史
Long-term Memory 跨会话主动召回知识
Goal State Agent 还要继续完成什么
DSH 内置支持前四项中的一部分:它强内置会话事件日志和上下文压缩,Goal 是持久任务状态;真正的语义长期记忆则通过外部 Provider 或 MCP 接入。
1. Session Persistence:日志才是事实来源
DSH 不把 messages[] 当作唯一状态,而是将一次交互保存为 append-only 的类型化事件:
turn/start
user/message
assistant/chunk
assistant/message
tool/call
tool/result
step/end
turn/end
模型的历史消息由这些事件重新派生。这样可以让 UI、Replay、Fork、Telemetry 和恢复逻辑共享同一份事实来源。Session 文档
持久化层通过 ctx.sessionPersistence 抽象出来,目前支持 JSONL 和 SQLite 后端。写入采用批处理和 flush checkpoint;崩溃恢复时,DSH 会识别没有关闭的 turn,并以 interrupted 结束它,而不是粗暴截断日志。Persistence 文档
这是一种“事实优先”的设计:
原始日志尽量完整
模型上下文可以变化
历史投影可以重新计算
2. Compaction:压缩可见表面,不删除原始历史
上下文接近模型窗口时,DSH 不直接删除旧事件,而是选择一段旧的 surface,调用 summarizer 生成摘要,然后追加一个 checkpoint: