Prompt 管理、RAG 与 agents 使用 HazelJS
Source: Dev.to
一个入门示例:类型化提示模板、实时注册表、FileStore 持久化、RAG、监督代理以及 AI 任务——全部由同一个提示系统驱动
良好地管理 LLM 提示非常困难:你需要版本控制、无需重新部署的覆盖,以及一个让 RAG、代理和普通 AI 任务都能读取的统一位置。HazelJS Prompt Starter 展示了如何实现这一点。它基于 @hazeljs/prompts、@hazeljs/rag 和 @hazeljs/agent 构建,提供了:
- 一个带有 类型化模板 的 PromptRegistry,
- FileStore 持久化,
- 一个 REST API,可在运行时检查并覆盖任意提示。
RAG 答案合成、监督代理、工作代理以及四个 AI 任务(welcome、summarize、sentiment、translate)都使用同一个注册表。在本文中,我们将逐步介绍 starter 中包含的内容以及如何使用它。
功能
| 功能 | 描述 |
|---|---|
| PromptTemplate | Typed {variable} 渲染,具备完整的 TypeScript 推断 |
| PromptRegistry | 全局提示存储 — 在运行时注册、覆盖、版本管理 |
| FileStore | 提示持久化到 ./data/prompts.json,在重启之间保持 |
| RAG integration | RAG 答案合成提示由注册表驱动,并可通过 REST 覆盖 |
| Agent integration | 监督系统 + 路由提示来自注册表 |
| Worker agents | Researcher 和 Analyst 工作人员使用注册表提示来决定工具行为 |
| AI tasks | 欢迎、摘要、情感分析、翻译 — 全部由注册表提示支持 |
| Live REST API | 检查、预览并覆盖任何提示,无需重启服务器 |
一个服务器,一个注册表: 使用
PUT /api/prompts/:key更改提示,下一次 RAG 问题、代理运行或 AI 任务将使用新模板。
快速‑开始
git clone https://github.com/hazel-js/hazeljs-prompt-starter.git
cd hazeljs-prompt-starter
cp .env.example .env # add OPENAI_API_KEY
npm install
npm run dev
服务器运行在 http://localhost:3000。尝试列出提示:
curl http://localhost:3000/api/prompts
然后覆盖 RAG 回答提示并提问(见下方示例)。
每个提示都由一个键标识(例如 rag:answer、agent:supervisor:system、app:summarize)。REST API 让您无需修改代码即可管理它们。
Prompt Registry API
| 端点 | 描述 |
|---|---|
GET /api/prompts | 列出所有已注册的提示(键、名称、版本、模板) |
GET /api/prompts/stores | 显示已配置的存储后端(例如 FileStore) |
GET /api/prompts/:key | 单个提示的完整详情 |
GET /api/prompts/:key/versions | 列出缓存的版本 |
POST /api/prompts/:key/preview | 使用提供的变量渲染(查看 LLM 实际收到的内容) |
PUT /api/prompts/:key | 在运行时覆盖提示(立即持久化到 FileStore) |
POST /api/prompts/save | 将整个内存注册表持久化到 FileStore |
POST /api/prompts/load | 从 FileStore 重新加载所有提示 |
示例:覆盖 RAG 答案提示
curl -X PUT http://localhost:3000/api/prompts/rag%3Aanswer \
-H "Content-Type: application/json" \
-d '{
"template": "Answer in one sentence.\nContext: {context}\nQuestion: {query}\nAnswer:",
"metadata": { "version": "2.0.0", "description": "Concise one‑sentence answers" }
}'
示例:使用变量预览提示
curl -X POST http://localhost:3000/api/prompts/app%3Asummarize/preview \
-H "Content-Type: application/json" \
-d '{ "variables": { "text": "HazelJS is a TypeScript framework.", "maxWords": "10" } }'
RAG 流程使用注册表中的 rag:answer 提示。通过 Prompts API 覆盖它,下一次对 /api/rag/ask 的调用将使用新的模板。
RAG API
| Endpoint | Description |
|---|---|
POST /api/rag/ingest | 将纯文本文档写入内存向量存储 |
POST /api/rag/ask | 使用当前 rag:answer 提示进行问答(响应中包含 promptUsed) |
POST /api/rag/ask/custom | 使用自定义模板的一次性问答(不更改注册表) |
GET /api/rag/stats | 文档数量和当前 rag:answer 模板 |
DELETE /api/rag/clear | 清空向量存储 |
导入并提问
curl -X POST http://localhost:3000/api/rag/ingest \
-H "Content-Type: application/json" \
-d '{
"documents": [
{ "content": "HazelJS is a TypeScript backend framework built for scalability.", "source": "intro.txt" },
{ "content": "@hazeljs/prompts provides typed, overridable prompt templates.", "source": "prompts.txt" }
]
}'
curl -X POST http://localhost:3000/api/rag/ask \
-H "Content-Type: application/json" \
-d '{ "question": "What is HazelJS?" }'
工作流程: 使用 PUT /api/prompts/rag%3Aanswer 覆盖 rag:answer,然后再次运行相同的问题 —— 答案风格将遵循新的提示。
代理 API
| 端点 | 描述 |
|---|---|
POST /api/agent/run | 在任务上运行主管(委派给 Researcher 和/或 Analyst) |
GET /api/agent/workers | 列出工作者及其提示注册表键 |
示例
curl -X POST http://localhost:3000/api/agent/run \
-H "Content-Type: application/json" \
-d '{ "task": "Research the benefits of RAG over fine‑tuning and analyse the trade‑offs." }'
响应中包含 supervisorSystemPrompt —— 用于主管的精确提示。覆盖 agent:supervisor:system 或 agent:worker:researcher 并重新运行,即可看到不同的委派和输出风格。
AI 任务 API
| 接口 | 描述 |
|---|---|
GET /api/ai/examples | 所有四个任务的当前模板和示例变量 |
POST /api/ai/task/welcome | 个性化问候 |
POST /api/ai/task/summarize | 限字数摘要 |
POST /api/ai/task/sentiment | JSON 情感分析(sentiment、confidence、reason) |
POST /api/ai/task/translate | 语言翻译 |
示例
curl -X POST http://localhost:3000/api/ai/task/welcome \
-H "Content-Type: application/json" \
-d '{ "name": "Alice", "topic": "prompt engineering" }'
curl -X POST http://localhost:3000/api/ai/task/summarize \
-H "Content-Type: application/json" \
-d '{ "text": "HazelJS makes building TypeScript back‑ends fast and type‑safe.", "maxWords": 15 }'
curl -X POST http://localhost:3000/api/ai/task/sentiment \
-H "Content-Type: application/json" \
-d '{ "text": "I love how easy it is to manage prompts with HazelJS!" }'
curl -X POST http://localhost:3000/api/ai/task/translate \
-H "Content-Type: application/json" \
-d '{ "text": "Hello, world!", "targetLanguage": "Spanish" }'
所有四个任务都从同一个注册表中获取提示,因此您可以通过 Prompt API 在运行时更新任意任务。
回顾
- One registry → 每个提示的唯一真实来源。
- Live REST API → 在无需重新部署的情况下编辑、预览、版本化并持久化提示。
- Typed templates → 完整的 TypeScript 推断,构建更安全的提示。
- FileStore → 提示在服务器重启后仍然保留。
试一试,实时微调提示,立刻感受 RAG、代理和 AI 任务行为的瞬间变化!
API 示例
# 摘要一段文本(最多30个词)
curl -X POST http://localhost:3000/api/ai/task/summarize \
-H "Content-Type: application/json" \
-d '{ "text": "HazelJS is a modular TypeScript framework...", "maxWords": "30" }'
# 获取情感分析
curl -X POST http://localhost:3000/api/ai/task/sentiment \
-H "Content-Type: application/json" \
-d '{ "text": "I love how easy HazelJS makes dependency injection!" }'
Prompt Registry Overview
| Key | Package | Description |
|---|---|---|
rag:answer | @hazeljs/rag | RAG答案合成 |
rag:entity-extraction | @hazeljs/rag | GraphRAG实体提取 |
rag:community-summary | @hazeljs/rag | GraphRAG社区摘要 |
rag:graph-search | @hazeljs/rag | GraphRAG搜索合成 |
agent:supervisor:system | @hazeljs/agent | 监督者身份 + 工作人员列表 |
agent:supervisor:routing | @hazeljs/agent | JSON路由决策 |
agent:worker:researcher | this starter | ResearcherAgent工具提示 |
agent:worker:analyst | this starter | AnalystAgent工具提示 |
app:welcome | this starter | 个性化问候 |
app:summarize | this starter | 字数限制的摘要 |
app:sentiment | this starter | JSON情感分类 |
app:translate | this starter | 语言翻译 |
项目结构
src/
├── main.ts # Bootstrap + startup banner
├── app.module.ts # Root HazelModule
├── prompts/ # @hazeljs/prompts integration
│ ├── prompts.service.ts
│ ├── prompts.controller.ts
│ └── prompts.module.ts
├── rag/ # @hazeljs/rag — reads rag:answer from registry
│ ├── rag.service.ts
│ ├── rag.controller.ts
│ └── rag.module.ts
├── agent/ # @hazeljs/agent — supervisor + workers from registry
│ ├── agent.service.ts
│ ├── agent.controller.ts
│ ├── workers/researcher.agent.ts
│ ├── workers/analyst.agent.ts
│ └── agent.module.ts
├── ai/ # AI tasks via registry prompts
│ ├── ai-task.service.ts
│ ├── ai-task.controller.ts
│ └── ai.module.ts
├── llm/ # OpenAI LLM provider for agents
│ └── openai-llm.provider.ts
└── health/
└── health.controller.ts # Liveness + readiness
How It Works
- Prompt Registry – 单个全局
PromptRegistry(由PromptTemplate和FileStore支持)保存所有提示模板。 - Runtime Overrides – 可以通过 REST API 列出、预览和覆盖提示;更改会被 RAG、代理和 AI 任务即时捕获。
- Persistence – 覆盖内容会持久化到
./data/prompts.json(或其他存储),并在重启后仍然有效。
环境变量
| Variable | Description | Default |
|---|---|---|
OPENAI_API_KEY | 必填 – OpenAI API 密钥 | — |
EMBEDDING_MODEL | 用于生成嵌入的模型 | — |
QA_MODEL | 用于问答的模型 | — |
AGENT_MODEL | 用于代理的模型 | — |
PROMPTS_FILE | 提示 JSON 文件的路径 | ./data/prompts.json |
PORT | 服务器的 HTTP 端口 | — |
请参阅 starter 项目的 .env.example 和 README 以获取完整列表。
扩展存储
在生产环境中,您可以通过调整 PromptsService 中的注册表配置,将 FileStore 替换为 RedisStore(或任何其他后端)。REST API 和所有使用者保持不变。
启动项目提供的内容
- 一个注册表 –
PromptTemplate、PromptRegistry以及可插拔的、可类型化、可覆盖的提示存储。 - 一个 REST API – 在运行时列出、预览并覆盖任意提示。所有服务(RAG、代理、AI 任务)会即时响应更改。
- RAG、代理和 AI 任务 – 均从同一注册表读取,实现无需代码更改的行为调优。
克隆仓库,设置 OPENAI_API_KEY,即可拥有一个演示提示管理、RAG、监督代理和 AI 任务的单一应用。
如需了解更多关于 HazelJS 和
@hazeljs/prompts的信息,请访问 hazeljs.com 和 HazelJS GitHub 仓库。