跳到主要内容

可复用的 AI 技能——属于你的提示词模板

· 阅读需 5 分钟
Creator of UnDercontrol

如果你经常使用 AI 助手,大概已经积累了一套真正好用的提示词。那个总能产出干净结果的重构提示词,符合团队风格的提交信息模板,还有每次生产故障时都要粘贴一遍的 bug 排查清单。

问题在于,这些提示词要么藏在你脑子里,要么贴在便利贴上,要么埋在一个没人记得打开的 Notion 文档里。UnDercontrol 的技能系统就是为了解决这个问题。

什么是技能?

技能是存储在 UnDercontrol 中的具名、可复用提示词模板。每个技能都有一个 slug(例如 refactor-tsdaily-standuppr-review),一段 markdown 正文,并归属于某个群组。最后这一点很重要——技能的作用域是群组级别的,团队可以共享同一套提示词库,而不需要每个人各自维护一份副本。

你可以通过 Web 界面创建和编辑技能,通过 CLI 管理技能,也可以通过 YAML 文件以声明式方式应用技能。markdown 内容支持各种提示词结构:指令、变量、多步骤工作流,满足你的任何使用场景。

Skills page showing system and custom skills with search and tags

创建技能

在 Web 编辑器中,创建技能就像写一篇笔记一样简单。给它起个名字、设定一个 slug,然后在 markdown 编辑器里写好提示词内容。保存之后,群组内的所有人立即可以使用。

通过 CLI,你可以像应用任务一样应用技能定义——使用带 YAML frontmatter 的 markdown 文件:

ud apply skill -f pr-review.md

文件格式大致如下:

---
name: pr-review
description: PR Review Checklist
tags:
- ai
- development
---

Review the following pull request diff and provide feedback on:
- Logic correctness
- Error handling
- Test coverage
- Naming and readability

这让技能具备了可移植性。你可以将它们纳入 dotfiles 仓库,和其他配置一起做版本管理,然后用一条命令部署到新的 UnDercontrol 实例。

使用技能——ud prompt 命令

技能真正的价值体现在使用方式上。ud prompt 命令通过 slug 获取技能内容,并将其输出到 stdout。之后你可以将它管道传递到任何地方。

想把技能传入 Claude Code?

claude-code $(ud prompt pr-review)

想在管道中与其他命令组合使用?

ud prompt pr-review | pbcopy

因为输出的就是标准的 stdout,ud prompt 可以与任何从 stdin 读取内容的工具配合使用——Claude Code、其他本地 AI 代理、shell 管道,一切都取决于你的工作流。UnDercontrol 不试图掌控 AI 层,它只是帮你管理好提示词,让你不必为此操心。

Skill detail view with markdown content and CLI usage commands

内置系统技能

UnDercontrol 内置了系统技能,在首次启动时自动创建。这些技能是只读的——不会被意外覆盖——既是实用的默认工具,也是了解技能结构的好范例。例如,ud-cli 系统技能提供了 CLI 命令结构的完整参考,使 AI 代理可以直接使用它来操作你的任务。

系统技能在 Web 界面中以锁图标标识,与你的自定义技能并列显示。你可以像调用自定义技能一样,通过 slug 引用它们。

长期管理技能

技能是 UnDercontrol 中的一等资源,通过 Web 界面和 CLI 均支持完整的增删改查操作。

  • ud get skills — 列出群组中的所有技能
  • ud describe skill <id> — 查看某个技能的完整内容
  • ud delete skill <id> — 删除不再需要的技能
  • ud apply skill -f skills/ — 一次性应用整个目录下的技能定义

Web 编辑器适合快速编辑和浏览现有技能,CLI 则更适合自动化、批量更新,以及将提示词库作为代码来管理。

为什么这很重要

技能背后的理念很简单:好用的提示词值得保留。将它们存储在一个自托管、群组作用域的系统中,意味着它们不会因为某人离职而消失,不会淹没在聊天记录里,也不需要每个人独立摸索出同样的工作流。

这也保护了你的提示词隐私。由于 UnDercontrol 是自托管的,你的提示词库——其中往往沉淀着组织知识、内部流程和特定领域的上下文——始终存放在你自己的基础设施上。

立即开始

技能功能今天就可以在 UnDercontrol 中使用。如果你已经在运行实例,可以在侧边栏中找到技能页面。如果你是首次部署,自托管指南可以帮助你在大约十分钟内完成部署。

阅读文档部署自己的实例即可开始。

团队协作,掌控不失:UnDercontrol 的协作功能详解

· 阅读需 5 分钟
Creator of UnDercontrol

大多数效率工具把协作当作附加功能来处理——给你一个分享按钮,也许再加个评论区,就算完了。UnDercontrol 采取了截然不同的思路:群组、基于角色的权限管理、共享任务,这些都是一等功能,与应用中的其他核心模块建立在同一套基础之上。

最重要的是,你依然在私有化部署的环境中运行。启用多人协作流程,不需要把数据交给任何第三方服务。

群组的工作原理

UnDercontrol 中的群组是一个共享工作空间。可以把它理解为一个容器,容纳需要共同查看或处理同一内容的人。常见的使用场景包括:家庭成员共同追踪开支预算、小团队协调项目任务,或者两个人共同分摊生活费用。

创建一个群组只需要几秒钟:填写名称、添加描述,你就成为群组的所有者。之后,你可以生成邀请链接,邀请其他人加入。

邀请链接有一定的灵活性。你可以设置有效期,让链接在一天或一周后自动失效——在添加临时协作者时非常实用。你也可以随时撤销任意链接。这是个小细节,但当你在意谁能访问你的工作空间时,它就变得很重要。

Group management for team collaboration

基于角色的权限管理

成员加入群组后,角色决定了他们能做什么。群组层面有三种角色:

  • 所有者(Owner) — 对群组拥有完全控制权,包括成员管理、设置以及所有共享内容
  • 管理员(Admin) — 可以管理成员和邀请链接,访问所有共享内容
  • 成员(Member) — 可以根据每个条目设置的权限级别查看和操作共享资源

除群组角色外,UnDercontrol 还有系统级别的角色:Admin、User 和 Visitor。如果你为小型组织运行一个私有化实例,可以创建自定义角色,为任务、支出、预算、文件等模块分配特定的权限组合。这种级别的访问控制通常只在企业级工具中才有,而在你自己运行的私有化应用中同样可以实现。

以合适的权限共享任务

将任务共享给群组时,你可以选择权限级别:只读或读写。

只读模式适用于你希望他人了解任务进展但不允许其修改的场景——例如,管理者查看任务列表,或者伴侣需要了解日程安排但不应意外编辑内容。

读写共享则实现了真正的协同工作。群组成员可以更新任务、勾选事项,与你并肩推进。共享任务会出现在每位成员的任务列表中,不会有任何内容被埋没。

附加到共享任务的文件,群组成员可以自动访问,无需单独的文件共享步骤。只要你在任务中附上了 PDF 或图片,所有有权限的人都能看到它。

看板与共享工作流

共享看板与群组系统直接集成。创建共享看板时,系统会在后台自动创建一个对应的群组。看板创建者成为群组管理员,协作者以成员身份加入。这意味着团队的工作流程始终绑定在一套完整的权限模型上,而不是一个任何人都能偶然访问的开放链接。

Shared kanban board for team collaboration

实用建议

在创建第一个群组之前,有几点值得了解:

目前每个用户同一时间只能属于一个群组,因此请提前规划工作空间的结构。如果你同时协调一个工作项目和一个家庭预算,相关人员需要选择加入哪个群组——或者你在同一个群组下通过清晰的任务命名规范来区分两类内容。

从一开始就使用有描述性的群组名称。"家庭预算 2026"或"后端团队 Q2"在三个月后仍然一目了然,远胜于"我的群组"这类含糊的名字。

在邀请临时协作者时,务必为邀请链接设置有效期。这只需要额外两秒钟,却省去了日后手动撤销链接的麻烦。

定期检查成员列表。人员会变动,项目会结束,生活情况也会改变。保持成员列表的及时更新,是任何共享工作空间的基本维护习惯。

立即开始

如果你已经有一个正在运行的私有化实例,前往"群组"页面创建你的第一个群组。如果你还没有搭建 UnDercontrol,私有化部署指南提供了完整的配置流程——使用 Docker 可以在一小时内完成部署。

协作功能文档涵盖了每项功能的详细说明,包括完整的权限系统,以及群组与预算、资源模块之间的交互方式。

基于 Server-Sent Events 的多端实时同步

· 阅读需 5 分钟
Creator of UnDercontrol

如果你同时在浏览器标签页、桌面应用和手机上打开了 UnDercontrol,你自然希望它们保持同步。在一个地方添加任务,其他地方应该立即显示,无需刷新页面。记录一笔支出,预算应该在所有端实时更新。

这种实时同步听起来简单,但一旦考虑到重连、离线状态以及长连接的资源开销,复杂度就会迅速上升。以下是 UnDercontrol 的处理方式。

为什么选择 Server-Sent Events

WebSocket 是实时功能的常见选择,但它有额外的开销——双向连接、自定义协议处理,以及两端更高的实现复杂度。在 UnDercontrol 中,数据更新的流向几乎完全是单向的:服务端向客户端推送变更。这与 Server-Sent Events(SSE)完美契合。SSE 是所有现代浏览器内置支持的标准 HTTP 机制。

SSE 基于普通 HTTP 实现持久连接,浏览器规范内置自动重连能力,除了运行实例所用的 Go 后端外,不需要任何额外基础设施。这让自托管模式保持简洁。

工作原理

打开 UnDercontrol 时,前端会向后端建立一条 SSE 连接。你的会话被注册到一个按用户维护的连接中枢——该结构追踪你账户下所有活跃连接,涵盖各个标签页、设备以及 Electron 桌面应用。当数据发生变化(任务被更新、支出被记录、文件被重命名),后端会向内部异步事件总线发布一个事件,该事件随即广播到你用户 ID 下注册的所有连接。

这意味着你在手机上记录一笔支出,浏览器标签页会在毫秒内感知到。无需轮询,无需手动刷新。

Task list view — changes sync in real-time across all connected clients

连接的生命周期经过精心管理。连接最长保持 30 分钟,到期后会自动重连。这可以防止长时间运行的实例出现资源泄漏,同时与有自身超时规则的负载均衡器和反向代理友好兼容。如果连接因任何原因断开——网络抖动、设备休眠唤醒、代理超时——客户端会使用指数退避策略自动重连。初始延迟较短,随后逐步增加,避免短暂离线的设备在恢复上线时瞬间冲击服务器。

客户端的智能缓存更新

收到事件是一回事,知道如何处理又是另一回事。UnDercontrol 并不会在 SSE 事件到达时盲目地重新拉取全量数据。前端采用差量缓存更新策略:识别哪些内容发生了变化,在本地 Zustand store 中找到对应条目,仅更新该条记录。

例如,某个任务的状态从"进行中"变为"已完成",事件只携带该任务的最新状态。客户端将其合并到现有缓存中,列表以新状态重新渲染,其余内容保持不变。

这让界面保持流畅,避免了那种因频繁全量请求而带来的突兀刷新感。

Kanban board with live status updates pushed via SSE

乐观更新与服务端协调

SSE 与 UnDercontrol 的乐观更新模型协同工作。本地做出变更时,界面立即响应——无需等待,无需加载动画。写入操作在后台发送到服务端。成功后,服务端发布一个 SSE 事件,传播到你的其他客户端。若操作失败,本地状态回滚,并显示错误提示。

最终效果是:主设备感觉即时响应,其他设备保持一致。服务端是唯一的数据来源,SSE 是让各端与之保持同步的机制。

你能直接感受到的好处

在两个浏览器标签页中打开同一个 UnDercontrol 实例,在其中一个标签页做出修改,另一个标签页无需任何操作即可看到变更。当你在一块屏幕上查看预算概览、在另一块屏幕上记录交易时,这一特性尤为实用。

Budget overview — expense changes propagate instantly to all open views

Electron 桌面应用同样参与这套同步机制。通过 CLI 或 Chrome 扩展所做的变更,也会通过 SSE 传播到当前打开的所有端。整个多平台体验的基础,正是这一层同步机制的可靠运行。

亲自体验

这一切运行在你自己的硬件上。没有云依赖,没有第三方同步服务,数据始终在你的掌控之中。SSE 端点是标准 UnDercontrol 后端的一部分。

如果你还没有部署 UnDercontrol,自部署指南介绍了如何在几分钟内通过 Docker 完成启动。如果你已经在运行实例,同步功能已经处于激活状态——打开第二个标签页,亲眼看看效果。

部署说明和配置选项请参阅文档

用 ud CLI 在终端中管理任务

· 阅读需 4 分钟
Creator of UnDercontrol

如果你大部分时间都在终端里工作,那么每次记录任务或查看待办事项都要切换到浏览器标签页,这种上下文切换完全没有必要。ud CLI 正是为了消除这种干扰而生。它将 UnDercontrol 的全部功能——任务增删改查、笔记、查询、看板——带入你的 shell 环境,并采用你已经熟悉的命令结构。

kubectl 风格的命令,因为它好用

CLI 使用与 kubectl 相同的动词-资源模式,这种模式让无数工程师觉得上手自然。你可以 get、describe、apply 和 delete 资源,无需建立新的心智模型。

# 列出所有任务
ud get task

# 查看任务完整详情(支持短 ID 前缀)
ud describe task 3de9f82b

# 从 markdown 文件创建或更新任务
ud apply -f task.md

# 删除任务
ud delete task abc123

apply 命令值得重点介绍。你的任务就是一个带有 YAML frontmatter 的 markdown 文件。如果文件中有 id 字段,则更新已有任务;没有 id,则新建任务。这使得批量更新、脚本化工作流以及版本控制的任务定义变得简单直接。

echo '---
title: Write release notes
status: in-progress
tags:
- release
deadline: 2026-04-10
---

Draft the changelog and update the docs site.' | ud apply -f -

Task list view — what the ud CLI manages from your terminal

真正能过滤的查询语法

ud task query 提供了一种类 SQL 的过滤语言,用于查询你的任务。当任务数量多到"翻列表"不再是可行策略时,它就派上用场了。

# 本周截止的任务
ud task query "deadline BETWEEN 'today' AND '+7d'"

# 标记为 urgent 的进行中任务
ud task query "(status = 'todo' OR status = 'in-progress') AND tags = 'urgent'"

# 标题搜索
ud task query "title ILIKE '%api%'"

如果你不想考虑语法,ud task nlquery 支持直接输入自然语言,并通过 AI 将其转译为查询:

ud task nlquery "show me overdue tasks"
ud task nlquery "tasks tagged with work that are not done"

两个命令都支持 --sort--order--limit 参数,便于分页和排序,可以干净地组合进脚本或 shell 别名中。

用笔记记录进度

每个任务都支持笔记——简短的自由格式条目,充当持续更新的进度日志。这对于记录你实际做了什么很有用,而不只是最终状态。

ud task note add 3de9f82b "Finished the backend changes, opening PR now"
ud task note ls 3de9f82b

笔记也让 CLI 天然适合 AI 智能体工作流。智能体可以从计划文件创建任务,在每个步骤追加进度笔记,最后标记任务完成——全程无需打开浏览器。团队的其他成员可以在 UnDercontrol Web 界面或桌面应用中看到完整的历史记录。这种交接方式轻量、实用,真正跑得通。

需要可视化时,用交互式 TUI

不带任何参数运行 ud,会打开终端 UI——一个支持键盘操作的看板式界面,带有 vim 风格的按键绑定。

Built-in terminal with ud CLI commands

按键操作
j / k在任务间移动
Enter打开任务详情
i新建任务
x切换状态
/搜索
f文件选择器(模糊搜索本地文件以创建任务)

文件选择器是个亮点。按 f,在当前目录中模糊搜索 markdown 文件,它就会变成一个任务——第一行作为标题,其余内容作为描述。如果你习惯在项目仓库中用 markdown 记笔记,并想把它们纳入任务追踪,这个功能非常实用。

多上下文支持多个服务器

如果你在多个环境中自托管 UnDercontrol——个人、工作、测试实例——上下文系统的处理方式与 kubectl 完全相同。

ud config set-context work --api-url https://ud.company.com
ud login --context work

# 单次命令使用不同上下文
UD_CONTEXT=personal ud get task

配置文件位于 ~/.config/ud/config.yaml。你也可以完全通过环境变量(UD_API_URLUD_API_KEYUD_TOKEN)驱动 CLI,无需修改配置文件,在 CI 流水线中同样可用。

快速开始

通过 npm、Homebrew 或一行 curl 命令安装:

npm install -g @oatnil/ud
# 或
brew install oatnil-top/ud/ud
# 或
curl -fsSL https://get.oatnil.com/ud | bash

然后指向你的 UnDercontrol 实例:

ud login

完整的命令参考——包括文件附件、多上下文认证和高级查询语法——请查阅 CLI Reference 文档。如果你还没有运行 UnDercontrol,自托管指南 介绍了如何在几分钟内用 Docker 启动一个服务器。

使用 CLI Context 管理多个账户

· 阅读需 4 分钟
Creator of UnDercontrol

如果你同时运行多个 UnDercontrol 实例——比如一个个人服务器和一个工作服务器——你大概已经体会过在不同 API 端点和凭据之间反复切换的麻烦。ud CLI 内置了一套仿照 kubectl 设计的 context 系统,切换账户只需一条命令。

高级用户查询与已保存筛选器——UnDercontrol 进阶指南

· 阅读需 4 分钟
Creator of UnDercontrol

当 UnDercontrol 里的任务积累到一定数量,"滚动浏览"这种方式就会开始失效。你清楚地知道自己在找什么——已逾期的项目、所有标记了 work 且仍在进行中的任务、还没有截止日期的待办——但仅靠状态筛选,很难快速定位到它们。

本文介绍 UnDercontrol 内置的查询系统:一套类 SQL 语法,可在 Web 界面、CLI、自定义视图、看板以及已保存查询中统一使用。一旦上手,你会发现自己几乎每天都在用它。

查询语法

这套语法在设计上与 SQL WHERE 子句非常接近。如果你写过数据库查询,会立刻感到熟悉;如果没有,基础部分大约五分钟就能掌握。

一个简单的查询如下:

status = 'todo' AND deadline <= 'today'

这会找出所有状态为待办、且截止日期在今天或更早的任务——也就是已逾期的待办项。

你可以在此基础上加入标签、文本搜索、日期范围和自定义字段:

(deadline <= 'today' OR tags = 'urgent') AND status != 'done' AND status != 'archived'

这是一个可靠的"当前需要处理"查询。将它保存为已保存查询(下文详述),就有了一个一键直达的紧急任务列表。

Task search with query syntax filtering

日期时间表达式

语法中较为实用的一部分是相对日期支持。你不需要写死具体日期,而是使用 '-7d''+1w' 或直接写 'today' 这样的表达式。

-- 过去一周内创建的任务
created_at >= '-7d'

-- 未来一个月内到期
deadline BETWEEN 'today' AND '+1m'

-- 今天有更新
updated_at >= 'today'

支持的时间单位包括天(d)、周(w)、月(m)和年(y),+ 表示未来,- 表示过去。当你需要固定日期时,2025-06-01 这样的标准 ISO 8601 格式同样适用。

文本搜索与自定义字段

文本搜索使用 LIKE(区分大小写)和 ILIKE(不区分大小写),以 % 作为通配符:

title ILIKE '%api%'

自定义字段需加上 cf. 前缀:

cf.priority > 3 AND cf.department = 'engineering'

自定义字段根据其类型支持完整的比较运算符——数字、文本、下拉选项、复选框和用户引用均可使用。

自然语言查询

熟悉语法后,手写查询其实很快。但如果你更倾向于直接描述需求,AI 集成功能可以自动完成转换。

在 Web 界面中,打开任务页面的 AI Chat 面板,输入类似"显示带有 work 标签的逾期任务",AI 会自动生成结构化查询并执行。

在 CLI 中,使用 ud task nlquery

ud task nlquery "tasks I need to finish this week"
ud task nlquery "high priority engineering items with no deadline"

如果想少打几个字,nl 别名同样有效。此功能需要配置 AI 提供商,但一旦设置完成,它能处理相当自然的描述方式。

已保存查询

这是查询系统真正在日常使用中发挥价值的地方。已保存查询允许你为任意查询命名并存储,之后只需在侧边栏点击一下即可执行。

Saved queries for quick access to filtered views

以下几个查询值得立即配置:

名称查询
已逾期deadline < 'today' AND status != 'done' AND status != 'archived'
本周到期deadline BETWEEN 'today' AND '+7d' AND status != 'done'
未规划deadline IS NULL AND status = 'todo'
近期活跃updated_at >= '-7d' AND status IN ('todo', 'in-progress')

你可以将常用查询置顶,通过拖拽调整顺序,并随时编辑。点击已保存查询后,结果会在当前页面内展开,无需跳转。

在 CLI 中使用查询

CLI 通过 ud task query 支持相同的查询语法:

ud task query "status = 'todo'" --sort deadline --order asc
ud task query "(status = 'todo' OR status = 'in-progress') AND tags = 'work'"

分页(--page--limit)和排序(--sort--order)参数均可使用。这使得将查询结果导入其他工具或在 shell 脚本中调用查询变得非常方便。

开始使用

完整的查询语法参考文档请见查询语法文档,包含所有运算符、日期时间表达式格式,以及一套可直接复用和改写的实用示例。

如果你还没有部署 UnDercontrol,自托管指南介绍了如何通过 Docker 完成部署。你的数据始终保存在自己的基础设施上——这正是它的核心价值所在。

让文件与工作同在:UnDercontrol 的资源管理

· 阅读需 5 分钟
Creator of UnDercontrol

大多数效率工具把文件存储当作附加功能——某个角落里的文件夹,与它所支撑的工作毫无关联。UnDercontrol 的做法不同:文件直接存放在它所属的任务、支出和预算旁边,收据跟着它对应的支出走,设计图跟着它所服务的任务走。

下面介绍资源管理系统在实际使用中的工作方式。

Task list view — files attach directly to tasks, expenses, and budgets

按你的工作习惯上传

将文件导入 UnDercontrol 不应该每次都要打开文件选择器绕一圈。目前支持三种主要上传方式:

拖放上传 — 打开资源页面,或在任务、支出的附件面板中,直接将文件拖入即可。支持单文件和批量上传。

剪贴板粘贴 — 按下 Ctrl+V,剪贴板中的文件会立即上传。这对截图尤其方便。对着收据或界面 bug 截个图,切换到 UnDercontrol,粘贴。无需先保存到磁盘。

CLI 上传 — 如果你习惯在终端工作,ud CLI 可以直接处理上传:

ud upload resource ./receipt.png --entity-type expense --entity-id exp-456

这在自动化工作流中很有用,比如将导出的报告自动附加到每月预算审查任务中。

一次附加,随处引用

同一个资源可以关联到多个条目。如果有一份合同 PDF 同时与某个预算和某个任务相关,你可以将它分别附加到两者——无需重复文件,也无需翻找文件夹。当任务标记为完成后,可以取消该文件与任务的关联,同时保留它与预算的附加关系。

检查器面板会清晰显示某个文件附加到了哪些条目,让你随时掌握文件的引用情况。

快速找到所需文件

资源页面提供所有已上传文件的完整概览,并内置筛选功能。你可以按文件类型、附加的实体类型(任务、支出、预算、账户)或日期范围进行筛选。对于图片,图库视图会显示缩略图,让你无需逐一打开便能快速浏览一批收据或截图。

检查器还会显示照片的 EXIF 元数据——如果你需要确认照片的拍摄时间或地点,这非常实用。

Resource management page showing uploaded files with thumbnails and metadata

存储:本地或 S3

由于 UnDercontrol 是自托管的,你可以完全掌控文件的存储位置。默认使用本地磁盘存储,对于运行在家庭服务器或 VPS 上的个人使用场景完全够用。对于更大规模的部署或远程访问需求,可以配置兼容 S3 的对象存储——AWS S3、Backblaze B2、MinIO,用你已有的方案即可。

关键一点:你的文件不会经过任何第三方服务,直接从浏览器传输到你自己的服务器。

存储限制可自行配置。普通用户默认获得 1 GB 空间,单文件上限 10 MB。管理员则不受限制。

内置 Drawio 图表

如果你的工作流程涉及系统图、流程图或架构草图,UnDercontrol 内置了 drawio 支持。你可以直接在应用内创建和编辑图表,无需导出为 PNG,也无需切换到其他工具再重新上传。图表文件作为资源附加在对应的任务或笔记上。

AI 识别图片内容

对于收据和文档扫描件,AI 集成功能值得了解。你可以打开一张图片资源,让 AI 从中提取信息——比如收据上的明细条目、扫描表格中的文字。这与支出追踪工作流天然契合:拍一张收据照片,附加到支出条目,让 AI 自动提取金额和商家名称。

日常使用场景

举一个实际的例子:你在追踪一个自由职业项目。有一个"审查客户合同"的任务,你将合同 PDF 附加到该任务。随后,你为项目采购的软件记录了一笔支出,并将发票附加到该支出条目。这两个文件都会出现在资源页面中——你可以按实体类型筛选,只查看支出附件,也可以一起查看,对整个项目进行完整的文件审计。

所有内容集中在一处,无需外部文件托管,也无需翻找邮件记录。

Budget overview — receipts and invoices attach to expenses within budgets

开始使用

如果你已经在运行 UnDercontrol,资源页面可以在主导航中找到。如果你正在评估是否自托管,部署指南 涵盖了实例搭建的全部流程,包括存储配置。

资源管理文档 提供了 CLI 命令、存储配置和实体附加选项的完整参考。

用自托管掌控你的数据

· 阅读需 4 分钟
Creator of UnDercontrol

这种挫败感往往是慢慢积累的。你注册了一款效率工具,把任务和财务数据迁移进去,围绕它建立起工作习惯——然后某一天,定价突然变了,公司转型了,甚至服务直接关停了。你的数据就此消失,或者被锁在一个导出按钮后面,导出来的东西几乎无法使用。

UnDercontrol 从一开始就是为了彻底避免这种情况而设计的。它支持自托管,意味着你在自己掌控的基础设施上运行它,数据存放在你指定的地方。

UnDercontrol dashboard — self-hosted and fully under your control

用 Docker Compose 几分钟内完成部署

对大多数人来说,Docker Compose 是最快的启动方式。一个 docker-compose.yml 文件就能拉取后端和前端镜像,将它们连接起来,几分钟内就能在你的服务器或本地机器上运行 UnDercontrol。

一个最简配置大致如下:一个将数据目录挂载为卷的后端服务、一个指向它的前端服务,以及可选的 Caddy 或 Nginx 反向代理。对于单用户或小家庭部署来说,这就是全部了。不需要托管云账户,不需要第三方服务的 API 密钥,数据不会离开你的网络。

Docker 镜像设计得轻量且行为可预期。它不会回连服务器,初次拉取后无需网络连接,所有内容都存储在你配置的路径下。

面向团队和进阶用户的 Kubernetes 部署

如果你在使用 Kubernetes 搭建家庭实验室,或者希望获得正式编排带来的可靠性,UnDercontrol 同样提供了 Kubernetes 清单文件。你可以使用标准的 Deployment 和 Service、用于数据持久化的 PersistentVolumeClaim,以及用于环境配置的 ConfigMap。

这对于为小型团队——家庭、朋友群组、小公司——部署 UnDercontrol 尤为实用。你可以设置合理的资源限制、滚动更新,并在需要时独立扩展后端。Kubernetes 还让添加 Ingress 规则、TLS 终止和命名空间级别的隔离变得非常简单。

SQLite 还是 PostgreSQL——按需选择

UnDercontrol 在数据库选择上给了你充分的灵活性。对于单用户或少量用户的场景,SQLite 是默认选项,而且表现非常出色。无需管理数据库服务器,无需配置连接池,备份就是复制一个文件那么简单。在这种场景下,SQLite 的能力出乎意料地强,运维负担几乎为零。

当你需要更多能力时——并发用户、大规模数据集、与现有数据库基础设施集成——切换到 PostgreSQL 只需修改环境变量并运行迁移。两种后端的 Schema 完全一致,不需要重新设计任何东西,只需将应用指向你的 Postgres 实例即可。

这种灵活性很重要,因为你的需求会随时间变化。从 SQLite 起步、之后再迁移是一条官方支持的路径,而不是事后才想到的补丁。

数据完全自主意味着什么

自托管意味着你的任务、财务记录、上传的文件以及 AI 对话历史,全部存储在你掌控的存储介质上。想迁移到其他服务器,只需复制数据目录并更新部署配置。想备份所有内容,备份那个目录就行。即使你决定彻底停用 UnDercontrol,数据依然在那里,格式可读。

不需要注销账户,不需要提交工单,不需要等待期。数据属于你,因为它从一开始就在你的机器上。

这也意味着你控制着访问权限。在私有网络或 VPN 后面运行 UnDercontrol,你的财务数据就不会触及公共互联网,除非你主动将其路由出去。对于追踪详细预算或敏感个人信息的用户来说,这绝非小事。

无供应商锁定,由设计保证

后端 API 有完整文档,且对外开放。CLI 使用 kubectl 风格的命令,与 Web 应用调用的是同一套 API。你可以编写脚本调用它、与其他工具集成,或者构建自己的客户端。任务和笔记的格式设计上注重可移植性。

我们的目标始终是:让你持续使用它,是因为它真的有用——而不是因为迁移走的代价太高、懒得折腾。

开始使用

部署指南详细介绍了 Docker Compose 配置、Kubernetes 清单、数据库配置以及备份策略。如果你有一台服务器或闲置的机器,今天就能跑起来一个可用实例。

查阅自托管文档开始部署,或者在 GitHub 上提 Issue,如果配置过程中有任何地方不符合预期。