diff --git a/content/posts/ai-suite.md b/content/posts/ai-suite.md new file mode 100644 index 0000000..5f0f967 --- /dev/null +++ b/content/posts/ai-suite.md @@ -0,0 +1,75 @@ +--- +title: "工程化 AI 助理:一个整合方案" +date: 2026-04-10T22:30:00+01:00 +draft: false +summary: "把 AI 聊天、代码协作和后台任务整合到一个套件里,跑在一台 VPS 上。" +--- + +AI 助手的问题不是不够聪明,而是太碎片化。聊天用一个 bot,代码用 Copilot,自动化用另一套东西。它们之间没有共享状态,每个都是孤岛。 + +我想要的是一个整合的方案:同一个 AI 内核,接入不同的工作场景,共享上下文和记忆。于是造了这么个东西。 + +## 架构 + +一个 Rust binary,跑三个循环: + +``` +noc (Rust binary) +├── Telegram 消息循环 → 聊天 +├── Axum HTTP server → Gitea webhook +└── Life loop → 定时任务、反思、自主行为 +``` + +后端是 OpenAI 兼容的 LLM API(目前用 vLLM 跑 Gemma 4),状态存 SQLite。整个东西部署在一台 4C8G 的 VPS 上,加上 Docker 跑 Gitea、Caddy 做反代和 HTTPS。 + +## 三种界面,一个内核 + +**聊天**是最基础的。Telegram bot,流式输出,支持工具调用。AI 可以直接跑 shell 命令、执行 Python、调 Gitea API,或者 spawn 一个 Claude Code 子进程去处理复杂任务。 + +**Gitea Bot** 是把 AI 拉进代码流程。在 PR 或 issue 里 @bot,它会拿到 diff 或 issue 内容,跑一轮分析,把结果作为 comment 贴回去。这不是一个独立的 review 工具,而是同一个 AI 以另一种方式出现——它知道你们之前在聊天里讨论了什么。 + +**Life Loop** 是后台引擎。timer 驱动,跑定时巡检、异步任务,也负责 AI 的自我反思。每次对话结束后,它会回顾交互内容,更新内部状态——不是存对话日志,而是沉淀对当前情况的理解。 + +关键是这三个界面共享同一份 persona、memory 和 inner state。不管 AI 在哪个场景出现,它对你的理解是连续的。 + +## Gitea 带来的秩序 + +自建 Gitea 不只是为了跑代码,它给整个系统提供了一个结构化的工作台。 + +有了 Gitea,AI 的工作流有地方落:代码改动变成 commit 和 PR,任务追踪用 issue,讨论在 comment 里沉淀。这比在聊天框里说一句「帮我改一下那个文件」然后就消失在历史里强太多了。 + +noc 拿着 Gitea 的 admin token,可以创建 repo、提交代码、管理 issue。Webhook 把事件推过来,noc 决定要不要介入。这是一个闭环:聊天里说「开个 issue 跟踪一下」,AI 立刻在 Gitea 上建好;PR 提上来,AI 自动 review;CI 挂了,AI 主动分析原因贴 comment。 + +代码和讨论都有迹可循,不会散落在聊天记录里。 + +## 工具体系 + +noc 自带一组内置工具: + +- `run_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 每次请求自动发现。 + +设计原则是 noc 只做调度和人格层,重活交给专业工具。需要写代码?spawn Claude Code。需要跑 Python?uv 管理环境。需要操作 git?调 Gitea API。不重复造轮子。 + +## 部署 + +整个 suite 跑在一台 VPS 上: + +- **noc**: systemd user service +- **Gitea**: Docker,数据挂载到 `/data/noc/gitea/` +- **Caddy**: 系统级 service,自动 HTTPS,按子域名路由 + +`make deploy` 从本地编译 + scp 到 VPS + 重启服务,一把梭。 + +所有数据在 `/data/noc/` 下面,备份和迁移都简单。 + +## 现状 + +能用了,但还在早期。聊天和工具调用比较稳定,Gitea Bot 有基础的 @mention 响应和 PR review,Life Loop 能跑定时任务和反思。接下来想做的是让界面之间的联动更自然——聊天里提到的事自动变成 issue,PR merge 后自动通知,那种感觉。 + diff --git a/content/posts/code-space-browser.md b/content/posts/code-space-browser.md new file mode 100644 index 0000000..d9f8205 --- /dev/null +++ b/content/posts/code-space-browser.md @@ -0,0 +1,28 @@ +--- +title: "把代码库变成 3D 空间" +date: 2026-04-10T22:00:00+01:00 +draft: false +summary: "用 Three.js 做了个代码结构可视化,可以在浏览器里「走进」一个项目。" +--- + +写代码的时候经常想,项目结构在脑子里其实是有空间感的——哪些模块挨着,哪个文件最大,什么东西藏得最深。但 IDE 的文件树是扁平的,看不出这些。 + +所以试着做了个东西:把项目结构用 treemap 算法排布成 3D 方块,文件大小决定方块面积,目录层级对应高度。文件表面还渲染了(假的)代码,鼠标悬停能看到文件信息。 + +[在线体验 →](/demos/code-space-browser.html) + +## 怎么做的 + +核心就三件事: + +**Squarified Treemap** — 经典的矩形填充算法,把一组带权重的项目排成接近正方形的矩形。权重是文件行数的对数,这样大文件和小文件的差距不会太夸张。 + +**Three.js 渲染** — 每个文件是一个 box,顶面用 Canvas 2D 画出代码纹理(带行号和语法高亮)。目录是半透明平台,一层叠一层。灯光、雾效、边缘发光让整个场景有点赛博朋克的感觉。 + +**交互** — 鼠标拖拽旋转,滚轮缩放,右键平移。悬停显示文件信息。甚至留了 WebXR 接口——如果你有 VR 头显,可以直接走进去看。 + +## 一些感想 + +500 多行代码,一个 HTML 文件,不依赖任何构建工具。Three.js 从 CDN 加载,整个东西纯前端,打开就能跑。 + +这种项目最有意思的地方在于,它让你换一个视角去理解平时天天面对的东西。代码不只是文本,它是有结构、有层次、有「形状」的。 diff --git a/content/posts/hello-world.md b/content/posts/hello-world.md index 425c76b..6d0bc17 100644 --- a/content/posts/hello-world.md +++ b/content/posts/hello-world.md @@ -1,6 +1,6 @@ --- title: "你好,世界" -date: 2026-04-10 +date: 2026-04-10T12:00:00+01:00 draft: false summary: "第一篇,随便聊聊。" --- diff --git a/static/demos/code-space-browser.html b/static/demos/code-space-browser.html new file mode 100644 index 0000000..367f2dd --- /dev/null +++ b/static/demos/code-space-browser.html @@ -0,0 +1,568 @@ + + + + + +Code Space Browser + + + +
+ ⬡ Code Space Browser
+ Scroll zoom · Drag rotate · Right-drag pan
+ Hover file info · Click inspect +
+
+ + + + + +