- 人工智能
- AI Agent
- Agent 框架
- 后端
- 工具调用
【免费下载链接】eve
The Open Framework for Building Agents
本指南面向希望在 Eve 生态中快速搭建"持久化个人 AI 助手"的开发者,以仓库内apps/templates/personal-agent-template模板(下称 Personal Agent Template)为研究对象,系统讲解其双服务架构、环境变量配置、内部 API 通信模式、长期记忆流程以及自定义与部署全流程。读完本文后,你将掌握该模板从本地启动、接入 Slack / iMessage / Linear 到定制自己的 Agent 与记忆体系的一整套实战方案,并能读懂其源码级实现细节。
模板是什么
Personal Agent Template 是一个由 Eve 与 Nuxt 4 驱动的开源个人 AI 助手模板,定位为"durable personal AI assistant"。它的核心卖点是:Web 聊天、Slack、iMessage 三种交互表面共享同一个 Agent、同一份长期记忆,且所有记忆写入都必须经过用户显式批准。模板默认以V作为示例 persona,你可直接 fork 后按需改造。
在仓库中,模板的入口文档apps/templates/personal-agent-template/CLAUDE.md以@AGENTS.md的方式引入其配套的 AI 编码助手速查文档,后者汇总了全部开发要点:命令速查、目录结构、文档索引、内部 API 调用模式、记忆流程与自定义检查清单。本文将沿这条主线展开,并结合 docs/ARCHITECTURE.md、docs/ENVIRONMENT.md、docs/CUSTOMIZATION.md 三份文档及源码做深度扩充。
快速参考:常用命令一览
在开始之前,先熟悉模板的构建与开发命令(定义见 package.json):
| 命令 | 作用 |
|---|---|
pnpm install | 安装依赖 |
pnpm dev | 启动 Nuxt Web 应用(本地http://localhost:3000) |
pnpm dev:all | 通过 Vercel CLI 启动本地双服务图(Nuxt + Eve agent 对等服务) |
pnpm build | 生产构建(内部为eve build+nuxt build两步) |
pnpm typecheck | TypeScript 类型检查 |
pnpm db:generate | 生成 Drizzle 迁移文件 |
pnpm db:migrate | 应用数据库迁移 |
需要说明的是,模板要求 Node.js 24+ 与 pnpm(engines.node: ">=24"、packageManager: pnpm@11.25.0)。
项目结构:三层各司其职
personal-agent-template/ ├── agent/ # Eve agent(channels、tools、skills、connections) ├── apps/web/ # Nuxt UI、Nitro API、共享应用代码 ├── lib/ # 跨层共享类型与常量(agent 与 web 共用) ├── vercel.ts # Vercel 对等服务编排 └── docs/ # 架构、环境变量、自定义指南关键子目录职责如下:
agent/:Eve Agent 的全部逻辑,包括agent.ts(模型配置)、channels/(eve、slack、sendblue三个渠道)、tools/(weather、save_memory、github)、skills/(如daily-summary.md)、connections/(Linear MCP)、lib/(基础指令、内存/ Slack/ 电话内部 API 客户端)、instructions.ts(session.started钩子,用于记忆注入)。apps/web/:Nuxt 前端(app/)、Nitro 服务端(server/,含/api/*、/api/internal/*、数据库 schema 与迁移、Better Auth)以及跨层共享代码(shared/)。lib/:Agent 与 Web 两端共享的常量与类型,例如lib/agent.ts(品牌信息)、lib/types/memory.ts(记忆类别)、lib/connect.ts(Vercel Connect connector UID)。
#号 import 别名("#*": "./agent/*")让 agent 目录内的文件可以以#agent/xxx形式被 Web 侧引用,这是模板刻意设计的共享通道。
系统架构:Vercel 上的对等双服务
模板在 Vercel 上以两个协作服务运行,vercel.ts通过withEve在构建期编排这两个对等服务:
| Vercel 服务 | 入口 | 职责 |
|---|---|---|
web | / | Nuxt UI + Nitro API |
eve | /_eve_internal/eve | Eve agent 运行时 |
// apps/templates/personal-agent-template/vercel.ts import { withEve } from "eve/vercel"; export default await withEve({ services: { web: { framework: "nuxt", root: "apps/web" }, }, routes: [{ src: "^(.*)$", destination: { type: "service", service: "web" } }], });整体数据流为:
用户表面(Web 聊天 · Slack DM/提及 · iMessage/Sendblue) │ ▼ Eve agent(channels: eve · slack · sendblue / tools: weather · save_memory / connections: Linear MCP) │ HTTP + Authorization: Bearer <INTERNAL_API_SECRET> ▼ Nuxt 应用(/api/* 公开 API · /api/internal/* agent 专用 · Better Auth · NuxtHub SQLite) │ ▼ Vercel Connect(Linear · Slack 等集成)也就是说:用户从任意渠道发消息,都由 Eve Agent 处理;Agent 需要读写业务数据时,通过带 Bearer 密钥的内部 API 回调 Nuxt;Nuxt 负责认证、数据库与集成授权。这种"Agent 无状态、数据收敛在 Web 服务"的设计,是模板实现跨渠道持久化的基石。
内部 API 模式:Agent 与 Nuxt 的通信契约
模板中最值得复用的工程模式是"Agent 侧客户端 →/api/internal/*→server/utils/*"这一 HTTP 调用链:
agent/lib/*-internal.ts → /api/internal/* → server/utils/*所有/api/internal/*路由都要求请求头携带Authorization: Bearer <INTERNAL_API_SECRET>,校验逻辑集中在 apps/web/server/utils/internal-api.ts:
export function requireInternalRequest(event: H3Event) { const secret = process.env.INTERNAL_API_SECRET?.trim(); if (!secret) { throw createError({ statusCode: 503, statusMessage: "Internal API is not configured" }); } const authorization = getRequestHeader(event, "authorization"); if (authorization !== `Bearer ${secret}`) { throw createError({ statusCode: 401, statusMessage: "Unauthorized" }); } }Agent 侧的调用封装在 agent/lib/internal-api.ts:appOrigin()依次取BETTER_AUTH_URL→VERCEL_URL→ 默认http://localhost:3000,internalHeaders()则拼装Bearer头并强制要求INTERNAL_API_SECRET已配置。
现有内部路由清单:
| 路由 | 用途 |
|---|---|
GET /api/internal/memory | 拉取用户记忆,用于会话注入 |
POST /api/internal/memory | 由 Agent 工具保存记忆 |
GET /api/internal/phone/link | 根据电话号码解析 App 用户(Sendblue/iMessage) |
GET /api/internal/slack/link/member | 根据 Slack 用户解析 App 用户 |
POST /api/internal/slack/link/consume | 消费 Slack 链接码 |
例如 apps/web/server/api/internal/memory.get.ts 内部会并行调用getOrCreateProfileForUser与listMemoryForUser,返回{ profile, memory };而memory.post.ts用 zod 校验{ userId, category, content, source }后调用setMemoryForCategory落库。这组路由被以下 Agent 侧客户端消费:
agent/lib/memory-internal.ts—fetchUserContext(GET)与saveMemoryRemote(POST);agent/lib/phone-internal.ts/agent/lib/slack-internal.ts— 渠道身份绑定。
环境变量:从本地三件套到生产全量
最小启动集(本地开发只需这三个)
| 变量 | 获取方式 |
|---|---|
BETTER_AUTH_SECRET | 执行openssl rand -base64 32 |
BETTER_AUTH_URL | 本地为http://localhost:3000,生产为你的线上 URL |
INTERNAL_API_SECRET | 执行openssl rand -base64 32(web 与 eve 两个服务必须一致) |
cp .env.example .env这三个变量足以支撑本地开发。上 Vercel 时需在web 与 eve 两个服务上都配置,并额外准备数据库。
数据库:本地 SQLite 与线上 Turso
本地开发时,NuxtHub(hub.db: "sqlite")直接使用.data/db/sqlite.db文件,无需任何配置。但在 Vercel 等 serverless 平台无法创建本地文件,若不配置托管数据库,每个请求都会报错:
Error: ConnectionFailed("Unable to open connection to local database .../.data/db/sqlite.db: 14")解决方案是从 Vercel Marketplace 开通 Turso 数据库(README 中的 Deploy 按钮会自动附带,也可以对已有项目执行vercel integration add turso)。这会为项目注入TURSO_DATABASE_URL与TURSO_AUTH_TOKEN;NuxtHub 在构建期检测到这两个变量后自动从本地文件切换到远端 libSQL,因此配置后需要重新部署。随后拉取环境并迁移:
vercel env pull .env --yes pnpm db:migrate可选变量NUXT_PUBLIC_SITE_URL用于 SEO 规范化 URL(Open Graph、Twitter card、canonical),缺省时回退到请求源地址。
认证与内部密钥
BETTER_AUTH_SECRET(必需):Better Auth 用于签名会话与令牌的随机密钥。BETTER_AUTH_URL(必需):Nuxt 应用的公开 URL,既用于认证回调,也作为 Agent → Nuxt 内部 API 调用的基础 URL。INTERNAL_API_SECRET(必需):Eve agent 服务与 Nuxt 内部 API 共享的 Bearer 令牌,用于记忆读写、Slack 账号绑定、iMessage 电话绑定。两个服务必须完全一致;缺失或不一致时,记忆注入、Slack 绑定、iMessage 认证会静默失败或返回 401。
Sendblue(iMessage,可选)
以下变量设置在eve服务上(BETTER_AUTH_URL则两个服务都要设,以便 Agent 解析电话绑定):
| 变量 | 必填 | 说明 |
|---|---|---|
SENDBLUE_API_KEY | 是 | Sendblue 控制台的 API key ID |
SENDBLUE_API_SECRET | 是 | API 密钥 |
SENDBLUE_FROM_NUMBER | 是 | 你的 Sendblue 号码(E.164 格式,如+15551234567) |
SENDBLUE_WEBHOOK_SECRET | 是 | 通过sb-signing-secret头校验的共享密钥 |
SENDBLUE_STATUS_CALLBACK_URL | 否 | 外发消息的送达状态回调 |
SENDBLUE_ALLOWED_SERVICES | 否 | 逗号分隔的服务白名单,默认仅iMessage,设为iMessage,SMS,RCS可全部接受 |
AI 模型
模板不在.env.example中定义 AI 密钥,默认模型在 agent/agent.ts 中:
export default defineAgent({ model: "anthropic/claude-sonnet-4.6", modelOptions: { providerOptions: { anthropic: { thinking: { type: "enabled", budgetTokens: 2048 }, }, }, }, });在 Vercel 上由 Eve 平台负责 provider 配置;本地开发时按 Eve 文档为你选择的 provider 配置环境。
本地勿提交的文件
.env(本地密钥)、.data/(NuxtHub SQLite)、.eve/(Eve 开发缓存)、.vercel/(Vercel CLI 链接元数据)均已被 gitignore。重置本地数据库:
rm -rf .data/db && pnpm db:migrate长期记忆:从注入到保存的完整闭环
记忆是模板的灵魂功能,其数据流可分为三个环节:
1. 会话注入(session.started)
agent/instructions.ts 监听session.started事件:先取ctx.session.auth.current?.principalId,若用户已认证则调用fetchUserContext(userId)拉取GET /api/internal/memory返回的{ profile, memory },再经buildUserContextPrompt拼装成"关于用户 + 记忆"的提示段落,追加到BASE_INSTRUCTIONS之后注入本会话。
提示段落的结构(agent/lib/memory-internal.ts):
# About this user:bio(如有)、时区、首选语言;# Memory:按类别逐个输出## <类别名>+ 该类别完整内容。
注意:注入发生在会话建立时,因此导入或修改记忆后必须新开一个聊天,Agent 才会拾取最新上下文。
2. Agent 保存(save_memory工具 + Web 审批 UI)
agent/tools/save_memory.ts 用defineTool定义,关键特征:
- 输入 schema 用 zod 约束:
reason(保存理由)+updates(1~5 条),每条{ category, content },其中content必须是该类别整段替换文本而非增量; approval: always()— 每次保存都必须经过用户审批(Web 端由ToolSaveMemory.vue渲染审批 UI);execute中逐条调用saveMemoryRemote(POST/api/internal/memory,source: "agent"),服务端由 apps/web/server/api/internal/memory.post.ts 落库。
3. 档案管理 UI(Settings → Profile)
用户可在设置页对记忆执行导入、查看、编辑、删除。记忆类别固定为 5 个(见 lib/types/memory.ts):
| 类别枚举 | UI 标签 | 导入解析别名 |
|---|---|---|
work_context | Work Context | work context |
personal_context | Personal Context | personal context |
active_focus | Active Focus | active focus/active context |
instructions_preferences | Instructions & Preferences | instructions & preferences/instructions and preferences |
project_history | Project History | project history |
每类只保存一段散文文本,保存时整块替换(setMemoryForCategory会清空该类别旧行再写入新行)。对应的 Drizzle 表user_memory定义于 apps/web/server/db/schema/memory.ts,含user_id + category联合索引。此外模板还提供 Raycast 风格的 ChatGPT 导出粘贴导入解析器(apps/web/server/utils/memory-import.ts)。
渠道接入:Slack 与 iMessage 的实战实现
Slack:账号绑定与上下文注入
agent/channels/slack.ts 基于slackChannel实现:
- 凭据来自 Vercel Connect:
connectSlackCredentials("slack/v")(自定义 fork 时替换 slug); - 消息到达后先尝试解析
link <code>命令(调用consumeSlackLinkCodeRemote消费 Web 端生成的链接码),成功则回复绑定完成; - 未绑定的 Slack 用户会收到指引:打开集成页生成链接码,再在 DM 中发送
link <code>; - 已绑定用户通过
fetchSlackLinkForMember查到 App 用户,用buildAppSessionAuth构造会话认证,使 Slack 会话复用与 Web 相同的身份、记忆与集成授权; - 同时把发送者的 display name、username、email 及"最近线程消息"注入上下文,让 Agent 知道是谁在说话、上文说了什么。
iMessage / Sendblue:纯文本世界的审批降级
agent/channels/sendblue.ts 实现了完整的 Sendblue 渠道,值得注意的设计点:
- Webhook 路由为
POST /eve/v1/sendblue/webhook,先校验sb-signing-secret头、跳过 typing 事件与is_outbound/非RECEIVED消息、默认拒绝群聊; - 入站消息按 E.164 号码通过
GET /api/internal/phone/link解析 App 用户,未绑定号码会收到"去 Settings → Profile 添加号码"的指引; - 由于 iMessage 没有浏览器审批 UI,工具审批被降级为纯文本 YES/NO 回复:
input.requested事件把 pending 工具请求记录到pendingInputByThread,用户回复yes/y/ok/approve或no/n/skip/deny触发source.respond; save_memory在 iMessage 上被特殊处理:模板明确告知用户记忆保存需在 Web 档案中完成(Memory saves are not available in iMessage…),避免在无 UI 渠道上执行记忆写入。
Linear:MCP 连接即工具
agent/connections/linear.ts 使用defineMcpClientConnection连接https://mcp.linear.app/mcp,凭据通过 Vercel Connect(mcp.linear.app/linear)按用户维度下发;completeAuthorization还带 0/500/1000/2000ms 的重试退避。连接成功后,Agent 即可直接调用 Linear 的 issues/projects/cycles 等工具。基础指令(agent/lib/base-instructions.ts)为此内置了强约束:"Always call the tools first,绝不用state: "open"(Linear 没有该状态),总结时输出 identifier/title/status/priority"——这些规则直接避免了大模型"凭记忆作答"和无效查询。
自定义清单:把 V 变成你的 Agent
模板以V为示例 persona,fork 后按以下清单逐项替换:
- lib/agent.ts — 品牌信息(
name/slug/tagline/description/avatar.icon); - agent/lib/base-instructions.ts — persona、语气、工具使用与记忆行为规则;
- agent/channels/slack.ts —
connectSlackCredentials("slack/你的slug"); - agent/agent.ts — AI 模型与 provider 选项。
同时需要同步更新的还有:apps/web/app/app.config.ts中的站点元数据(site.name/title/description/tagline)、apps/web/public/下的banner.png/og.png/favicon.ico品牌素材,以及发布 fork 时的package.json元信息。
扩展点:新工具、新技能、新集成
- 新增工具:在
agent/tools/创建defineTool(参考 agent/tools/weather.ts 与 agent/tools/save_memory.ts);如需自定义渲染,在apps/web/app/components/chat/tool/添加组件并挂到MessageContentEve.vue。工具目录按约定自动发现(具体以 Eve 文档为准)。 - 新增技能:在
agent/skills/写 Markdown 即可,参考 agent/skills/daily-summary.md(晨间简报:从注入的记忆取 active focus → 查 Linear 未完成 issues → 输出 Today/Linear/Suggested next 三段式),并在首页快捷操作中引用。 - GitHub 集成:通过 Vercel Connect OAuth +
@github-tools/sdk/eve,connector UID 在 lib/connect.ts(GITHUB_CONNECTOR = "github/personal-agent",与server/connectors.ts保持同步),工具在session.started时按用户 token 动态装配(agent/tools/github.ts)。创建命令:vercel connect create github --name personal-agent与vercel connect attach github/personal-agent。 - Linear / Slack 集成:均走 Vercel Connect;Linear 无需改代码(connector 固定为
mcp.linear.app/linear),Slack 需把 slug 换成自己的。
数据库模型一览
SQLite 经由 NuxtHub,schema 定义在 apps/web/server/db/schema/(迁移文件在server/db/migrations/)。核心表:
| 表 | 用途 |
|---|---|
user/session/account | Better Auth 认证 |
threads | 聊天线程 |
user_profile | 姓名、时区、电话 |
user_memory | 按类别的长期记忆 |
phone_links | 电话 ↔ App 用户映射(Sendblue/iMessage) |
slack_links | Slack ↔ App 用户映射 |
slack_link_codes | 临时链接码 |
迁移流程为pnpm db:generate→pnpm db:migrate。
本地开发与 Vercel 部署
本地自托管
pnpm install cp .env.example .env pnpm db:migrate pnpm dev打开http://localhost:3000,注册账号即可开始聊天。如需同时跑起 Agent 侧,使用pnpm dev:all(Vercel CLI 本地模式同时运行 Nuxt 与 eve 对等服务)。
部署 fork
核心注意事项:
- 双服务:
web+eve由 vercel.ts 编排; - 两侧环境变量一致:尤其是
INTERNAL_API_SECRET与BETTER_AUTH_URL; - 生产数据库:开通 Turso 后
vercel env pull .env --yes && pnpm db:migrate应用迁移; - 生产迁移在部署后执行,不要在构建期依赖本地 SQLite 文件。
小结:这套模板的工程价值
从源码与文档可以看出,Personal Agent Template 的工程要点可以归纳为四点:Eve 与 Nuxt 双服务对等部署、Bearer 密钥保护的内部 API 作为 Agent ↔ 业务数据通道、按类别整块替换的长期记忆模型(注入 + 审批保存 + UI 管理三段式)、多渠道(Web/Slack/iMessage)共享同一身份与记忆的绑定机制。无论你是想 fork 它直接产出个人助手,还是研究 Eve 框架下"Agent + 全栈 Web 服务"的协作范式,这份模板都提供了完整且可运行的最佳实践参考。深入源码的入口包括 agent/、apps/web/server/ 与 docs/ 三处,配合仓库根目录的 AGENTS.md 可快速建立全局认知。
- 人工智能
- AI Agent
- Agent 框架
- 后端
- 工具调用
【免费下载链接】eve
The Open Framework for Building Agents
相关推荐
个人助理 AI Agent 开发指南:从任务调度到习惯学习,构建你的 Personal Assistant
个人助理 AI Agent 开发指南:从任务调度到习惯学习,构建你的 Personal Assistant 个人助理(Personal Assistant)AI
文档教程知识库OpenAgent 实战指南:基于 LLM、RAG 与 Agent 循环构建自托管个人 AI 助手
OpenAgent 实战指南:基于 LLM、RAG 与 Agent 循环构建自托管个人 AI 助手 OpenAgent 是一个开源的下一代个人 AI 助手平台,
人工智能大模型AI 应用AI AgentRAGMCP Clients交互助手浏览器控制代码智能体GUI 自动化AI 技能后端前端本地部署agentmemory 开发指南:基于 iii-engine 三原语构建的 AI 编码 Agent 持久化记忆系统
agentmemory 开发指南:基于 iii engine 三原语构建的 AI 编码 Agent 持久化记忆系统 agentmemory 是一个为 AI 编码
人工智能AI 应用Agent 记忆RAGMCP 服务知识图谱
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考