主题
使用 Deno Deploy 部署
使用 Hono 路由处理程序在 Deno Deploy 上部署 LangChain deep agent,并从单个入口点提供 Vite React SPA。
以下页面详细介绍一个示例应用:它在 Deno Deploy 上部署 LangChain deep agent,包含流式聊天 UI、子 agent 和线程历史,全部由以 Hono 服务器上的 HTTP + SSE 路由处理程序形式实现的 Agent Streaming Protocol 提供支持。React 前端是一个 Vite SPA(从 Next.js 示例移植而来);Deno 通过单个 main.ts 入口点同时提供构建后的静态资源和 API。
这是将 Next.js 示例移植到 Deno + Hono,展示了如何在 Deno Deploy(而不是 Vercel)上运行相同的 agent 技术栈。
来源:部署 cookbook 中的 js-deno。
部署到 Deno Deploy
Create a Deno Deploy project
Fork 或克隆 langchain-ai/deployment-cookbook。在 Deno Deploy 仪表板中,创建一个链接到该仓库的新项目。
Configure build settings
- 将 Root Directory 设置为
js-deno。 - 将 build command 设置为
deno task build:client(将 Vite SPA 构建到dist/)。 - 将 entrypoint 设置为
main.ts。 - 在项目环境变量中添加
OPENAI_API_KEY。
Deploy
从仪表板部署。Deno 的构建环境会运行构建命令,因此 dist/ 在云端生成,永远无需提交。
或者,使用内置的 deno deploy CLI(Deno 2.x)。deno.json 中的 deploy 块设置了 org/app。请将它们改为你自己的(或传入 --org/--app 标志,它们会覆盖这些设置)。
bash
cd js-deno
# First time only: create the app
deno deploy create --org <your-org> --app <your-app> --source local --region us --entrypoint main.ts
# Set your OpenAI key
deno deploy env add OPENAI_API_KEY <your-key> --org <your-org> --app <your-app>
# Build the client, deploy to production, and clean up dist/
deno task deploydeno task deploy 会运行 deno task build:client && deno deploy --prod,然后运行 rm -rf dist。必须在本地构建,因为 deno deploy --source local 会上传你的工作树(除去 .gitignore),并且不会运行构建命令。这些命令只会为连接到 GitHub 的应用运行。
WARNING
CLI --source local 流程有两个特有的坑:
dist/不能被 gitignore。 上传器会遵循.gitignore,因此新构建的dist/必须在上传窗口内可见,否则所有非/api路由都会返回 404。仓库根目录的.gitignore忽略了所有dist,因此js-deno/.gitignore用!dist/和!dist/**将其重新包含进来。deno task deploy流程会在上传后删除dist/,因此尽管它没有被忽略,也不会留在git status中。- 不要使用
deploy.include列表。 Deno Deploy 存在一个 bug:添加include会使构建将入口点解析为src/main.ts并失败。请改用基于.gitignore的默认上传方式。
可以选择通过添加 .env.example 中的变量来启用 LangSmith 追踪。
必需的 API 端点
该应用在 /api/threads/... 下暴露 Agent Streaming Protocol。路由处理程序位于 server/routes.ts,与 js-next/app/api/threads/ 中的 Next.js 处理程序相对应。
最小集(流式聊天)
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /api/threads/:threadId/commands | 接受协议命令(run.start 等)并启动 agent run |
POST | /api/threads/:threadId/stream | 某次 run 的协议事件 SSE 流 |
GET / POST | /api/threads/:threadId/state | 读取并引导已 checkpoint 的线程状态 |
可选(侧栏)
| 方法 | 路径 | 用途 |
|---|---|---|
GET | /api/threads | 列出 checkpointer 已知的线程 |
DELETE | /api/threads/:threadId | 删除线程的会话和检查点 |
POST | /api/threads/:threadId/history | 分页的检查点历史(Agent Protocol) |
请求流程
%%{init: {"themeVariables": {"lineColor": "#40668D", "primaryColor": "#E5F4FF", "primaryTextColor": "#030710", "primaryBorderColor": "#006DDD"}}}%%
flowchart TB
subgraph browser["Browser (Vite React SPA)"]
SP["StreamProvider"]
Adapter["HttpAgentServerAdapter"]
SP --- Adapter
end
subgraph deno["Deno.serve + Hono"]
CMD["POST /api/threads/:id/commands"]
STR["POST /api/threads/:id/stream (SSE)"]
STA["GET|POST /api/threads/:id/state"]
end
subgraph server["server/"]
SRV["registry · session · threads"]
end
subgraph agent["server/agent"]
AGT["createDeepAgent + checkpointer"]
end
Adapter -->|POST| CMD
Adapter -->|POST| STR
Adapter -->|GET / POST| STA
CMD --> SRV
STR --> SRV
STA --> SRV
SRV --> AGT
classDef process fill:#E5F4FF,stroke:#006DDD,stroke-width:2px,color:#030710
classDef trigger fill:#F6FFDB,stroke:#6E8900,stroke-width:2px,color:#2E3900
classDef output fill:#EBD0F0,stroke:#885270,stroke-width:2px,color:#441E33
class browser,deno process
class server trigger
class agent output
Deno 后端如何工作
此示例作为单个 Deno 进程运行:
main.ts:Deno.serve+ Hono 应用。挂载/api路由,并从dist/提供 Vite 构建的 SPA。server/routes.ts:Agent Streaming Protocol 的 Hono 路由定义。server/session.ts:LocalThreadSession:在 LangGraphStreamChannel中缓冲协议事件,使用matchesSubscription过滤,并通过 SSEReadableStream分发匹配的帧。server/threads.ts:以 LangGraph SDK 线格式提供的、由 checkpointer 支持的getState/updateState/getHistory辅助函数。server/registry.ts:进程本地单例,拥有 agent 以及每个线程 id 一个会话。server/agent/:与 Next.js 示例相同的createDeepAgent编排器(researcher + math-whiz 子 agent、mock 工具)。
Deno Deploy 会为每个 isolate 运行各自的内存 MemorySaver checkpointer。若要实现跨 isolate 的生产级持久化,请换用持久 checkpointer(Postgres、Redis 等)。路由处理程序和 server/threads.ts 辅助函数保持不变。
生产持久化
开箱即用时,agent 使用内存中的 MemorySaver checkpointer(server/agent/index.ts)和进程本地会话映射(server/registry.ts)。这适用于本地开发和单 isolate 部署,但在 Deno Deploy 上(多个 isolate、冷启动),对话状态在实例之间不具备持久性。
将 server/agent/index.ts 中的 MemorySaver 替换为持久 checkpointer,例如 @langchain/langgraph-checkpoint-postgres 或 @langchain/langgraph-checkpoint-redis。你还需要一个共享的会话/重放存储,以便 SSE 重连能够跨 isolate 工作。
本地开发
bash
cp .env.example .env # set OPENAI_API_KEY
export $(grep -v '^#' .env | xargs) # load env for Deno
# Terminal 1 — API + static (after first client build)
deno task build:client # first time only
deno task dev
# Terminal 2 — Vite dev server with HMR (proxies /api to :8000)
cd client && pnpm install && pnpm dev打开 http://localhost:5173 进行带热重载的开发。Vite 开发服务器会将 /api 代理到端口 8000 上的 Deno 服务器。
要进行类似生产环境的本地运行(单服务器,无 HMR):
bash
deno task build:client
deno task start项目布局
main.ts:Deno Deploy 入口点(Deno.serve+ Hono)。server/agent/:deep agent(createDeepAgent),包含子 agent 和 mock 工具。server/:协议服务器逻辑:session.ts、threads.ts、serialize.ts、registry.ts、routes.ts。client/:Vite + React SPA(与 Next.js 示例相同的 UI)。dist/:由 Deno 提供的 Vite 构建输出(由deno task build:client生成)。