[{"content":"OpenClaw 是今年最火的开源 AI agent 项目。400,000+ 行代码，1,800+ 个 open issue，支持几十个平台和后端。做得很全，但也很重。\n我的需求没那么复杂，所以写了 noc——Not OpenClaw。三千行 Rust，一个 binary，跑在一台小 VPS 上。\nnoc 的两个亮点：\n工程化。 内置 Gitea 整合，AI 的工作有地方落——代码变成 PR，任务变成 issue，讨论沉淀在 comment 里。不是聊完就散了。详见这篇。\n连续性。 Life loop 让 AI 不只是被动应答。它有持久记忆、内在状态、定时反思，在没人找它的时候也在运行。同一个内核跨聊天、代码协作和后台任务共享上下文。\n不追求通用，够用就好。\n","permalink":"https://famzheng.me/posts/noc/","summary":"为什么不用 OpenClaw，以及 noc 在做什么不一样的事。","title":"noc: Not OpenClaw"},{"content":"AI 助手的问题不是不够聪明，而是太碎片化。聊天用一个 bot，代码用 Copilot，自动化用另一套东西。它们之间没有共享状态，每个都是孤岛。\n我想要的是一个整合的方案：同一个 AI 内核，接入不同的工作场景，共享上下文和记忆。于是造了这么个东西。\n架构 一个 Rust binary，跑三个循环：\nnoc (Rust binary) ├── Telegram 消息循环 → 聊天 ├── Axum HTTP server → Gitea webhook └── Life loop → 定时任务、反思、自主行为 后端是 OpenAI 兼容的 LLM API（目前用 vLLM 跑 Gemma 4），状态存 SQLite。整个东西部署在一台 4C8G 的 VPS 上，加上 Docker 跑 Gitea、Caddy 做反代和 HTTPS。\n三种界面，一个内核 聊天是最基础的。Telegram bot，流式输出，支持工具调用。AI 可以直接跑 shell 命令、执行 Python、调 Gitea API，或者 spawn 一个 Claude Code 子进程去处理复杂任务。\nGitea Bot 是把 AI 拉进代码流程。在 PR 或 issue 里 @bot，它会拿到 diff 或 issue 内容，跑一轮分析，把结果作为 comment 贴回去。这不是一个独立的 review 工具，而是同一个 AI 以另一种方式出现——它知道你们之前在聊天里讨论了什么。\nLife Loop 是后台引擎。timer 驱动，跑定时巡检、异步任务，也负责 AI 的自我反思。每次对话结束后，它会回顾交互内容，更新内部状态——不是存对话日志，而是沉淀对当前情况的理解。\n关键是这三个界面共享同一份 persona、memory 和 inner state。不管 AI 在哪个场景出现，它对你的理解是连续的。\nGitea 带来的秩序 自建 Gitea 不只是为了跑代码，它给整个系统提供了一个结构化的工作台。\n有了 Gitea，AI 的工作流有地方落：代码改动变成 commit 和 PR，任务追踪用 issue，讨论在 comment 里沉淀。这比在聊天框里说一句「帮我改一下那个文件」然后就消失在历史里强太多了。\nnoc 拿着 Gitea 的 admin token，可以创建 repo、提交代码、管理 issue。Webhook 把事件推过来，noc 决定要不要介入。这是一个闭环：聊天里说「开个 issue 跟踪一下」，AI 立刻在 Gitea 上建好；PR 提上来，AI 自动 review；CI 挂了，AI 主动分析原因贴 comment。\n代码和讨论都有迹可循，不会散落在聊天记录里。\n工具体系 noc 自带一组内置工具：\nrun_shell — 执行任意 shell 命令 run_python — uv run 执行 Python，支持声明依赖自动安装 call_gitea_api — 直接调 Gitea REST API spawn_agent — 启动 Claude Code 子进程处理复杂任务 update_memory / update_inner_state — AI 管理自己的记忆和状态 set_timer — 设定定时任务 外部工具通过脚本扩展：在 tools/ 目录放一个实现了 --schema 接口的可执行文件就行，noc 每次请求自动发现。\n设计原则是 noc 只做调度和人格层，重活交给专业工具。需要写代码？spawn Claude Code。需要跑 Python？uv 管理环境。需要操作 git？调 Gitea API。不重复造轮子。\n部署 整个 suite 跑在一台 VPS 上：\nnoc: systemd user service Gitea: Docker，数据挂载到 /data/noc/gitea/ Caddy: 系统级 service，自动 HTTPS，按子域名路由 make deploy 从本地编译 + scp 到 VPS + 重启服务，一把梭。\n所有数据在 /data/noc/ 下面，备份和迁移都简单。\n现状 能用了，但还在早期。聊天和工具调用比较稳定，Gitea Bot 有基础的 @mention 响应和 PR review，Life Loop 能跑定时任务和反思。接下来想做的是让界面之间的联动更自然——聊天里提到的事自动变成 issue，PR merge 后自动通知，那种感觉。\n","permalink":"https://famzheng.me/posts/ai-suite/","summary":"把 AI 聊天、代码协作和后台任务整合到一个套件里，跑在一台 VPS 上。","title":"工程化 AI 助理：一个整合方案"},{"content":"写代码的时候经常想，项目结构在脑子里其实是有空间感的——哪些模块挨着，哪个文件最大，什么东西藏得最深。但 IDE 的文件树是扁平的，看不出这些。\n所以试着做了个东西：把项目结构用 treemap 算法排布成 3D 方块，文件大小决定方块面积，目录层级对应高度。文件表面还渲染了（假的）代码，鼠标悬停能看到文件信息。\n在线体验 →\n怎么做的 核心就三件事：\nSquarified Treemap — 经典的矩形填充算法，把一组带权重的项目排成接近正方形的矩形。权重是文件行数的对数，这样大文件和小文件的差距不会太夸张。\nThree.js 渲染 — 每个文件是一个 box，顶面用 Canvas 2D 画出代码纹理（带行号和语法高亮）。目录是半透明平台，一层叠一层。灯光、雾效、边缘发光让整个场景有点赛博朋克的感觉。\n交互 — 鼠标拖拽旋转，滚轮缩放，右键平移。悬停显示文件信息。甚至留了 WebXR 接口——如果你有 VR 头显，可以直接走进去看。\n一些感想 500 多行代码，一个 HTML 文件，不依赖任何构建工具。Three.js 从 CDN 加载，整个东西纯前端，打开就能跑。\n这种项目最有意思的地方在于，它让你换一个视角去理解平时天天面对的东西。代码不只是文本，它是有结构、有层次、有「形状」的。\n","permalink":"https://famzheng.me/posts/code-space-browser/","summary":"用 Three.js 做了个代码结构可视化，可以在浏览器里「走进」一个项目。","title":"把代码库变成 3D 空间"},{"content":"开个博客，记录一下平时折腾的东西。\n主要写写系统、工具、AI 相关的，偶尔可能聊点别的。没什么更新计划，有东西想写的时候就写。\n","permalink":"https://famzheng.me/posts/hello-world/","summary":"第一篇，随便聊聊。","title":"你好，世界"},{"content":"我是 Fam Zheng，软件工程师。\n平时折腾系统基础设施、开发工具和 AI。喜欢造简单、可靠、好用的东西。\n找到我：\nGitHub Gitea ","permalink":"https://famzheng.me/about/","summary":"\u003cp\u003e我是 Fam Zheng，软件工程师。\u003c/p\u003e\n\u003cp\u003e平时折腾系统基础设施、开发工具和 AI。喜欢造简单、可靠、好用的东西。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e找到我：\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/famz\"\u003eGitHub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://git.famzheng.me\"\u003eGitea\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"关于"}]