内容
# agent-canvas
一个原生代理的全栈启动模板:一个Hono API和一个React/Vite前端,端到端类型化,可部署到Cloudflare Workers + D1,具有无状态MCP服务器、代理发现界面和检索增强生成。工作的例子是存储的MLB游戏数据集;下面的画布是领域无关的,因此您可以将例子替换为您自己的领域。
## 使用此模板
这是一个GitHub模板仓库。点击GitHub上的**使用此模板**(或运行`gh repo create <you>/<name> --template brettdavies/agent-canvas-template`),以获取具有单个干净初始提交的新仓库,然后按照[设置](#设置)进行操作。`main`是默认分支;`dev`从同一个提交开始,用于日常工作,具有从`dev`切割的功能分支。
## 技术栈
- Bun(包管理器 + TypeScript运行器),Node运行时,TypeScript
- 后端:Hono在`@hono/node-server`(端口3000);一个Cloudflare Worker(`worker/`)用于边缘部署
- 前端:React 19 + Vite 7(端口5173),Tailwind 4 + DaisyUI
- 数据:Drizzle ORM覆盖Postgres 16 + pgvector在Node服务器(`postgres.js`)和Cloudflare D1(SQLite)边缘;通过`drizzle-zod`进行Zod模式
- AI:OpenAI(`chat` + `embed`);RAG覆盖本地`qmd`知识库、实时MLB StatsAPI和持久pgvector搜索
- 代理界面:MCP覆盖可流式传输的HTTP(`@hono/mcp` + `@modelcontextprotocol/sdk`),以及`.well-known`发现、OpenAPI 3.1和`llms.txt`
- 校验/格式化:Biome · 测试:Vitest · 无障碍:axe-core(WCAG 2.1 A/AA)
## 设置
```bash
bun install
git config core.hooksPath scripts/hooks # 启用校验/类型检查钩子
cp .env.example .env # 设置DATABASE_URL + OPENAI_API_KEY
bun run db:migrate # 应用Postgres迁移
bun run db:seed # 加载样本MLB固件(db/fixtures/mlb-seed.json)
bun run dev
```
`bun run dev` 在 <http://localhost:5173> 启动Vite,在 <http://localhost:3000> 启动Hono;Vite代理`/api`到服务器。标题健康点证明React、Vite代理、Hono、Drizzle和Postgres都已连接。
## MLB示例
该示例存储MLB游戏并通过REST和MCP公开它们,两个接口包装相同的读取内容,以便它们保持同步。
### REST
- `GET /api/health`:存活(数据库往返)。
- `GET /api/teams`:存储的团队。
- `GET /api/games?season=&teamId=&date=&limit=`:查询存储的游戏,最新的优先(`date`为`YYYY-MM-DD`)。
- `GET /api/games/:gamePk`:一个游戏汇总(摘要,每局得分,记分)。
- `POST /api/analyze`:计算摘要统计数据(运行总数,平均值,零封,最高得分游戏,每个团队记录)对于调用者提供的游戏列表,提供内联(`games`),通过https URL(`games_url`),或作为多部分JSON文件。
- `POST /api/rag`:检索增强答案(参见下面的RAG)。
- `GET /api/schema/input.json`和`output.json`:分析输入/输出的JSON模式(2020-12)。
### MCP(`POST /mcp`)
工具:`now`(数据库时间),`list_teams`,`query_games`,`get_game`,`analyze_dataset`和`rag_answer`。工作器公开相同的工具,不带`now`/`rag_answer`(需要Postgres/qmd)。使用`bunx @modelcontextprotocol/inspector`针对`http://localhost:3000/mcp`或普通`curl`驱动程序:服务器是无状态的,因此curl上的JSON-RPC表现与MCP客户端相同(参见`/mcp-skill.md`)。
### RAG
`ragAnswer`从本地`qmd` `stars`知识库中检索,运行`stats_embeddings`上的pgvector语义搜索(持久的MLB数据,当加载时),并从MLB StatsAPI为任何日期问题名称获取实时比分,然后使用内联 `[S#]` / `[D#]` / `[MLB]` 引用合成答案。当数据库为空或无法访问时,它会优雅地降级。
## 原生代理界面
由工作器在稳定路径上提供,以便代理可以发现服务器及其合约:
- `/.well-known/mcp/server-card.json`(以及别名`/.well-known/mcp`,`/.well-known/mcp.json`,`/mcp.json`)
- `/.well-known/ai.txt`,`/llms.txt`,`/llms-full.txt`,`/mcp-skill.md`,`/openapi.json`
- 代理界面上的开放CORS,按IP速率限制,诚实的404/405状态代码和`index.html`中的根HTML导航。
## Cloudflare部署
工作器(`worker/`)提供应用程序和D1支持的数据集的一部分。部署对于本地开发不是必需的。
```bash
wrangler d1 create agent-canvas # 然后在wrangler.jsonc中设置database_id
bun run db:generate-d1 # (重新)从worker/db/schema.ts生成D1迁移
wrangler d1 migrations apply agent-canvas --remote
bun run db:seed-d1 # 写入db/fixtures/seed-d1.sql
wrangler d1 execute agent-canvas --remote --file=db/fixtures/seed-d1.sql
bun run cf:deploy # vite构建 + wrangler部署
```
在部署前设置自定义域名(`wrangler.jsonc`中的`routes`)和`worker/discovery.ts`和`worker/openapi.ts`中的`BASE`源。
## 加载真实的MLB数据
种子固件是一个小样本。完整的管道将真实的StatsAPI数据加载到Postgres(加载程序读取`db/feeds/`和`db/embeddings/`下的本地缓存,这些缓存被git忽略):
- `bun run db:load-one-game [gamePk]`:一个游戏的完整GUMBO馈送(团队,玩法,投球,记分,线路得分)。
- `bun run db:load-stats`:从`db/feeds/`批量加载。
- `bun run db:load-homeruns`:黑客马拉松本垒打CSV(`MLB_HOMERUNS_DIR`指向本地数据集)。
- `bun run db:embed:submit|recover|fetch|update`:`stats_embeddings`的OpenAI批量嵌入管道。
## 脚本
`dev`,`build`,`db:generate`,`db:migrate`,`db:generate-d1`,`db:seed`,`db:seed-d1`,`db:load-one-game`,`db:load-stats`,`db:load-homeruns`,`db:embed:*`,`cf:dev`,`cf:build`,`cf:deploy`,`lint`,`format`,`typecheck`,`test`,`test:watch`,`test:a11y`。
## 布局
```text
src/ React + Vite前端(应用壳,Rag,Games,AgentLinks,主题,库)
server/ Hono应用(app.ts导出AppType),db/(客户端 + 模式),mlb/(查询 + 模式),
ingest/(多源解析器),rag/,ai/,mcp/(服务器 + 工具)
shared/ 跨边界Zod模式 + 类型(日志,mlb)通过@shared别名
worker/ Cloudflare工作器:index.ts,mcp.ts,discovery.ts,openapi.ts,db/schema.ts(D1)
db/scripts/ 加载程序,种子,嵌入管道 · db/fixtures/ 提交样本数据
drizzle/ Postgres迁移 · worker/migrations/ D1迁移
```
## 替换示例
按照[AGENTS.md](./AGENTS.md)中的构建循环替换您的MLB域:定义`server/db/schema.ts`中的表,在`server/mlb/`下添加读取内容(重命名为您的域),在`server/app.ts`和`worker/index.ts`中连接REST路由,在`server/mcp/tools/`和`worker/mcp.ts`中注册MCP工具,并更新发现/OpenAPI副本。画布(壳,MCP传输,发现,RAG管道,部署)保持不变。
参见[AGENTS.md](./AGENTS.md)了解约定和类型单一真实源。