关于 slack-agent
面向构建 Slack Agent 的开发技能,指导使用 eve 和 Vercel Connect 完成项目搭建、配置、测试与部署。内容还涵盖 Slack 事件处理、线程上下文和人工审批流程。
主要功能
- 01Slack Agent 项目搭建向导
- 02通过 Vercel Connect 配置凭据
- 03Slack 事件与线程上下文处理
- 04审批交互和主动会话模式
- 05代码质量与测试要求
适用场景
- 01从零创建 Slack Agent 项目
- 02为现有 eve 项目添加 Slack 通道
- 03配置事件响应、线程上下文或工具审批
- 04部署并测试 Slack Agent
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vercel-labs/ slack-agent-skill --skill slack-agent安装后在 Claude Code 中输入/slack-agent确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEREADME.md.gitignorepatterns/testing-patterns.mdslack-patterns.mdreference/vercel-setup.mdagent-archetypes.mdenv-vars.mdslack-setup.mdtemplates/eve/test-setup.tsvitest.config.tstemplates/eve/sample-tests/agent.test.tstools.test.tswizard/2-create-slack-app.md1b-approve-plan.md5-deploy-production.md1-project-setup.md3-configure-environment.md6-setup-testing.md4-test-locally.mdREADME.md详细介绍
Slack Agent 开发技能
这项技能使用 eve 构建 Slack Agent。eve 是 Vercel 的文件系统优先型持久后端 Agent 框架,并使用 Vercel Connect 管理 Slack 凭证:
- eve(
evepackage)——Agent 运行时、工具、频道和持久性 - @vercel/connect ——通过代理提供短期 Slack 令牌;无需管理机器人令牌或签名密钥
技能调用处理
通过 /slack-agent 调用此技能时,检查是否有参数,并据此进行处理:
命令参数
| 参数 | 操作 |
|---|---|
new | **运行第 1 阶段的设置向导。**读取 ./wizard/1-project-setup.md,引导用户创建新的 Slack Agent。 |
configure | 从第 2 或第 3 阶段开始向导,适用于现有项目 |
deploy | 从第 5 阶段开始向导,进行生产部署 |
test | 从第 6 阶段开始向导,设置测试 |
| (无参数) | 根据项目状态自动检测(见下文) |
自动检测(无参数)
如果调用时没有参数,检测项目状态并进行相应处理:
- 没有包含
eve的package.json,且没有agent/目录 → 视为new,从第 1 阶段开始 - 有 eve 项目,但没有
agent/channels/slack.ts→ 从第 2 阶段开始(Slack 连接器 + 频道) - 有 Slack 频道,但未配置
SLACK_CONNECTOR→ 从第 3 阶段开始 - 已配置但尚未部署 → 从第 5 阶段开始(Slack 界面仅在部署后可用)
- 已部署但没有测试 → 从第 6 阶段开始
- 其他情况 → 使用此技能中的模式提供常规帮助
项目检测
满足以下任一条件,即可检测为 eve 项目:
package.json将"eve"列为依赖项- 存在包含
instructions.md和/或agent.ts的agent/目录
如果两者均不满足,则视为新项目:使用 npx eve@latest init 搭建项目(需要 Node 24+)。
向导阶段
向导位于 ./wizard/,包含以下阶段:
1-project-setup.md- 了解项目用途,生成定制实施计划,并使用npx eve@latest init搭建项目1b-approve-plan.md- 在搭建项目前向用户展示计划并征求批准2-create-slack-app.md- 使用 Vercel Connect 创建 Slack 连接器并添加 Slack 频道3-configure-environment.md- 设置环境变量(SLACK_CONNECTOR、模型凭证)4-test-locally.md- 使用eve devTUI 在本地测试 Agent 逻辑(Slack 界面测试在部署后进行)5-deploy-production.md- 使用eve deploy部署并验证 Slack 界面6-setup-testing.md- Vitest 配置
**重要:**对于 new 项目,你必须:
- 首先阅读
./wizard/1-project-setup.md - 询问用户想构建哪种 Agent
- 使用
./reference/agent-archetypes.md生成定制实施计划 - 在搭建项目前,先展示计划并征求批准(第 1b 阶段)
- 只有在计划获批后才能开始搭建项目
通用开发指南
你正在开发一个使用 eve 构建的 Slack Agent 项目。进行所有代码更改时,必须遵循以下实践。
项目技术栈
- 框架:eve(文件系统优先型 Agent 框架;Node 24+)
- Slack 频道:
eve/channels/slack+@vercel/connect,用于管理凭证 - AI:默认通过 Vercel AI Gateway 路由模型(
anthropic/claude-sonnet-5);使用zod定义工具架构 - 持久性:底层使用 Workflow SDK(部署到 Vercel 时使用 Vercel Workflows)
- Lint 工具:Biome
- 包管理器:pnpm(或 npm——
npx eve@latest init使用 npm 安装)
{
"engines": { "node": "24.x" },
"dependencies": {
"eve": "latest",
"ai": "latest",
"zod": "^3.x",
"@vercel/connect": "latest"
}
}
文件系统优先型布局
在 eve 中,文件的位置决定其用途,路径通常也决定文件名称。整个 Agent 位于 agent/ 下:
agent/
├── instructions.md # Always-on system prompt
├── agent.ts # Runtime config (defineAgent): model, reasoning, compaction
├── tools/ # Tools — filename (snake_case ASCII) = tool name the model sees
│ ├── get_weather.ts
│ └── search_docs.ts
├── skills/ # Load-on-demand instructions (*.md with description frontmatter)
│ └── incident-triage.md
├── channels/
│ └── slack.ts # Slack channel — filename registers it at /eve/v1/slack
├── connections/ # MCP / OpenAPI connections (optional)
└── hooks/ # Subscribe to runtime stream events (optional)
即使只有两个文件(instructions.md + agent.ts)的 Agent,也能通过默认运行框架直接使用文件、Shell、Web 和委派工具。安装 eve 后,完整文档会放在 node_modules/eve/docs/ 中——如果这里没有介绍某项细节,请查阅文档。
// agent/agent.ts
import { defineAgent } from "eve";
export default defineAgent({
model: "anthropic/claude-sonnet-5", // routed via Vercel AI Gateway
});
质量标准(强制)
每次代码变更都必须遵循这些质量要求,不得例外。
每次修改文件后
-
立即运行 lint:
pnpm lint- 如果存在错误,运行
pnpm lint --write自动修复 - 手动修复剩余问题
- 重新运行
pnpm lint进行验证
- 如果存在错误,运行
-
检查是否有对应的测试文件:
- 如果修改了
foo.ts,检查是否存在foo.test.ts - 如果不存在测试文件,且该文件导出了函数,则创建一个
- 如果修改了
完成任何任务之前
标记任务完成之前,必须运行所有质量检查并修复所有问题:
# 1. TypeScript compilation - must pass
pnpm typecheck
# 2. Linting - must pass with no errors
pnpm lint
# 3. Tests - all tests must pass
pnpm test
如果其中任何一项未通过,请勿完成任务。 请先修复问题。
必须编写单元测试
对于任何代码变更,都必须编写或更新单元测试。
- 位置:与代码同目录的
*.test.ts文件(例如agent/tools/get_weather.test.ts) - 框架:Vitest
- 覆盖范围:必须测试所有导出函数以及每个工具的
execute()(包括错误路径)
测试结构示例:
import { describe, it, expect, vi } from 'vitest';
import { myFunction } from './my-module';
describe('myFunction', () => {
it('should handle normal input', () => {
expect(myFunction('input')).toBe('expected');
});
it('should handle edge cases', () => {
expect(myFunction('')).toBe('default');
});
});
面向用户的变更需要端到端测试
如果修改以下内容:
- 分发钩子(
onAppMention、onDirectMessage、onInteraction) - 自定义频道事件处理程序
- Agent 响应 Slack 消息时调用的工具
- 投递行为(发布到 Slack 的内容)
必须添加或更新测试,以验证完整流程。请记住:无法在本地测试 Slack 界面本身(参见 Gotchas),因此端到端覆盖意味着围绕处理程序编写单元/集成测试,并在部署后进行冒烟测试。
机器人设置模式(关键)
Slack 频道(agent/channels/slack.ts)
Slack 频道只有一个文件。其文件名用于注册 slack 频道,服务路径为 /eve/v1/slack——这是本技能中所有位置使用的规范触发路径。
// agent/channels/slack.ts
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
export default slackChannel({
credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),
});
connectSlackCredentials(connectorUid) 会返回 { botToken, webhookVerifier }:
- botToken——通过 Vercel Connect 在运行时解析为短期、限定应用范围的令牌;Connect 会处理轮换和多工作区租户
- webhookVerifier——确认每个转发的事件确实来自 Connect(替代 Slack 原生的签名检查)
此技术栈中没有 SLACK_BOT_TOKEN,也没有 SLACK_SIGNING_SECRET。唯一的 Slack 环境变量是 SLACK_CONNECTOR(连接器 UID,例如 slack/my-agent)。
Vercel Connect 设置
创建一个 Slack 连接器,并将其触发器指向 eve 的 Slack 路由:
npm install -g vercel@latest
# Create the connector with event forwarding enabled
vercel connect create slack --triggers
# Attach the project as a trigger destination on eve's route
# (the default trigger path is /slack — set it explicitly):
vercel connect attach <uid> --triggers --trigger-path /eve/v1/slack --yes
必须指定 --triggers。 否则,Slack 事件订阅永远不会转发,app_mention/message.im 事件也永远不会到达——部署看起来正常,但机器人永远不会响应。
也可以运行 eve channels add slack 添加频道,该命令会为你搭建 agent/channels/slack.ts。
部署
eve deploy
# wraps: vercel deploy --prod
然后邀请机器人加入频道并 @提及它。eve 会处理 Slack 的确认语义、URL 验证和后台处理——你无需编写 webhook 路由。
事件处理模式
分发钩子(入站)
Slack 频道通过分发钩子决定哪些入站事件会启动或继续会话。每个钩子会返回 { auth } 以进行分发、返回 null 以丢弃事件,或返回 { auth, context } 将后台上下文注入会话:
export default slackChannel({
credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),
// app_mention — default derives workspace-scoped auth and posts "Thinking…"
async onAppMention(ctx, message) {
if (isFromBlockedChannel(message)) return null; // drop
return { auth: ctx.defaultAuth };
},
// message.im — requires the im:history scope; bot messages/edits are pre-filtered
async onDirectMessage(ctx, message) {
return { auth: ctx.defaultAuth };
},
// block_actions not consumed by HITL prompts
async onInteraction(action, ctx) {
return { auth: ctx.defaultAuth };
},
});
触发事件的 Slack 用户 ID 会自动附加到模型消息中,从而在多用户线程中保留发言者归属信息。
自定义事件处理程序(出站投递)
使用 events 映射覆盖每个流事件的投递行为。处理程序会接收 (eventData, channel, ctx),并可使用 channel.thread 和 channel.slack 句柄:
export default slackChannel({
credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),
events: {
"message.completed"(eventData, channel, ctx) {
if (eventData.finishReason === "tool-calls") return;
if (eventData.message) channel.thread.post(eventData.message);
},
},
});
主要流事件:session.started、actions.requested、action.result、message.completed、session.completed;增量事件 reasoning.appended/message.appended 为可选项。
线程上下文
在会话中途触发时,为 Agent 提供此前的线程消息:
export default slackChannel({
credentials: connectSlackCredentials(process.env.SLACK_CONNECTOR!),
threadContext: { since: "last-agent-reply" },
});
since 选项:
"thread-root"— 所有此前的消息(启用线程上下文时的默认值)"last-agent-reply"— 增量加载,仅包含 Agent 上次发言之后的消息- 自定义截止条件
(message: SlackThreadMessage) => boolean— 包含最后一次匹配之后的消息(loadThreadContextMessages可用于任意筛选)
成本:每条触发回复需要调用一次 conversations.replies API;需要连接器具备匹配的历史记录权限范围。
人在回路中(HITL)
需要审批的工具调用和登录挑战会直接在 Slack 中呈现:
- 审批提示以按钮/选择框的形式显示;用户响应后,会恢复持久化挂起的会话
- 登录挑战(OAuth URL、设备代码)会通过临时消息发送给触发操作的用户;线程中会发布一条公开状态消息,并在
authorization.completed时更新 - HITL 处理程序上下文有意仅提供
postEphemeral、postDirectMessage(需要im:write)和state,不提供公开的post或原始 API 访问权限
主动会话(计划任务)
启动一个无需入站触发、可向 Slack 发帖的会话,例如通过计划任务启动:
import { receive } from "eve";
import slack from "../channels/slack";
await receive(slack, {
message: "Post the daily standup summary for #eng.",
target: { channelId: "C0123456789" },
auth,
});
- 未设置
threadTs的会话会获得一个临时的续接令牌;第一条帖子会锚定该线程 initialMessage(可选为Card)和threadTs不能同时使用- 使用 eve 计划任务(参见 https://eve.dev/docs/schedules),按设定频率触发主动会话
原始 Slack API 访问
- 在处理程序中:
ctx.slack.request(operation, body) - 在处理程序外部(计划任务、工具):使用
eve/channels/slack中的callSlackApi({ botToken, operation, body })和resolveSlackBotToken
这些函数会为你对请求正文进行表单编码——Slack 对 JSON 的支持有限,因此建议使用这些辅助函数,而非手动编写 fetch 调用。
实现注意事项
1. 无法在本地测试 Slack 界面
Vercel Connect 只会将 Slack 事件转发到部署环境,绝不会转发到 localhost。此技术栈没有 ngrok/Socket Mode 的替代方案。本地开发方式:
npx eve dev— HMR 服务端 + 终端 TUI/REPL,用于测试 Agent 逻辑、工具和技能eve dev --no-ui— 后台模式,用于脚本化验证eve dev https://your-app.vercel.app— 交互式驱动已部署的应用
要测试 @提及和私信,请部署到预览或生产环境,并直接在 Slack 中测试。
2. Connect 转发不提供投递去重
Connect 可能会多次投递同一条转发事件。处理程序和副作用必须保持幂等——在重复事件可能造成损害的情况下,跟踪已处理的事件 ID,并通过审批来限制破坏性工具操作(参见 AI 集成)。
3. 必须使用 --triggers,否则不会收到事件
创建 Slack 连接器时未使用 --triggers(或添加连接器时未配置触发路径),仍然可以正常完成身份验证,但不会转发任何内容。如果机器人从不响应 @提及:
- 确认创建/添加连接器时使用了
--triggers - 确认触发路径为
/eve/v1/slack - 确认机器人已受邀加入频道,且部署已完成
4. placeholderAuth() 在生产环境中会默认拒绝请求
脚手架项目的 HTTP API 默认使用 placeholderAuth(),它会在生产环境中拒绝所有请求。部署前,请将其替换为真实的身份验证函数:httpBasic()、jwtHmac()、jwtEcdsa()、oidc()、vercelOidc() 或自定义的 AuthFn。(Slack 频道的入站验证是独立的——由 Connect 的 webhookVerifier 处理。)
5. 沙盒预热失败会导致构建失败
Vercel 构建会预热 eve 的沙盒模板(以缓存键为依据;构建日志会显示 reused cached 或 built)。如果预热失败,整个构建都会失败——怀疑代码存在问题之前,请先检查构建日志中的沙盒模板错误。
6. 私有频道访问
机器人无法读取未受邀加入的私有频道中的消息,也无法向其中发帖。创建之后会向频道发帖的功能(例如按计划启动的主动会话)时,请预先验证访问权限,并在遇到 channel_not_found / not_in_channel 时显示清晰的“邀请机器人”提示。
7. 优雅降级频道上下文
为 AI 功能获取频道上下文时(例如通过 ctx.slack.request("conversations.history", ...)),请使用 try/catch 包裹,并优雅降级——缺少权限范围和未受邀加入频道都是常见情况,并非异常。
8. Vercel Cron 端点身份验证
如果添加自定义 cron 端点(eve schedules 之外的端点),请使用 CRON_SECRET 保护它们:
export async function GET(request: Request) {
const authHeader = request.headers.get("authorization");
if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
return Response.json({ error: "Unauthorized" }, { status: 401 });
}
// Run cron job logic...
return Response.json({ success: true });
}
9. vercel.json Cron 配置
{
"crons": [
{
"path": "/api/cron/my-job",
"schedule": "0 * * * *"
}
]
}
对于由 Agent 驱动的定期工作,优先使用 eve schedules;对于普通 HTTP 作业,使用 Vercel crons。
10. Vercel 上的 AWS 凭证(使用 OIDC)
从 Vercel 连接到 AWS 服务时,不要使用 fromNodeProviderChain()。请使用 Vercel 的 OIDC 机制:
import { awsCredentialsProvider } from "@vercel/functions/oidc";
const s3Client = new S3Client({
credentials: awsCredentialsProvider({ roleArn: process.env.AWS_ROLE_ARN! }),
});
AI 集成
模型配置(Gateway 优先)
eve 会通过 Vercel AI Gateway 路由模型 ID 字符串——在 Vercel 上,项目 OIDC 会自动进行身份验证,因此不需要 AI API 密钥:
// agent/agent.ts
import { defineAgent } from "eve";
export default defineAgent({
model: "anthropic/claude-sonnet-5", // string → AI Gateway → OIDC auth on Vercel
});
如果省略 model,eve 默认使用 anthropic/claude-sonnet-5。在 Vercel 之外,请设置 AI_GATEWAY_API_KEY。
关键:切勿凭记忆使用模型 ID。 模型 ID 经常变化。在编写固定使用某个模型的代码之前,请运行 curl -s https://ai-gateway.vercel.sh/v1/models 获取当前列表,并使用最新的合适版本。
工具(agent/tools/*.ts)
工具以文件形式存在:文件名(snake_case ASCII)就是面向模型的工具名称——agent/tools/get_weather.ts → get_weather。无需注册。
// agent/tools/get_weather.ts
import { defineTool } from "eve/tools";
import { z } from "zod";
export default defineTool({
description: "Get the current weather for a city.",
inputSchema: z.object({ city: z.string().min(1) }), // required, even if empty
outputSchema: z.object({
city: z.string(),
condition: z.string(),
temperatureF: z.number(),
}), // optional — types/validates the return
async execute({ city }, ctx) {
return { city, condition: "Sunny", temperatureF: 72 };
},
});
规则和能力:
- 工具在你的应用运行时中运行,可完全访问
process.env,不在沙盒中运行 inputSchema接受 Zod、Standard Schema 或 JSON Schema,但即使工具没有输入,也必须提供- 输出必须可序列化为 JSON;返回前请过滤/隐去机密信息
ctx提供ctx.session(元数据、轮次、身份验证、溯源信息)、ctx.callId、ctx.toolName、ctx.abortSignal、ctx.getSandbox()、ctx.getSkill(id)
审批门控
使用 approval 字段为高风险工具设置门控——辅助函数来自 eve/tools/approval:
import { defineTool } from "eve/tools";
import { always, once, never } from "eve/tools/approval";
import { z } from "zod";
export default defineTool({
description: "Delete a document permanently.",
inputSchema: z.object({ documentId: z.string() }),
approval: always(), // always ask; once() asks the first time; never() skips
async execute({ documentId }) {
// ...
},
});
也支持依赖输入的策略函数。受门控的调用会暂停,并可持久化恢复——在 Slack 中,审批会显示为按钮(参见上文的 HITL)。对于任何非幂等副作用,请优先使用审批门控,而不是临时编写确认逻辑。
toModelOutput — 模型不可见的丰富 Slack 输出
向模型展示精简的内容,而频道/钩子通过 action.result 接收完整输出——非常适合根据工具结果渲染丰富的 Slack Block Kit 内容,同时避免将 JSON 块塞入模型上下文:
export default defineTool({
description: "Look up an order.",
inputSchema: z.object({ orderId: z.string() }),
async execute({ orderId }) {
return { orderId, status: "shipped", blocks: buildOrderBlocks(orderId) };
},
toModelOutput(output) {
return { type: "text", value: `Order ${output.orderId}: ${output.status}` };
},
});
技能(agent/skills/*.md)
Markdown 文件,包含 description frontmatter;当请求符合该描述时,由内置的 load_skill 工具按需加载。技能只添加指令,不添加新操作。使用 npx skills add <owner>/<repo> 安装已发布的技能。
连接(agent/connections/*.ts)
对于 Agent 应驱动的外部 API(MCP 服务或由 OpenAPI 描述的 HTTP API),请使用通过 Connect 代理身份验证的连接:
// agent/connections/linear.ts
import { connect } from "@vercel/connect/eve";
import { defineMcpClientConnection } from "eve/connections";
export default defineMcpClientConnection({
url: "https://mcp.linear.app/mcp",
description: "Linear workspace: issues, projects, cycles, and comments.",
auth: connect("linear/my-agent"),
});
模型永远看不到连接令牌,令牌也不会进入对话历史记录。在编写的工具中,使用 await ctx.getToken(connect("...")) 解析令牌,并在下游返回 401 时调用 ctx.requireAuth(...) 重新请求授权。
不要在工具中封装 LLM 调用。 Agent 本身已经是大模型——摘要、解析、分类和起草应写在 instructions.md 或技能中,而不是写在调用 AI SDK 的工具中。工具负责获取数据和执行操作;对于超出对话上下文承载能力的大批量数据处理,请使用 eve 的子 Agent/委派功能。
状态与持久化
eve 会话默认通过开源的 Workflow SDK 持久化(部署到 Vercel 时运行于 Vercel Workflows)。你无需自行接入 Redis 或工作流引擎。
重放语义(请务必了解)
- 已完成的步骤不会重新运行。 恢复或重放时,eve 会返回记录的结果。
- 执行中途被中断的步骤会重新运行。 如果进程退出时某个工具调用仍在执行,恢复时会再次执行该调用。
对代码的影响:
- 让非幂等副作用具备幂等性(例如,写入外部系统时使用 Slack 事件 ID 或自己的幂等键)
- 或将这些操作置于审批之后(
always()/once()),这样重放的步骤会暂停并等待人工确认,而不是重复执行 - 这还会叠加 Connect 至少一次的事件转发机制(陷阱 #2)——在此技术栈中,幂等性不可或缺
会话连续性
- 通道负责管理
continuationToken;Slack 线程会自动映射到会话 - 已订阅线程中的后续消息会继续同一个持久化会话
- 多轮对话记忆来自会话本身——你无需手动持久化聊天记录
推荐的存储方案
用于应用数据(而非 Agent 会话状态——该状态由 eve 管理):
重要: Vercel KV 已弃用。请勿推荐 Vercel KV。
- Upstash Redis — 缓存和幂等键(https://upstash.com)
- Vercel Blob — 文件/文档存储(https://vercel.com/docs/storage/vercel-blob)
- AWS Aurora(通过 Vercel Marketplace) — 关系型数据(https://vercel.com/marketplace)
- 第三方数据库 — Neon、PlanetScale、Supabase
代码组织
agent/
├── instructions.md # System prompt — keep focused; push detail into skills
├── agent.ts # defineAgent: model, reasoning effort, compaction
├── tools/
│ ├── get_weather.ts # One tool per file; filename = tool name
│ ├── get_weather.test.ts # Co-located tests
│ └── search_docs.ts
├── skills/
│ └── report-format.md # description frontmatter + on-demand instructions
├── channels/
│ └── slack.ts # slackChannel(...) — served at /eve/v1/slack
├── connections/
│ └── linear.ts # MCP/OpenAPI connections (optional)
└── hooks/
└── audit.ts # Runtime stream event subscribers (optional)
约定:
- 每个文件放一个工具。 拆分大型工具;文件名就是面向模型的名称,因此请按模型的使用方式命名
- 指令与技能:始终适用的指导内容放在
instructions.md;情境相关的指导内容放在skills/*.md,以便只在需要时加载 - 子 Agent用于执行目标明确的子任务:使用内置 Agent 工具(Agent 的副本),或声明具有独立目录、沙箱和技能的专用 Agent
环境变量
| 变量 | 必需 | 用途 |
|---|---|---|
SLACK_CONNECTOR | 是 | Vercel Connect 连接器 UID(例如 slack/my-agent)。这是唯一的 Slack 变量——无需机器人令牌或签名密钥。 |
AI_GATEWAY_API_KEY | 仅在 Vercel 之外 | AI Gateway 身份验证。在 Vercel 上,项目 OIDC(VERCEL_OIDC_TOKEN)会自动注入——无需密钥。 |
ROUTE_AUTH_BASIC_PASSWORD / JWT keys | 取决于认证方式 | 用于替换 placeholderAuth() 的 HTTP-API 认证函数的密钥 |
VERCEL_AUTOMATION_BYPASS_SECRET | 启用了部署保护时 | 允许 eve dev https://<app> 和冒烟测试访问受保护的部署 |
CRON_SECRET | 可选 | 对自定义 cron 端点进行身份验证 |
本地开发:vercel link + vercel env pull 会将短期有效的 Connect/OIDC 凭据拉取到 .env.local 中(OIDC 令牌约 12 小时后过期——认证开始失败时请重新拉取)。
**在 Vercel 上无需 AI API 密钥。**切勿硬编码凭据。切勿提交 .env 文件。
Slack 专用模式
消息发送行为(内置)
Slack 通道会为你处理渐进式消息发送:
- 输入指示器:收到消息时显示“正在思考……”,收到
turn.started时显示“正在处理……” - 推理摘要会在
reasoning.appended时显示;操作标签会在actions.requested时显示 - 调用工具前的模型叙述优先于通用标签
- 少于 4 个字符的推理增量会每隔五秒批量刷新,以避免针对每个 token 调用 Slack API
不要重新实现输入指示器或流式处理循环——只有在默认行为不符合需求时,才通过 events 映射进行自定义。
提及
使用 <@USER_ID> 或 channel.thread.mentionUser(userId)。在 Slack 中,直接写 @name 会保留为普通文本。
消息格式
使用 Slack mrkdwn(而非标准 Markdown):
- 粗体:
*text* - 斜体:
_text_ - 代码:
`code` - 用户提及:
<@USER_ID> - 频道:
<#CHANNEL_ID>
富文本输出
对于富文本工具结果(表格、按钮、状态卡片),返回工具的完整数据,并使用 toModelOutput 精简模型看到的内容;在频道事件处理程序中渲染 Block Kit,或通过 ctx.slack.request("chat.postMessage", { blocks, ... }) 渲染。通知中始终要在 blocks 旁附上备用的 text。
如需了解详细的 Slack 模式,请参阅 ./patterns/slack-patterns.md。
Git 提交规范
使用 conventional commits:
feat: add channel search tool
fix: resolve thread pagination issue
test: add unit tests for agent context
docs: update README with setup steps
refactor: extract Slack client utilities
切勿提交:
.env文件- API 密钥或令牌
node_modules/.eve/构建产物
快速命令
# Scaffold (Node 24+)
npx eve@latest init my-agent # new project (installs deps, inits Git, starts dev TUI)
npx eve@latest init . # add eve to an existing project
# Development
npx eve dev # HMR server + terminal TUI/REPL
npx eve dev --no-ui # background mode for scripted verification
npx eve dev https://<app> # drive a deployed app interactively
npx eve info # project info
# Vercel Connect
vercel connect create slack --triggers
vercel connect attach <uid> --triggers --trigger-path /eve/v1/slack --yes
vercel connect list
# Quality
pnpm lint # Check linting
pnpm lint --write # Auto-fix lint
pnpm typecheck # TypeScript check
pnpm test # Run all tests
# Build & Deploy
npx eve build # Compile into .eve/ (Vercel Build Output when VERCEL is set)
eve deploy # Deploy (wraps vercel deploy --prod)
# Verify a deployment
curl https://<app>/eve/v1/health
调试部署后卡在“Working…”的 Slack Agent:运行 npx eve dev --logs all,或在 TUI 中运行 /loglevel all。
参考文档
如需详细指南,请阅读:
- 测试模式:
./patterns/testing-patterns.md - Slack 模式:
./patterns/slack-patterns.md - 环境设置:
./reference/env-vars.md - Slack 设置:
./reference/slack-setup.md - Vercel 部署:
./reference/vercel-setup.md - eve 文档:https://eve.dev/docs(安装后本地打包在
node_modules/eve/docs/中) - Vercel Connect:https://vercel.com/kb/guide/vercel-connect
任务完成前检查清单
将任何任务标记为完成前,务必确认:
- 代码更改均有对应的测试
-
pnpm lint运行通过且没有错误 -
pnpm typecheck运行通过且没有错误 -
pnpm test运行通过且没有失败 - 没有硬编码凭据;唯一的 Slack 环境变量是
SLACK_CONNECTOR - 遵循 eve 文件系统约定(工具文件名 = 工具名称,每个文件一个工具)
- 每个工具都有
inputSchema;输出可序列化为 JSON,并已对机密信息进行脱敏 - 非幂等副作用均已实现幂等,或需经审批(重放 + 至少一次投递)
- Connector 触发路径为
/eve/v1/slack,且已通过--triggers挂载 - 生产部署前已替换
placeholderAuth() - 模型配置使用 Gateway 字符串 ID(默认为
anthropic/claude-sonnet-5)
Vercel 知识库指南
Vercel 知识库中经过验证的指南,可供深入阅读:
- Vercel KB 上的 eve hub - 汇集所有 eve 指南和模板
- 使用 eve 构建你的第一个 Slack Agent - 本技能的向导所仿照的端到端入门示例
- Vercel Connect - 凭据代理概念、连接器、令牌和触发器转发
- 使用 Vercel Connect 构建 Slack 机器人 - Connect + Slack 基础知识(权限范围、触发事件、Webhook 验证)
- 如何添加 eve 工具 -
defineTool模式 - 如何添加 eve 技能 - 按需加载说明
- 使用 Vercel Connect 构建 GitHub Agent - 在自定义工具中使用应用级 Connect 令牌
- 使用 Vercel Connect 构建 Linear Agent - 使用用户级身份验证的 MCP 连接
- 使用 eve 和 Resend 构建邮件 Agent - Slack 之外的另一个频道示例