<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>可靠性 on CAO ZUOHUA</title><link>https://caozuohua.github.io/tags/%E5%8F%AF%E9%9D%A0%E6%80%A7/</link><description>Recent content in 可靠性 on CAO ZUOHUA</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 19 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://caozuohua.github.io/tags/%E5%8F%AF%E9%9D%A0%E6%80%A7/index.xml" rel="self" type="application/rss+xml"/><item><title>Agent 评测与可观测性术语地图：从 Eval、Trace 到 Replay</title><link>https://caozuohua.github.io/posts/2026-09-19-agent-evaluation-observability-glossary/</link><pubDate>Sat, 19 Sep 2026 00:00:00 +0000</pubDate><guid>https://caozuohua.github.io/posts/2026-09-19-agent-evaluation-observability-glossary/</guid><description>&lt;p&gt;Agent 评测领域最容易造成误解的，不是某个指标怎么算，而是同一个词在不同框架里常常指向不同层级。&lt;/p&gt;&#10;&lt;p&gt;有人把一次模型调用叫 Run，有人把整个工作流叫 Run；有人说 Replay，实际只是重新发送 prompt；有人把 Trace 当日志，也有人把它当成一棵有父子关系、可以定位耗时与错误的执行树。术语没有先对齐，评测报告里的“成功率 95%”“支持恢复”“全链路可追踪”就很难验证。&lt;/p&gt;&#10;&lt;p&gt;这篇文章不按字母顺序背词典，而是沿着一条完整链路解释这些概念：Agent 怎样运行，怎样留下证据，怎样用数据集和评估器打分，又怎样把失败样本变成回归测试。&lt;/p&gt;&#10;&lt;h2 id="先看全局一次运行如何变成一次评测"&gt;先看全局：一次运行如何变成一次评测&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Dataset 中的一条 Case&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ 输入 + 可选 Ground Truth&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Workflow 启动一个 Run&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Span：模型调用&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Span：Tool Call&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Span：Guardrail 检查&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Checkpoint：保存 State&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── HITL：暂停并等待人工决定&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Trace：串起本次执行的完整证据&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Evaluator 打分&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Offline Eval 批量比较&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ├── Online Eval 生产监控&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └── Replay / Regression Eval 复现与防回退&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里可以先记住三句话：&lt;/p&gt;</description></item><item><title>Agent 框架评测实验室系列：如何测出企业场景中的真实强弱</title><link>https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-series/</link><pubDate>Fri, 18 Sep 2026 00:00:00 +0000</pubDate><guid>https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-series/</guid><description>&lt;p&gt;“LangGraph、OpenAI Agents、PydanticAI、Google ADK，到底哪个更强？”&lt;/p&gt;&#10;&lt;p&gt;这句话听起来像一个排行榜问题，实际上至少藏着六个不同问题：谁更容易写出第一个 demo，谁在同一模型下更省 token，谁能安全暂停审批，谁能在进程崩溃后恢复，谁的原生抽象更适合复杂工作流，谁的运行证据足以通过企业审计。&lt;/p&gt;&#10;&lt;p&gt;如果不先限定业务场景和风险边界，“最强框架”没有可验证的含义。&lt;/p&gt;&#10;&lt;p&gt;我在开发 &lt;a href="https://github.com/caozuohua/agent-framework-lab"&gt;Agent Framework Lab&lt;/a&gt; 的过程中，逐步把框架测验从“同一个 prompt 跑一遍”改造成一条证据链：冻结任务、提示词、工具、模型和价格；交错重复执行；注入审批、取消、工具故障、worker 崩溃和进程重启；保存不可变原始结果；最后才按自定义权重生成比较结果。&lt;/p&gt;&#10;&lt;p&gt;这个系列整理 Lab 的核心理念、方法、代码、失败经验和阶段记录。它既是项目复盘，也是未来开发其他 Agent 测验项目时可以复用的设计手册。&lt;/p&gt;&#10;&lt;h2 id="系列文章"&gt;系列文章&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-1-define-the-question/"&gt;别急着问哪个 Agent 框架最好：先把比较问题定义对&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-2-enterprise-contracts/"&gt;把企业需求写成可执行的 Agent 评测契约&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-3-failure-evidence/"&gt;不注入故障，就测不出 Agent 框架的生产能力&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-4-scoring-and-statistics/"&gt;从原始运行到排行榜：硬门、权重与统计陷阱&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-5-development-journal/"&gt;Agent Framework Lab 开发实录：从比较 demo 到企业就绪 Alpha&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;此前发布的&lt;a href="https://caozuohua.github.io/posts/2026-09-17-agent-framework-lab-pitfalls/"&gt;《Agent 框架开发与评测踩坑实录》&lt;/a&gt;是本系列的代码型伴读，集中记录事件账本、审批绑定、幂等键、价格表和 ground truth 等十二类工程坑。&lt;/p&gt;&#10;&lt;h2 id="一张图理解-lab"&gt;一张图理解 Lab&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;场景 / Prompt / 工具 / 模型 / 价格 / 限额&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ 冻结并版本化&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Framework Adapter Matrix&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ┌──────────┴──────────┐&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ 公平公共赛道 │ 原生上限赛道&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; │ 同输入、同工具 │ 原生图、handoff、checkpoint&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; └──────────┬──────────┘&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 正常运行 + 固定故障注入&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Raw Result / Events / Artifacts&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 硬性 No-Go → 加权能力画像&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ▼&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Go / Conditional-Go / No-Go&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这套方法最重要的变化，是不再把框架看成一个只负责“调用模型”的 SDK。企业应用真正关心的是一整组能力：任务质量、安全治理、故障恢复、审计、成本、延迟、可运维性、开发体验和迁移成本。&lt;/p&gt;</description></item><item><title>Agent 框架开发与评测踩坑实录：从能跑到可审计、可比较</title><link>https://caozuohua.github.io/posts/2026-09-17-agent-framework-lab-pitfalls/</link><pubDate>Thu, 17 Sep 2026 18:00:00 +0800</pubDate><guid>https://caozuohua.github.io/posts/2026-09-17-agent-framework-lab-pitfalls/</guid><description>&lt;p&gt;很多 Agent demo 的成功标准是：“模型能调用工具，最后返回一个答案。”&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;本文现作为&lt;a href="https://caozuohua.github.io/posts/2026-09-18-agent-framework-evaluation-series/"&gt;《Agent 框架评测实验室系列》&lt;/a&gt;的代码型伴读；系列正文进一步讨论公平赛道、企业场景、故障证据、评分统计和项目演进。&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;但只要把它放进真实系统，问题马上变成另一组问题：任务执行到一半进程崩了怎么办？审批通过的到底是哪一次工具调用？工具重试会不会重复扣款？两个框架比较时，是否真的使用了同一份提示词和工具？模型价格变化后，旧实验的排名还能不能复算？&lt;/p&gt;&#10;&lt;p&gt;我在 Agent Framework Lab V2 RC 中把这些问题做成了一个可以运行、恢复、审计和比较的实验台。本文不讲“Agent 很有前景”，只记录实现过程中最容易被低估的坑、最终采用的设计，以及可以直接复制的代码片段。&lt;/p&gt;&#10;&lt;h2 id="先给结论agent-评测是一条证据链"&gt;先给结论：Agent 评测是一条证据链&lt;/h2&gt;&#10;&lt;p&gt;可信的评测结果必须能回答：这次运行用了哪个框架、模型、provider、提示词和工具？模型调用、工具调用、审批、checkpoint 的顺序是什么？崩溃或重启后哪些动作被恢复，哪些动作绝不能重放？结果怎么评分？换一组权重后能否只重算排名？排名是否因为 ground truth 写错了？&lt;/p&gt;&#10;&lt;p&gt;因此数据流不是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;prompt -&amp;gt; model -&amp;gt; score&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而是：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;任务契约 + 模型契约 + 工具契约&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; append-only 运行事件&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 不可变 RunResult 原始证据&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 可重算的 ScoreProfile&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ↓&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 排名、图表和审计报告&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="坑一把任务成功和评分高混成一件事"&gt;坑一：把“任务成功”和“评分高”混成一件事&lt;/h2&gt;&#10;&lt;p&gt;一次运行可能在运行时层面成功完成，但答案质量只有 60 分；反过来，一个答案看起来不错，也不能掩盖未授权工具调用、预算超限或事件账本损坏。&lt;/p&gt;&#10;&lt;p&gt;Lab 将两者拆开：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;RunResult&lt;/span&gt;(BaseModel):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; run_id: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; matrix_id: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; framework: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; case_id: str&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status: Literal[&lt;span style="color:#e6db74"&gt;&amp;#34;completed&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;failed&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;blocked_gateway_contract&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;unavailable&amp;#34;&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; final_output: str &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tool_calls: list[ToolCallRecord] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; model_calls: list[ModelCallRecord] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; usage: Usage &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Usage()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; score: Score &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; trace_id: str &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; metadata: dict[str, Any] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;status == completed&lt;/code&gt; 只表示执行器完成生命周期；&lt;code&gt;score.total&lt;/code&gt; 是评测器对结果的判断。模型返回错误 JSON 时，运行可以成功但结构化输出为 0；预算结算失败时，即使模型输出正确，也必须判为运行时失败；评分规则改变时，可以重算分数，但不能重写原始执行状态。&lt;/p&gt;</description></item><item><title>不仅是定时：使用 systemd 构建企业级自动化运维体系</title><link>https://caozuohua.github.io/posts/2026-09-14-linux-systemd-ops/</link><pubDate>Mon, 14 Sep 2026 11:30:00 +0800</pubDate><guid>https://caozuohua.github.io/posts/2026-09-14-linux-systemd-ops/</guid><description>&lt;h1 id="不仅是定时使用-systemd-构建企业级自动化运维体系"&gt;不仅是定时：使用 systemd 构建企业级自动化运维体系&lt;/h1&gt;&#10;&lt;p&gt;在 Linux 环境下，如何让服务“永远在线”？对于企业级 Agent 系统而言，答案通常不是编写一个死循环的 Shell 脚本，而是将任务交给系统最底层的管家——&lt;code&gt;systemd&lt;/code&gt;。&lt;/p&gt;&#10;&lt;h2 id="1-为什么弃用用户态-daemon"&gt;1. 为什么弃用用户态 Daemon？&lt;/h2&gt;&#10;&lt;p&gt;在之前的运维实践中，我们尝试过使用自定义的 &lt;code&gt;blog_daemon&lt;/code&gt; 进行自动化调度，但结果证明它不可靠：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;状态丢失&lt;/strong&gt;：Daemon 若因崩溃、重启或环境抖动导致 PID 文件丢失，整个调度机制就会“瘫痪”。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;权限与依赖限制&lt;/strong&gt;：Daemon 难以管理任务间的依赖顺序，也无法精准进行资源限制（如 CPU/内存配额）。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="2-systemd-的核心优势"&gt;2. systemd 的核心优势&lt;/h2&gt;&#10;&lt;p&gt;将任务转交给 &lt;code&gt;systemd&lt;/code&gt;（通过 &lt;code&gt;.service&lt;/code&gt; 与 &lt;code&gt;.timer&lt;/code&gt;），意味着将任务的生存责任交给了内核：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;内核级保障&lt;/strong&gt;：&lt;code&gt;systemd&lt;/code&gt; 与内核紧密协作，即使服务崩溃，它也能通过 &lt;code&gt;Restart=always&lt;/code&gt; 实现秒级恢复。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;资源限制 (Cgroups)&lt;/strong&gt;：通过配置 &lt;code&gt;MemoryMax&lt;/code&gt; 或 &lt;code&gt;CPUQuota&lt;/code&gt;，可以防止 Agent 因死循环或内存泄露耗尽主机所有资源。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;依赖管理&lt;/strong&gt;：通过 &lt;code&gt;After=network.target&lt;/code&gt;，确保服务在网络就绪后再启动，解决了 Daemon 启动时常见的“网络不可用”问题。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="3-局限性与避坑指南"&gt;3. 局限性与避坑指南&lt;/h2&gt;&#10;&lt;p&gt;尽管 &lt;code&gt;systemd&lt;/code&gt; 强大，但它并非完美，在生产环境中需注意：&lt;/p&gt;&#10;&lt;h3 id="systemd-的局限性"&gt;systemd 的局限性：&lt;/h3&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;侵入性强&lt;/strong&gt;：配置需要 Root 权限。在部分云原生环境（如只读文件系统）中，我们无法触及系统级目录，此时 &lt;code&gt;systemd&lt;/code&gt; 会失效。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;配置复杂&lt;/strong&gt;：相比 crontab，&lt;code&gt;systemd&lt;/code&gt; 的配置逻辑冗长。如果项目环境多变，配置迁移成本高。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;单点风险&lt;/strong&gt;：&lt;code&gt;systemd&lt;/code&gt; 本身是系统守护进程，一旦它出现异常，整个系统的服务管理将瞬间停滞（尽管这种情况极少见）。&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="避坑指南"&gt;避坑指南：&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;配置验证&lt;/strong&gt;：在上线前，务必使用 &lt;code&gt;systemd-analyze verify&lt;/code&gt; 检查语法，防止服务启动失败导致雪崩。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;日志归一化&lt;/strong&gt;：&lt;code&gt;systemd&lt;/code&gt; 托管的服务日志默认由 &lt;code&gt;journald&lt;/code&gt; 管理，需配置好日志轮转，防止 &lt;code&gt;/var/log&lt;/code&gt; 空间被写满。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;非 Root 环境替代方案&lt;/strong&gt;：如果环境限制无法使用 &lt;code&gt;systemd&lt;/code&gt;（如无 Root 权限的容器内），请考虑 &lt;strong&gt;&lt;code&gt;supervisord&lt;/code&gt;&lt;/strong&gt; 或基于 &lt;strong&gt;容器调度器 (K8s/Nomad)&lt;/strong&gt; 的健康检查机制，而非编写简易 Daemon。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;hr&gt;&#10;&lt;h2 id="4-企业级最佳实践systemd-配置模板"&gt;4. 企业级最佳实践：Systemd 配置模板&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# /etc/systemd/system/agent-task.timer&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Unit]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Description&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;Daily Agent Task Timer&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Timer]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;OnCalendar&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;*-*-* 12:00:00&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Persistent&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;true&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;[Install]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;WantedBy&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;timers.target&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;&#10;&lt;h2 id="总结"&gt;总结&lt;/h2&gt;&#10;&lt;p&gt;对于企业级 Agent 系统，追求“高可靠性”的关键不在于代码写得多么复杂，而在于如何高效地利用操作系统的管理能力。&lt;code&gt;systemd&lt;/code&gt; 是 Linux 运维的定海神针，但我们也需清楚它的边界——当系统权限受到限制时，拥抱云原生架构（如 GitHub Actions/K8s）将是更优雅的选择。&lt;/p&gt;</description></item><item><title>极简 Agent 实用测试基准：别再只看能不能跑起来</title><link>https://caozuohua.github.io/posts/2026-08-25-minimal-agent-practical-benchmark/</link><pubDate>Tue, 25 Aug 2026 11:30:00 +0800</pubDate><guid>https://caozuohua.github.io/posts/2026-08-25-minimal-agent-practical-benchmark/</guid><description>&lt;p&gt;很多项目把“轻量”写在 README 里，但这个词经常只代表安装命令短、核心代码少，或者演示时能在一台小机器上启动。&lt;/p&gt;&#10;&lt;p&gt;对一个需要 24 小时在线的个人助理来说，这些都不够。真正的问题是：它空闲时占多少资源？连续调用工具后会不会涨内存？断网、重启、模型限额和审批暂停之后还能不能回来？&lt;/p&gt;&#10;&lt;p&gt;因此我给“极简 Agent”定义了一套实用测试基准。它不评模型知识，也不追求实验室里的漂亮分数，只回答一个工程问题：&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;这个 Agent 能不能在低资源 VPS 上，长期、稳定、安全地替一个人处理真实任务？&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h2 id="极简不是一个内存数字"&gt;极简不是一个内存数字&lt;/h2&gt;&#10;&lt;p&gt;一个个人 Agent 至少包含四层：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;消息入口 → Agent Runtime → 外部模型 → 工具与状态&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只统计 Agent 主进程的 RSS，会漏掉浏览器、Node bridge、MCP 子进程、后台 worker 和模型代理。只统计空闲内存，也会漏掉长上下文、文件解析和工具输出带来的峰值。&lt;/p&gt;&#10;&lt;p&gt;所以“轻量”应该同时满足：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;常驻资源低；&lt;/li&gt;&#10;&lt;li&gt;任务峰值有上限；&lt;/li&gt;&#10;&lt;li&gt;空闲后能够回落；&lt;/li&gt;&#10;&lt;li&gt;不产生孤儿进程；&lt;/li&gt;&#10;&lt;li&gt;重启后能恢复必要状态；&lt;/li&gt;&#10;&lt;li&gt;失败不会演变成无限重试；&lt;/li&gt;&#10;&lt;li&gt;高风险动作不会绕过审批。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="测试环境必须先固定"&gt;测试环境必须先固定&lt;/h2&gt;&#10;&lt;p&gt;不同机器、Python/Node 版本和模型端点会显著影响结果。每次测试至少记录：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;host&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;cpu&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;vCPU&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;memory&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;GiB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;swap&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;GiB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;os&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Ubuntu 24.04&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;runtime&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;version&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;git commit / release tag&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;language&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Python 3.12 / Node 26 / Go 1.x&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;model&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;endpoint&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;remote OpenAI-compatible&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;model&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;fixed model id&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;context_window&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;fixed&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;features&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;channel&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Lark WebSocket&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;memory&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;SQLite or files&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;mcp_servers&lt;/span&gt;: [&lt;span style="color:#ae81ff"&gt;luck-ops]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;browser&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;disabled&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不要一边测 Agent A 的最小配置，一边给 Agent B 打开浏览器、语音和十个插件。功能集合必须一致，模型也必须一致。&lt;/p&gt;</description></item></channel></rss>