在小型 GCP VPS 上尝试用 OpenCode 接管个人助理
我希望把日常对话、QPC 知识库与日历逐步放进一个个人助理,同时控制小型 VPS 的资源占用。已有 Hermes 网关正在使用另一只 Lark 机器人。这个实验的目标是暂停 Hermes,在同一台共享小机上尝试运行 OpenCode,并使用 personal-assistant 的机器人验证接管链路。
**同日补充:**第一次窗口结束前的消息被中断;经再次授权,重开受保护的短时窗口后,真实 Lark 两轮私聊均收到回复,第二轮正确使用了前文。模型任务期间的内存峰值和压力依然偏高,尚不能据此判断适合在这台小机上长期常驻。
这次实验的边界很窄:测试短时对话、资源和回退;QPC 与日历不是这次已经实现的能力。两只机器人独立,暂停 Hermes 会暂时影响原机器人,不会自动把它的会话和权限迁移到新机器人。
为什么不能只比较一个 RSS
在决定切换前,观察到 Hermes 主进程的一次 RSS 约 341 MiB,另有进程数据进入 swap。本机 WSL 中 OpenCode 空闲服务的主进程 RSS 大约 224–262 MiB。但 Hermes 当时正在承担实际网关工作,OpenCode 的本机测试没有接真实 Lark 或模型。不同机器、不同负载和不同统计口径不能直接得出完整替代方案的节省量。
共享实例约有 952 MiB 可见内存,Hermes 运行时多次采样的可用内存只有一百多 MiB,还有明显 swap 使用。相比直接叠加一个服务,先暂停旧网关、在相同机器上测量完整链路,更接近实际问题。
把切换做成可回退试验
方案是由已有的轻量 Lark 入口负责本人身份检查、消息去重与回复状态,OpenCode 仅在本机回环地址提供模型对话接口。服务使用非特权用户、单独工作目录、内存和 CPU 限额;OpenCode 工具权限默认拒绝,试验不开放文件修改、Shell 或其他外部动作。模型凭证和机器人凭证分开提供,不放入仓库或文章。
切换前设置了十分钟自动回退,并持续观察内存余量、内存压力和关键服务状态。试验失败或达到时限时,停止试验服务,恢复 Hermes gateway 和 A2A bridge。两个服务独立恢复,是因为 bridge 没有声明会自动跟随 gateway 的依赖关系。
对话适配器每轮创建独立 OpenCode 会话,只加入已确认送达的有限历史;调用超时不自动重试。模型回答和 Lark 成功投递分开记录。OpenCode 自身会在状态目录写入会话数据,尝试调用 API 删除会话并不等于证明底层数据被彻底擦除,因此试验使用独立目录并在结束后清理。
AI Agent 工程师学习路线图:Python · Linux · 算法 · Agent 四线合一(2025–2026)
这篇文章把四条通常被分开讲的学习线——Python 工程、Linux 系统、数据结构与算法、AI/Agent——放进同一张路线图。核心判断是:它们不是四份独立的清单,而是围绕同一个能力闭环收敛。Linux 提供 Agent 的运行与隔离边界,Python 提供工程化底座,算法提供检索/规划/限流/缓存的内核,AI/Agent 是最终交付形态。
为什么要四线交叉,而不是串行
AI Agent 工程师与传统后端工程师的差别,不在模型本身,而在围绕模型的系统工程:如何把一次不稳定的模型调用,包装成可恢复、可观测、可评测、可审计的运行时。
这个目标恰好落在四类能力的交集上:
- 模型调用会失败,要重试与限流 → 需要并发与算法;
- 工具调用要触碰真实文件与网络 → 需要 Linux 内核能力做边界;
- 上下文、检索、评测要长期维护 → 需要 Python 工程化;
- 最终形态是一套服务 → 需要容器、部署与可观测性。
所以正确姿势是交叉推进,而不是"先学完 A 再学 B"。下面这张表是整体节奏,每周建议投入 10–15 小时:工作日 1–1.5 小时(以算法为主),周末 5–6 小时(以项目为主)。
| 阶段 | 周期 | Python | Linux | 算法(贯穿) | AI / Agent |
|---|---|---|---|---|---|
| P0 环境基线 | 第 1–2 周 | uv + ruff + pytest + mypy 模板仓库 | Shell 最小集 + SSH 密钥登录 | 复杂度分析 | 通读 Anthropic《Building Effective Agents》 |
| P1 工程打底 | 第 3–10 周 | 类型系统、Pydantic v2、asyncio、FastAPI 流式服务 | 权限/进程/cgroup v2/systemd/网络 | 数组、哈希、双指针、二分、排序 | 原生 API 手写 ReAct Agent;结构化输出 |
| P2 应用构建 | 第 11–24 周 | 数据栈、profiling、打包发布 | 容器化、反代 TLS、VPS 加固、可观测性 | 树、堆、图、DFS/BFS、拓扑排序、回溯、DP 入门 | RAG(混合检索+重排)、评测、MCP server/client |
| P3 Agent 深化 | 第 25–40 周 | 异步多工具运行时、性能优化 | eBPF/perf 排障、Landlock/seccomp 沙箱 | 并查集、Trie、贪心、高级 DP、字符串算法 | LangGraph 1.0 有状态工作流、多 Agent、A2A |
| P4 生产化 | 第 41–52 周 | vLLM 本地部署、服务切换 | 高可用、备份、监控告警 | 图算法综合、位运算、综合题 | 可观测+评测回归+安全防护的生产级 Agent |
一、Python 工程线:把"能跑"变成"敢维护"
版本基线
生产基线选 Python 3.12/3.13,新项目可以上 3.14(3.15 处于 RC 阶段)。需要掌握的语言特性集中在四处:
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 重写插件。
DeepSeek Harness 解读(四):minimal 真的是最小 Agent 吗?
这是 DSH 系列的最后一篇。我们之前问过:minimal preset 只有两个工具,它是否已经是最小化 Agent?答案是:对模型可见能力来说接近最小,对真实运行时来说并不是。
DSH 的四种 preset 不是四个产品
DSH 当前把 Agent 能力组合成几类 preset:
standard 完整 Coding Agent
ptc TypeScript Code Mode / PTC
minimal persistent bash + str_replace_editor
creator 运行时检查和插件实验
它们不是四个独立程序,而是同一个 Cordis Runtime 上的不同能力组合。
这一区分很重要:preset 决定的是某个 Agent Scope 可以看到和使用哪些能力,而不是重新启动一套完全不同的 Agent 实现。
minimal 为什么看起来很小
DSH 的 minimal 配置对模型暴露的主要能力只有:
1. persistent bash
2. str_replace_editor
同时它关闭或抑制了很多额外上下文:
- 不加载完整 Coding Agent 的复杂工具集;
- 不注入运行时上下文;
- 不使用默认的复杂压缩能力;
- 使用固定、短的系统提示;
- 让 Bash 在多个 step 之间保持状态。
相关实现可以直接看 minimal agent preset 和 minimal runtime 设计记录。
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:
DeepSeek Harness 解读(二):内核不是 Agent,而是 Cordis 运行时
上一篇讨论了 DSH 为什么不应该被简单看成“另一个 Codex”。这一篇进入源码架构:DSH 的真正内核不是一个大而全的 Agent 类,而是一套用来组装 Agent 的插件运行时。
先给一个简化模型
Runtime = Profile + Bundle + Patch + Plugin
Agent = Scoped Context + Session + Agent Driver
Turn = LLM Request + Tool Pipeline + Durable Events
DSH 官方文档对自己的描述很直接:模型适配器、工具注册表、会话日志和 Agent Loop 都是插件;没有一个需要被所有扩展修改的 privileged core。DSH Architecture
这里的“没有核心”不是说系统没有基础代码,而是说:基础服务存在,但业务能力没有被绑死在一个不可替换的中心对象里。
Cordis:Context 是服务仓库
Cordis 是 DSH 底层的插件框架。每个插件可以向共享 Context 注册服务:
ctx.llm 模型适配器
ctx.sessions 会话存储
ctx.tools 工具注册表
ctx.systemPrompt Prompt 组装
ctx.fs 文件系统能力
ctx.sandbox 沙箱能力
ctx.agents Agent 注册表
插件不直接依赖具体实现,而是通过 ctx.<key> 找到能力;依赖通过 inject 声明,加载顺序由服务依赖关系决定。插件注册的工具、Prompt、Provider 和事件监听器都会通过 effect 安装,并在插件卸载时撤销。Cordis Primer
DeepSeek Harness 解读(一):它不是另一个 Codex
这是一组关于 DeepSeek Harness(简称 DSH)的源码级解读。第一篇先回答一个很现实的问题:市场上已经有 Codex、Claude Code,为什么还需要 DSH?
先说结论
如果需求是“给我一个现在就能写代码的 Agent”,普通用户没有太多理由选择 DSH。Codex 和 Claude Code 的优势在于完整的产品体验:安装、权限、上下文、编辑、测试、恢复和日常交互都已经被包装好了。
DSH 的合理定位不是“另一个更好用的 Codex”,而是:
一个可编程、可替换、可嵌入、可自托管的 Agent Runtime,同时提供一个 DeepSeek 原生的 Coding Agent。
这两个定位看起来相近,实际上面对的是不同买家。
三种产品不是同一层
可以把 Agent 市场拆成三层:
模型层:DeepSeek / OpenAI / Anthropic / 自建模型
运行时层:DSH / OpenAI Agents SDK / Google ADK / LangGraph / Pi
产品层:Codex / Claude Code / 企业内部 Agent 产品
Codex 和 Claude Code 的核心目标是让用户完成任务。它们当然也在开放 Skills、MCP、SDK 和企业部署能力,但用户不需要先理解运行时内部结构,就可以开始工作。Codex 开发者主页、Claude Code CLI 文档
DSH 的重点则是把运行时本身暴露出来:模型适配器、工具注册表、Session Log、Agent Loop、沙箱和审批都可以通过插件和配置组合。官方架构文档甚至明确写道,产品中的这些部分都属于插件,而不是一个必须修改的特权核心。DSH 架构文档
Agent 系列日记 5:为什么 Skill 路由比 ReAct 控制器更适合个人助理
从 luck-agent 到 Hermes-lite,我花了两年时间才想清楚这个问题:80% 的请求不需要"思考",只需要"路由"。
回顾:ReAct 控制器模式的困境
2024 年做 luck-agent 的时候,我采用的是经典的 ReAct 模式(Reasoning + Acting):
用户输入 → 大模型推理(意图识别 → 规划 → 工具选择 → 执行)→ 输出
所有请求,不管简单还是复杂,都走同一个推理链。一个"查 QPC 里有没有 VPS 相关的记录"的请求,也要经过:
- 理解自然语言
- 判断意图类别
- 选择工具(search_qpc)
- 构造查询参数
- 执行并解释结果
问题很明显:
- Token 消耗大:每次推理要带上完整的 system prompt + 工具定义,光上下文就吃掉 3000-5000 token
- 延迟高:一个简单查询要等模型完成完整推理链,响应时间 3-8 秒
- 上下文窗口压力:随着工具数量增加(现在 Hermes-lite 有 20+ 个工具),system prompt 越来越大
我当时就在知识库里记了一条:
“对于个人助理场景,相比最初的 ReAct 控制器模式,Skill 技能路由更适合当前 luckagent:80% 请求是固定模式,不需要复杂推理,技能比 Agent 更稳定,成本更低,响应更快。”
Skill 路由的核心思想
一句话:预定义技能映射,轻量分类先路由,只加载需要的工具和 prompt。
用户输入 → 轻量路由(关键词/意图 → 技能)→ 加载专用 prompt + 工具 → 执行
路由表设计
# 简化版路由逻辑
ROUTING_RULES = {
"qpc": {
"keywords": ["QPC", "知识库", "记一下", "记录"],
"skill": "qpc",
"tools": ["feishu_bitable_read", "feishu_bitable_write"],
"prompt": "qpc_skill_prompt" # 只加载 QPC 相关的 prompt
},
"vps": {
"keywords": ["VPS", "服务器", "防火墙", "Docker"],
"skill": "gcp-vps-ops",
"tools": ["terminal", "read_file"],
"prompt": "vps_skill_prompt"
},
"blog": {
"keywords": ["博客", "文章", "Hugo", "发布"],
"skill": "hugo-blog",
"tools": ["terminal", "read_file", "write_file"],
"prompt": "blog_skill_prompt"
}
}
对比:同样"查 QPC"操作
| 指标 | ReAct 模式 | Skill 路由 |
|---|---|---|
| 上下文 token | ~4000(全量工具定义) | ~800(仅 QPC 相关) |
| 首次响应延迟 | 3-8s | 0.5-1.5s |
| 工具调用次数 | 2-3 次(推理+执行) | 1 次(直接执行) |
| 准确率 | 92%(模型可能选错工具) | 98%(路由确定性高) |
Hermes-lite 的 Skill 实现
Hermes-lite 的 skill 系统是这样工作的: