ITADN
timothy-agent/timothy · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

提摩太

CI Release Go React TypeScript PostgreSQL License: MIT

Timothy

自托管的个人 AI 助手:聊天、成本跟踪、任务和智能体,运行在您自己的硬件上,可与您配置的任意 LLM 提供商进行交互。

状态:早期,正在积极开发中。

带有预构建镜像的 Alpha 版本可在发布页面]获取;请预期各版本间存在粗糙之处和破坏性变更。

当前可用的功能

  • 多提供商聊天:通过单一网关支持 Anthropic、Amazon Bedrock 以及任何兼容 OpenAI 的 API;提供商、模型和按任务的路由均为数据库配置,可在运行时通过设置面板编辑并支持热重载。
  • 持久会话:每个对话都是一个仅追加的事件日志;在流式传输中途终止容器,会话将恢复并精确重放。
  • 工具、权限、技能:代理循环在约束/权限链背后执行工具(破坏性操作需要在 UI 中明确批准);技能包按任务懒加载。
  • 任务:具有纯状态机的长时运行代理任务,由测试框架拥有的验证(在任何模型声明生效之前,产物必须存在),按任务隔离的沙箱、预算和 LLM 审查;周期性任务由 cron 计划触发。
  • 长期记忆:带有确认队列的分阶段事实提取,在严格的令牌预算下使用混合 pgvector 检索(向量 + 文本 + 实体,RRF 融合)。
  • 成本核算:每个请求都记录在账本中,具有诚实的定价(未知价格记录为 null,绝不猜测);使用量仪表板、带有警报的支出预算,以及每个服务上的 Prometheus 指标。
  • 隐私底线:输出包含敏感数据(原始电子邮件)的工具会将其回合的其余部分以及所有下游侧调用(记忆提取、压缩)固定到一个专用路由,您可以将其链接到本地模型。

架构

单个公共 API 背后的 Go 微服务,一个 PostgreSQL 数据库,React Web UI。全部通过 Docker Compose 运行。

服务角色
brain公共 API:聊天编排、智能体循环、任务、基于事件的会话、SSE 流式传输
gateway内部 LLM 网关:多提供商路由、成本账本
memoryd内部记忆服务:基于 pgvector 的召回
sandboxd持有 Docker socket 的内部服务:每任务沙箱容器
webReact + Tailwind 界面:聊天、任务、用量、设置
searxngweb_search 工具的内部元搜索后端
markitdown内部 Python 边车:文件→Markdown 转换
whisper内部 Python 边车:Web 麦克风按钮的本地语音转文本

外加 Postgres(18 + pgvector),仅内部使用,不映射主机端口。迁移嵌入在每个 Go 二进制文件中,并在启动时自动应用;没有单独的 migrate 命令。每个 Go 服务都暴露 GET /healthGET /metrics

会话是一个仅追加的事件日志:每一轮对话、工具执行和压缩操作都是不可变的事件,因此对话可以在流式传输中途崩溃后存活,并精确地按原样重放。

已发布的端口(其余均为 compose 内部使用):

端口用途
3300Web UI
8300Brain(公共 API)
3301Vite 开发服务器(make dev

快速开始(预构建镜像)

运行 Timothy 的最快方式:无需 Go/Node 工具链,无需构建步骤,只需 Docker 和已发布的镜像。

  1. 创建一个空目录,并从最新 release下载安装程序。在 Timothy 处于 alpha 阶段期间,每个 release 都标记为预发布版本,因此 GitHub 的 /releases/latest 重定向无法解析;请改为查找最新的标签:

    mkdir timothy && cd timothy
    TAG=$(curl -fsSL https://api.github.com/repos/timothy-agent/timothy/releases \
      | grep -E '"tag_name"|"published_at"' | paste - - \
      | sed -E 's/.*"tag_name": "([^"]+)".*"published_at": "([^"]+)".*/\2 \1/' \
      | sort -r | head -1 | awk '{print $2}')
    curl -fsSLo install.sh "https://github.com/timothy-agent/timothy/releases/download/$TAG/install.sh"
  2. 运行前请阅读 install.sh。然后运行它:

    sh install.sh

它会下载 docker-compose.ymlenv.example,生成带有新密钥的 .envPOSTGRES_PASSWORDTIMOTHY_MASTER_KEYTIMOTHY_API_TOKEN),拉取镜像,启动服务栈,并在 Web UI 就绪后打印一个魔法登录链接。

  1. 打开打印出的链接:Web UI 会从 URL 中的令牌自动登录。

稍后升级时:在 .env 中更新 TIMOTHY_VERSION,运行 docker compose pull && docker compose up -d,然后运行 docker pull ghcr.io/timothy-agent/timothy-sandbox:$TIMOTHY_VERSION(每个任务的沙箱镜像 sandboxd 通过 Docker 套接字拉取,独立于 compose 自身的拉取)——或者只需重新运行 install.sh,它会执行以上所有操作(它不会修改现有的 .env,仅刷新 docker-compose.yml、searxng 配置和沙箱镜像)。

本 README 的其余部分介绍如何从源代码构建和运行。

从源代码构建

前提条件:

  • Docker(Desktop,或引擎 + compose 插件)。
  • 一个拥有有效令牌的 hugeicons.com 账户。Web UI 的图标是 HugeIcons Pro(付费图标集),构建 web 镜像时需要该令牌;如果没有它,make up 将在 Web 构建步骤中失败。上述预构建镜像的快速入门不需要此令牌。
  1. 复制 env 文件并填写所需的值:

    cp deploy/env.example deploy/.env

打开 deploy/.env 并设置:

  • POSTGRES_PASSWORD:compose 若缺少此项将拒绝启动。
  • TIMOTHY_MASTER_KEY:使用 openssl rand -base64 32 生成。这是加密密钥存储的信任根(provider API 密钥、OAuth 令牌均受其保护)。若此项为空,Compose 将硬性失败。请备份此项:丢失它会导致所有已存储的密钥无法恢复。
  • TIMOTHY_API_TOKEN:使用 openssl rand -hex 32 生成。API 的 Bearer 令牌;若此项为空,所有请求将返回 401。
  • HUGEICONS_TOKEN:您的 HugeIcons Pro 令牌,用于构建 web 镜像。
  1. (可选)Missions 沙箱。deploy/env.example 会预填 MISSION_SANDBOX_IMAGE=timothy-sandbox:latest,但在您构建之前该镜像并不存在:

    make sandbox-image

如果不需要将任务隔离在各自的容器中,请跳过此步骤,并在 .env 中保持 MISSION_SANDBOX_IMAGE 为空;此时任务 shell 命令将在进程内运行。

  1. (仅限 Linux)设置 DOCKER_SOCK_GID,以便 sandboxd 可以使用 Docker 套接字:

    stat -c '%g' /var/run/docker.sock

将该数字填入 .env。在 Docker Desktop 上,默认值 0 可直接使用。注意:挂载 docker.sock 会提供 sandboxd 对主机的等效 root 访问权限。它运行在独立的 compose 网络中,以只读模式运行,并丢弃了所有 capabilities,但 socket 本身是信任边界,因此仅在你控制的主机上运行此配置。

  1. 启动该栈:

    make up

Web UI: http://localhost:3300. API: http://localhost:8300.

  1. 首次登录。没有登录页面:Web UI 在首次找不到 API 令牌时会自动打开一个设置对话框,要求输入 API 令牌。请粘贴 deploy/.env 中的 TIMOTHY_API_TOKEN 值。它存储在浏览器的 localStorage 中。

  2. 添加一个提供商。全新安装没有任何 LLM 提供商,也未配置路由,因此在完成此操作之前,Timothy 无法回答任何问题。前往 Settings → Providers,选择一个预设磁贴(OpenAI、Anthropic、Bedrock、GLM、Grok、Ollama 或自定义的 OpenAI 兼容端点),填写表单,并在添加之前运行连接测试。您输入的 API 密钥会被加密到密钥存储中(默认后端 db,使用 TIMOTHY_MASTER_KEY 加密);数据库仅保存对它的引用,从不保存原始值,且它绝不会出现在 .env、日志或 API 响应中。创建第一个提供商会自动引导 Timothy 正常工作所需的 4 条路由(defaultsummarizeembeddingvision);否则,路由完全由用户从 Settings → Routing 进行管理(创建、编辑链/策略、删除)。

可选:本地模型

在主机上原生运行 Ollama,而不是在容器中运行:容器化的 Ollama 只能使用 CPU,而主机安装可以使用 Metal 或 CUDA。然后使用 Ollama 预设添加一个提供商;它会预填基础 URL http://host.docker.internal:11434/v1。在 Linux 上,host.docker.internal 可能需要在您的 Docker 配置中有一个 host-gateway 条目才能解析。

可选:Google 连接器(Gmail、Calendar)

  1. 在 Google Cloud Console 中创建一个 OAuth 客户端,类型选择 Web application
  2. TIMOTHY_PUBLIC_URL 中的 .env 设置为你的浏览器访问 Timothy 所使用的 URL(例如 http://localhost:3300)。这必须与你在 Google 注册的内容一致,否则 OAuth 回调将失败。
  3. <TIMOTHY_PUBLIC_URL>/v1/connectors/oauth/callback 添加到 OAuth 客户端的授权重定向 URI 中。
  4. 在 UI 中:Settings → Connectors,选择 Gmail 或 Calendar 磁贴,粘贴客户端 ID 和客户端密钥,并完成同意流程。请求的权限范围:gmail.modifycalendar

当 Google OAuth 应用处于“Testing”模式(新 Cloud 项目的默认设置)时,刷新令牌大约每 7 天过期一次;当连接器停止工作时,请从 Settings 重新连接,或发布 OAuth 应用以避免过期。

可选:GitHub 连接器

Settings → Connectors 中配置为 MCP 预设:将 GitHub 个人访问令牌粘贴到 Bearer token 字段中。

可选:Amazon Bedrock

创建一个仅限定于 bedrock:InvokeModel* 范围的 IAM 用户,生成访问密钥,并将访问密钥 ID 和秘密访问密钥输入 Settings → Providers 中 Bedrock 提供商的相应字段。从下拉菜单中选择一个区域;无需 ~/.aws,无需 SSO,主机上无需运行任何内容。

运行该技术栈

make up      # start (builds images as needed)
make down    # stop
make logs    # follow logs for all services

代码更改后,重建并重启单个服务:

make brain      # or gateway, memoryd, web, markitdown, whisper, sandboxd

备份

Postgres 没有主机端口,因此请通过容器进行备份:

docker compose -f deploy/docker-compose.yml exec postgres pg_dump -U timothy timothy > backup.sql

完整备份是 pgdata 卷加上 deploy/.env:如果没有 TIMOTHY_MASTER_KEY,该转储中的加密密钥将无法恢复。

升级

git pull
make up

迁移仅支持增量操作,一旦应用后绝不修改,并在服务启动时自动执行;无需单独的迁移步骤。

本地开发

Go 工具链完全在容器中运行;无需在主机上安装 Go。

make build   # compile everything
make test    # unit tests
make vet     # go vet
make lint    # golangci-lint

前端开发,支持热重载:

make dev   # Vite dev server on :3301, proxies /v1 to brain

make test-integrationmake canary 需要启动 compose 栈(make up 优先)。

设计决策以 D-0XX 标记的形式记录在代码注释中,位于其所解释的代码旁边。

License

MIT