跳转到内容

部署到 Vercel Edge

Vercel Edge Functions 是另一个常用 serverless 部署目标。Next.js 项目可以 直接把 Hashee Webhook 嵌进 app/api/hashee/webhook/route.ts

Next.js 项目脚手架

Terminal window
npx create-next-app@latest my-agent --ts --app --no-tailwind
cd my-agent
npm install @hasheeai/agent-sdk-ts

Route Handler

app/api/hashee/webhook/route.ts
import { createWebhookDispatcher, restRequest } from "@hasheeai/agent-sdk-ts";
export const runtime = "edge";
const dispatcher = createWebhookDispatcher({
agentId: process.env.HASHEE_AGENT_ID!,
token: process.env.HASHEE_AGENT_TOKEN!,
secret: process.env.HASHEE_WEBHOOK_SECRET!,
privateKeyBase64: process.env.HASHEE_X25519_PRIVATE_BASE64!,
signingPrivateKeyBase64: process.env.HASHEE_ED25519_PRIVATE_BASE64!,
baseUrl: "https://api.hashee.ai",
onMessage: async (msg) => {
if (msg.payload?.type !== "text") return;
const reply = await callLLM(msg.payload.text);
await restRequest({
method: "POST",
baseUrl: "https://api.hashee.ai",
path: `/agents/${process.env.HASHEE_AGENT_ID}/messages`,
token: process.env.HASHEE_AGENT_TOKEN!,
body: {
conversation_id: msg.conversation_id,
payload: { type: "text", text: reply },
},
});
},
onEvent: async (event) => {
if (event.type === "relation.revoked") {
// Vercel KV 清状态
await vercelKv.del(`user:${event.payload.user_id}`);
}
},
});
export async function POST(req: Request): Promise<Response> {
try {
await dispatcher.handle(
Object.fromEntries(req.headers),
await req.text(),
);
return new Response("ok", { status: 200 });
} catch (err: any) {
console.error("[hashee] error:", err);
return new Response("error", { status: err?.statusCode ?? 500 });
}
}
async function callLLM(text: string): Promise<string> {
// OpenAI / Anthropic / etc
return `Echo: ${text}`;
}

环境变量

在 Vercel 项目 Settings → Environment Variables 添加:

变量Sensitive
HASHEE_AGENT_IDUUID
HASHEE_AGENT_TOKENhsk_...
HASHEE_WEBHOOK_SECRET共享 secret
HASHEE_X25519_PRIVATE_BASE64私钥
HASHEE_ED25519_PRIVATE_BASE64签名私钥

或者用 Vercel CLI:

Terminal window
vercel env add HASHEE_AGENT_ID
vercel env add HASHEE_AGENT_TOKEN
# ...

部署

Terminal window
vercel deploy --prod

部署后会得到 https://my-agent.vercel.app

注册到 Agent

把 DemoBot 的连接模式改成 webhook
URL: https://my-agent.vercel.app/api/hashee/webhook
secret: <HASHEE_WEBHOOK_SECRET 值>

长任务异步化

Edge Runtime 单请求 25 秒上限(Vercel Pro),且 Hashee 期望 ≤ 10 秒响应。 长任务必须异步:

方案 A:用 Vercel Queues(Beta)

import { enqueue } from "@vercel/queue";
onMessage: async (msg) => {
await enqueue("agent-jobs", {
conversation_id: msg.conversation_id,
text: msg.payload.text,
});
// 立即返回,handler 200
},

队列消费者在 app/api/queue/agent-jobs/route.ts 处理。

方案 B:用第三方 queue(Inngest / QStash)

import { Inngest } from "inngest";
const inngest = new Inngest({ id: "my-agent" });
onMessage: async (msg) => {
await inngest.send({
name: "agent/message.received",
data: msg,
});
},

Inngest function 处理后调 restRequest 回写 Hashee。

方案 C:Edge Runtime + waitUntil(短任务)

import { waitUntil } from "@vercel/functions";
onMessage: async (msg) => {
waitUntil(processAndReply(msg)); // 异步执行,不阻塞 200 OK
},

适合 LLM 调用 ≤ 25 秒的场景。超过用 Queues。

持久状态

工具用途
Vercel KV配置 / 缓存 / 简单 key-value
Vercel Postgres关系数据
Vercel Edge Config全局配置(毫秒级读取)
Upstash Redis复杂数据结构(list/set/sortedset)

性能与限制

Vercel Edge 限Hashee 限
请求超时25 s(Pro)10 s
内存128 MB
Body 大小4 MB1 MB(Hashee)
子请求50 / req
并发请求1000 / 实例

故障排查

症状排查
vercel logs 看不到调用检查 Hashee Agent webhook URL 是否对
401 invalid signaturesecret 错;redeploy 时 env 变了
edge runtime crash检查 cold start log;可能依赖不兼容 edge
Cron timeout长任务必须 enqueue

下一步