256 lines
8.0 KiB
Markdown
256 lines
8.0 KiB
Markdown
# 教育智能体 HTML 发布服务
|
||
|
||
这个服务用于接收智能体生成的知识点讲解 HTML,将内容保存为服务器上的唯一随机文件名,并返回可直接访问的链接。
|
||
|
||
当前主实现为 FastAPI,接口地址默认前缀为 `/api`。生成后的 HTML 文件默认存放在 `backend/data/generated_html/`,元数据记录在 `backend/data/html_generator.db`。
|
||
|
||
## 适用场景
|
||
|
||
- 教育智能体生成知识点讲解页
|
||
- 将模型输出的 HTML 片段封装为完整页面
|
||
- 为智能体返回可分享、可打开的独立链接
|
||
- 保留一定天数后自动清理过期文件
|
||
|
||
## 推荐对接方式
|
||
|
||
腾讯云智能体侧建议直接使用本服务的 OpenAPI 文档:
|
||
|
||
- OpenAPI 地址:`https://你的域名/openapi.json`
|
||
- 接口文档地址:`https://你的域名/docs`
|
||
|
||
如果你们使用腾讯云智能体的 API 插件或 HTTP 工具节点,推荐直接导入上面的 OpenAPI 文档;如果不导入,也可以手工按本文档配置请求参数。
|
||
|
||
## 接口总览
|
||
|
||
### 1. 生成 HTML
|
||
|
||
- 方法:`POST`
|
||
- 路径:`/api/html/generate`
|
||
- Content-Type:`application/json`
|
||
|
||
#### 请求头
|
||
|
||
| 名称 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `Content-Type` | string | 是 | 固定为 `application/json` |
|
||
| `X-API-Key` | string | 否 | 当服务端配置了 `API_KEY` 时必填 |
|
||
|
||
#### 请求体参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `html_content` | string | 是 | 智能体生成的 HTML 内容,可以是完整 HTML,也可以是 HTML 片段 |
|
||
| `title` | string | 否 | 页面标题,最大 120 个字符 |
|
||
| `source` | string | 否 | 来源标识,建议填智能体名称、工作流名或插件名,最大 80 个字符 |
|
||
| `request_id` | string | 否 | 请求追踪 ID,方便排查问题,最大 120 个字符 |
|
||
| `ttl_days` | integer | 否 | 文件保留天数,默认 7 天,最大 30 天 |
|
||
|
||
#### 兼容别名
|
||
|
||
为了方便不同智能体或旧配置迁移,服务还兼容以下别名:
|
||
|
||
- `html` -> `html_content`
|
||
- `content` -> `html_content`
|
||
- `expire_days` -> `ttl_days`
|
||
|
||
#### 请求示例
|
||
|
||
```json
|
||
{
|
||
"title": "勾股定理讲解",
|
||
"source": "tencent-education-agent",
|
||
"request_id": "lesson-math-20260321-001",
|
||
"ttl_days": 7,
|
||
"html_content": "<section><h1>勾股定理</h1><p>在直角三角形中,a² + b² = c²。</p></section>"
|
||
}
|
||
```
|
||
|
||
#### 成功响应示例
|
||
|
||
```json
|
||
{
|
||
"message": "HTML file generated successfully",
|
||
"unique_id": "vE7k7llv3zXc1A08",
|
||
"url": "https://你的域名/api/html/vE7k7llv3zXc1A08/content",
|
||
"query_url": "https://你的域名/api/html/vE7k7llv3zXc1A08",
|
||
"title": "勾股定理讲解",
|
||
"source": "tencent-education-agent",
|
||
"request_id": "lesson-math-20260321-001",
|
||
"size_bytes": 1286,
|
||
"created_at": "2026-03-21T12:00:00.000000",
|
||
"expires_at": "2026-03-28T12:00:00.000000"
|
||
}
|
||
```
|
||
|
||
#### 字段说明
|
||
|
||
| 返回字段 | 类型 | 说明 |
|
||
| --- | --- | --- |
|
||
| `message` | string | 接口处理结果说明 |
|
||
| `unique_id` | string | 系统生成的唯一 ID |
|
||
| `url` | string | 可直接打开的 HTML 页面地址 |
|
||
| `query_url` | string | 查询该记录元数据的地址 |
|
||
| `title` | string \| null | 页面标题 |
|
||
| `source` | string \| null | 来源标识 |
|
||
| `request_id` | string \| null | 请求追踪 ID |
|
||
| `size_bytes` | integer | 实际生成文件大小,单位字节 |
|
||
| `created_at` | string | 创建时间,UTC |
|
||
| `expires_at` | string | 过期时间,UTC |
|
||
|
||
### 2. 查询已生成 HTML 的元数据
|
||
|
||
- 方法:`GET`
|
||
- 路径:`/api/html/{unique_id}`
|
||
|
||
返回结构与生成接口一致,可用于后续查询链接是否仍有效。
|
||
|
||
### 3. 访问 HTML 内容
|
||
|
||
- 方法:`GET`
|
||
- 路径:`/api/html/{unique_id}/content`
|
||
|
||
这个地址会直接返回 `text/html` 内容。智能体侧通常只需要使用生成接口返回的 `url` 字段即可。
|
||
|
||
## 智能体调用约定
|
||
|
||
建议腾讯云智能体在工具描述中遵守以下规则:
|
||
|
||
1. `html_content` 必须是完整、可展示的知识讲解内容,优先输出结构化讲解,不要只返回一句话。
|
||
2. 推荐使用语义标签,例如 `section`、`article`、`h1`、`h2`、`p`、`ul`、`ol`、`table`。
|
||
3. 如果只生成 HTML 片段,服务端会自动补齐基础的 `html/head/body` 包装。
|
||
4. 优先输出静态展示内容,不要把它当成前端应用来写。
|
||
5. 成功后请直接使用返回的 `url` 对外展示,不要自己拼接文件名。
|
||
|
||
## 内容限制和安全规则
|
||
|
||
当 `ALLOW_UNSAFE_HTML=false` 时,默认开启安全拦截,以下内容会被拒绝:
|
||
|
||
- `<script>`
|
||
- `<iframe>`
|
||
- `<object>` / `<embed>` / `<base>`
|
||
- `<form>`
|
||
- `<link>`
|
||
- `meta refresh`
|
||
- 内联事件属性,例如 `onclick=`
|
||
- `javascript:` 协议
|
||
|
||
这是为了避免智能体把任意动态脚本直接挂到线上域名下。
|
||
|
||
当前项目默认配置已经改为 `ALLOW_UNSAFE_HTML=true`,也就是:
|
||
|
||
- 不再拦截 `<script>`、`<link>` 等标签
|
||
- 返回 HTML 时不再附加严格的 CSP 头
|
||
- 适合需要 JavaScript 动态展示的页面
|
||
|
||
这意味着安全风险将由你们自己兜底,建议至少做到:
|
||
|
||
- 独立子域名部署
|
||
- 不挂载登录态 Cookie
|
||
- 不与主站后台同域
|
||
- 对智能体输出做额外审核
|
||
|
||
### 推荐约束
|
||
|
||
- 推荐把生成 HTML 的访问域名单独隔离,例如 `html.example.com`
|
||
- 推荐全站 HTTPS
|
||
- 不要在该域名下挂载登录态 Cookie
|
||
- 生产环境不要把 `ALLOW_UNSAFE_HTML` 设为 `true`
|
||
- 单次 HTML 内容大小默认不超过 `200000` 字节
|
||
|
||
## 常见状态码
|
||
|
||
| 状态码 | 含义 |
|
||
| --- | --- |
|
||
| `201` | HTML 创建成功 |
|
||
| `400` | HTML 内容不安全或业务参数非法 |
|
||
| `401` | API Key 不正确 |
|
||
| `404` | 记录不存在或已过期 |
|
||
| `422` | 请求体格式不符合要求 |
|
||
| `500` | 服务端异常 |
|
||
|
||
## 本地启动
|
||
|
||
### 后端
|
||
|
||
```bash
|
||
cd backend
|
||
pip install -r requirements.txt
|
||
python server.py
|
||
```
|
||
|
||
也可以直接使用:
|
||
|
||
```bash
|
||
cd backend
|
||
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
||
```
|
||
|
||
### 前端演示页
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
如需指定后端地址,可设置:
|
||
|
||
```bash
|
||
NEXT_PUBLIC_API_BASE_URL=http://localhost:8000
|
||
```
|
||
|
||
## 环境变量
|
||
|
||
`backend/.env.example` 已给出示例,核心配置如下:
|
||
|
||
| 变量名 | 类型 | 默认值 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `APP_NAME` | string | `HTML Knowledge API` | 服务名称 |
|
||
| `API_PREFIX` | string | `/api` | 接口前缀 |
|
||
| `PUBLIC_BASE_URL` | string | `http://localhost:8000` | 对外可访问的服务域名 |
|
||
| `ALLOWED_ORIGINS` | JSON array / string | `["*"]` | CORS 白名单 |
|
||
| `HTML_STORAGE_DIR` | string | `./data/generated_html` | HTML 文件存储目录 |
|
||
| `DEFAULT_RETENTION_DAYS` | integer | `7` | 默认保留天数 |
|
||
| `MAX_RETENTION_DAYS` | integer | `30` | 最大允许保留天数 |
|
||
| `MAX_HTML_LENGTH` | integer | `200000` | 单次 HTML 最大字节数 |
|
||
| `API_KEY` | string | 空 | 非空时启用 `X-API-Key` 鉴权 |
|
||
| `ALLOW_UNSAFE_HTML` | boolean | `true` | 是否关闭 HTML 安全拦截;当前默认开启,便于执行 JS |
|
||
|
||
## 给腾讯云智能体的最小参数说明
|
||
|
||
如果你们只想保留最简单的调用方式,智能体只传下面这一个字段也能工作:
|
||
|
||
```json
|
||
{
|
||
"html_content": "<section><h1>牛顿第一定律</h1><p>物体在不受外力时,将保持静止或匀速直线运动状态。</p></section>"
|
||
}
|
||
```
|
||
|
||
推荐智能体至少传:
|
||
|
||
```json
|
||
{
|
||
"title": "牛顿第一定律讲解",
|
||
"source": "tencent-education-agent",
|
||
"request_id": "physics-lesson-001",
|
||
"html_content": "<section>...</section>"
|
||
}
|
||
```
|
||
|
||
## 目录说明
|
||
|
||
- `backend/app/main.py`:FastAPI 应用入口
|
||
- `backend/app/routers/html.py`:HTML 生成、查询、访问接口
|
||
- `backend/app/schemas.py`:请求与响应模型
|
||
- `backend/app/models.py`:数据库模型
|
||
- `backend/server.py`:本地启动脚本
|
||
- `frontend/app/page.tsx`:手工联调用演示页
|
||
|
||
## 后续建议
|
||
|
||
如果你们后面还想继续增强,可以优先做这三项:
|
||
|
||
1. 为 `generate` 接口增加业务层面的调用日志和审计记录。
|
||
2. 给智能体增加更严格的 HTML 输出提示词模板,减少不合规标签。
|
||
3. 把 `PUBLIC_BASE_URL` 配成独立子域名,进一步隔离主站风险。
|