627 lines
16 KiB
Markdown
627 lines
16 KiB
Markdown
|
|
# Prompt 模板管理生效机制与占位符使用分析
|
|||
|
|
|
|||
|
|
## 1. 核心架构
|
|||
|
|
|
|||
|
|
Prompt 模板管理系统由以下核心组件构成:
|
|||
|
|
|
|||
|
|
### 1.1 数据模型
|
|||
|
|
|
|||
|
|
**PromptTemplate(模板实体)**
|
|||
|
|
- `id`: UUID,模板唯一标识
|
|||
|
|
- `tenant_id`: 租户 ID,实现多租户隔离
|
|||
|
|
- `name`: 模板名称
|
|||
|
|
- `scene`: 场景标识(如 "default"、"customer_service")
|
|||
|
|
- `description`: 模板描述
|
|||
|
|
- `is_default`: 是否为默认模板
|
|||
|
|
|
|||
|
|
**PromptTemplateVersion(模板版本)**
|
|||
|
|
- `template_id`: 关联的模板 ID
|
|||
|
|
- `version`: 版本号(整数,自增)
|
|||
|
|
- `status`: 版本状态(draft/published/archived)
|
|||
|
|
- `system_instruction`: 系统指令内容(包含占位符)
|
|||
|
|
- `variables`: 自定义变量定义列表
|
|||
|
|
|
|||
|
|
### 1.2 核心服务
|
|||
|
|
|
|||
|
|
**PromptTemplateService** - 模板管理服务
|
|||
|
|
- 位置:`ai-service/app/services/prompt/template_service.py`
|
|||
|
|
- 功能:模板 CRUD、版本管理、发布/回滚、缓存
|
|||
|
|
|
|||
|
|
**VariableResolver** - 变量解析器
|
|||
|
|
- 位置:`ai-service/app/services/prompt/variable_resolver.py`
|
|||
|
|
- 功能:占位符替换、变量验证
|
|||
|
|
|
|||
|
|
**OrchestratorService** - 编排服务
|
|||
|
|
- 位置:`ai-service/app/services/orchestrator.py`
|
|||
|
|
- 功能:在对话生成流程中加载和应用模板
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 生效机制详解
|
|||
|
|
|
|||
|
|
### 2.1 模板加载流程(12 步 Pipeline 中的第 7 步)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
用户请求 → Orchestrator._build_system_prompt() → 加载模板 → 解析变量 → 注入行为规则 → 传递给 LLM
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**详细步骤**:
|
|||
|
|
|
|||
|
|
1. **触发时机**:每次对话请求到达时,在 Step 7(PromptBuilder)执行
|
|||
|
|
2. **加载逻辑**:
|
|||
|
|
```python
|
|||
|
|
# orchestrator.py:632-638
|
|||
|
|
template_service = PromptTemplateService(session)
|
|||
|
|
template_version = await template_service.get_published_template(
|
|||
|
|
tenant_id=ctx.tenant_id,
|
|||
|
|
scene="default", # 场景可配置
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **缓存机制**:
|
|||
|
|
- 首次加载:从数据库查询 `status=published` 的版本
|
|||
|
|
- 后续请求:从内存缓存读取(TTL 300 秒)
|
|||
|
|
- 缓存失效:发布/回滚操作会自动清除缓存
|
|||
|
|
|
|||
|
|
4. **降级策略**:
|
|||
|
|
- 如果没有已发布的模板 → 使用硬编码的 `SYSTEM_PROMPT`
|
|||
|
|
- 如果数据库查询失败 → 使用硬编码的 `SYSTEM_PROMPT`
|
|||
|
|
|
|||
|
|
### 2.2 版本管理机制
|
|||
|
|
|
|||
|
|
**版本状态流转**:
|
|||
|
|
```
|
|||
|
|
draft(草稿)→ published(已发布)→ archived(已归档)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**发布流程**:
|
|||
|
|
```python
|
|||
|
|
# template_service.py:248-287
|
|||
|
|
async def publish_version(tenant_id, template_id, version):
|
|||
|
|
1. 查询模板是否存在(租户隔离)
|
|||
|
|
2. 将当前 published 版本改为 archived
|
|||
|
|
3. 将目标版本改为 published
|
|||
|
|
4. 清除缓存并预热新版本
|
|||
|
|
5. 记录日志
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**回滚流程**:
|
|||
|
|
```python
|
|||
|
|
# template_service.py:289-298
|
|||
|
|
async def rollback_version(tenant_id, template_id, version):
|
|||
|
|
# 实际上就是调用 publish_version
|
|||
|
|
# 将历史版本重新标记为 published
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**热更新保证**:
|
|||
|
|
- 发布/回滚后立即清除缓存:`self._cache.invalidate(tenant_id, scene)`
|
|||
|
|
- 下次请求会从数据库加载最新版本
|
|||
|
|
- 无需重启服务
|
|||
|
|
|
|||
|
|
### 2.3 租户隔离机制
|
|||
|
|
|
|||
|
|
所有操作都强制进行租户隔离:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 查询时必须带 tenant_id
|
|||
|
|
stmt = select(PromptTemplate).where(
|
|||
|
|
PromptTemplate.tenant_id == tenant_id,
|
|||
|
|
PromptTemplate.scene == scene,
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
不同租户的模板完全独立,互不影响。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 占位符使用详解
|
|||
|
|
|
|||
|
|
### 3.1 占位符语法
|
|||
|
|
|
|||
|
|
**格式**:`{{variable_name}}`
|
|||
|
|
|
|||
|
|
**示例**:
|
|||
|
|
```
|
|||
|
|
你是 {{persona_name}},当前时间是 {{current_time}}。
|
|||
|
|
你正在为 {{tenant_name}} 提供 {{channel_type}} 渠道的客服服务。
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 内置变量
|
|||
|
|
|
|||
|
|
**VariableResolver** 提供以下内置变量:
|
|||
|
|
|
|||
|
|
| 变量名 | 类型 | 默认值 | 说明 |
|
|||
|
|
|--------|------|--------|------|
|
|||
|
|
| `persona_name` | string | "小N" | AI 人设名称 |
|
|||
|
|
| `current_time` | function | 动态生成 | 当前时间(格式:YYYY-MM-DD HH:MM) |
|
|||
|
|
| `channel_type` | string | "default" | 渠道类型(wechat/douyin/jd) |
|
|||
|
|
| `tenant_name` | string | "平台" | 租户名称 |
|
|||
|
|
| `session_id` | string | "" | 会话 ID |
|
|||
|
|
|
|||
|
|
**动态变量示例**:
|
|||
|
|
```python
|
|||
|
|
# variable_resolver.py:15-21
|
|||
|
|
BUILTIN_VARIABLES = {
|
|||
|
|
"persona_name": "小N",
|
|||
|
|
"current_time": lambda: datetime.now().strftime("%Y-%m-%d %H:%M"),
|
|||
|
|
"channel_type": "default",
|
|||
|
|
"tenant_name": "平台",
|
|||
|
|
"session_id": "",
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 自定义变量
|
|||
|
|
|
|||
|
|
**定义方式**:在模板的 `variables` 字段中定义
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"variables": [
|
|||
|
|
{
|
|||
|
|
"name": "company_name",
|
|||
|
|
"default": "XX科技有限公司",
|
|||
|
|
"description": "公司名称"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"name": "service_hours",
|
|||
|
|
"default": "9:00-18:00",
|
|||
|
|
"description": "服务时间"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用示例**:
|
|||
|
|
```
|
|||
|
|
欢迎咨询 {{company_name}},我们的服务时间是 {{service_hours}}。
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.4 变量解析流程
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# variable_resolver.py:45-75
|
|||
|
|
def resolve(template, variables, extra_context):
|
|||
|
|
1. 构建上下文:内置变量 + 自定义变量 + 额外上下文
|
|||
|
|
2. 正则匹配:找到所有 {{variable}} 占位符
|
|||
|
|
3. 替换逻辑:
|
|||
|
|
- 如果变量存在 → 替换为值(函数则调用)
|
|||
|
|
- 如果变量不存在 → 保留原占位符 + 记录警告
|
|||
|
|
4. 返回解析后的字符串
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**正则表达式**:
|
|||
|
|
```python
|
|||
|
|
VARIABLE_PATTERN = re.compile(r"\{\{(\w+)\}\}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.5 变量优先级
|
|||
|
|
|
|||
|
|
变量解析的优先级(从高到低):
|
|||
|
|
|
|||
|
|
1. **extra_context**(运行时传入的额外上下文)
|
|||
|
|
2. **自定义变量**(模板定义的 variables)
|
|||
|
|
3. **实例化时的上下文**(VariableResolver 构造函数传入)
|
|||
|
|
4. **内置变量**(BUILTIN_VARIABLES)
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# variable_resolver.py:77-101
|
|||
|
|
def _build_context(variables, extra_context):
|
|||
|
|
context = {}
|
|||
|
|
|
|||
|
|
# 1. 加载内置变量
|
|||
|
|
for key, value in BUILTIN_VARIABLES.items():
|
|||
|
|
if key in self._context:
|
|||
|
|
context[key] = self._context[key] # 实例化时的上下文
|
|||
|
|
else:
|
|||
|
|
context[key] = value # 内置默认值
|
|||
|
|
|
|||
|
|
# 2. 加载自定义变量
|
|||
|
|
if variables:
|
|||
|
|
for var in variables:
|
|||
|
|
context[var["name"]] = var.get("default", "")
|
|||
|
|
|
|||
|
|
# 3. 加载额外上下文(优先级最高)
|
|||
|
|
if extra_context:
|
|||
|
|
context.update(extra_context)
|
|||
|
|
|
|||
|
|
return context
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 实际使用示例
|
|||
|
|
|
|||
|
|
### 4.1 创建模板(通过 API)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /admin/prompt-templates
|
|||
|
|
X-Tenant-Id: szmp@ash@2026
|
|||
|
|
X-API-Key: your_api_key
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"name": "客服模板 v1",
|
|||
|
|
"scene": "default",
|
|||
|
|
"description": "标准客服对话模板",
|
|||
|
|
"system_instruction": "你是 {{persona_name}},一位专业的客服助手。\n当前时间:{{current_time}}\n渠道:{{channel_type}}\n\n你需要遵循以下原则:\n- 礼貌、专业、耐心\n- 优先使用知识库内容回答\n- 无法回答时建议转人工\n\n公司信息:{{company_name}}\n服务时间:{{service_hours}}",
|
|||
|
|
"variables": [
|
|||
|
|
{
|
|||
|
|
"name": "company_name",
|
|||
|
|
"default": "XX科技",
|
|||
|
|
"description": "公司名称"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"name": "service_hours",
|
|||
|
|
"default": "9:00-21:00",
|
|||
|
|
"description": "服务时间"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"is_default": true
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|||
|
|
"name": "客服模板 v1",
|
|||
|
|
"scene": "default",
|
|||
|
|
"description": "标准客服对话模板",
|
|||
|
|
"is_default": true,
|
|||
|
|
"created_at": "2026-02-27T12:00:00Z",
|
|||
|
|
"updated_at": "2026-02-27T12:00:00Z"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
此时模板已创建,但版本状态为 `draft`,尚未生效。
|
|||
|
|
|
|||
|
|
### 4.2 发布模板
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /admin/prompt-templates/{tpl_id}/publish
|
|||
|
|
X-Tenant-Id: szmp@ash@2026
|
|||
|
|
X-API-Key: your_api_key
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"version": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"message": "Version 1 published successfully"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**生效时间**:立即生效(缓存已清除)
|
|||
|
|
|
|||
|
|
### 4.3 模板生效后的实际效果
|
|||
|
|
|
|||
|
|
**用户请求**:
|
|||
|
|
```json
|
|||
|
|
POST /ai/chat
|
|||
|
|
X-Tenant-Id: szmp@ash@2026
|
|||
|
|
X-API-Key: your_api_key
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"sessionId": "kf_001_wx123_1708765432000",
|
|||
|
|
"currentMessage": "你好",
|
|||
|
|
"channelType": "wechat"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Orchestrator 内部处理**:
|
|||
|
|
|
|||
|
|
1. **加载模板**(Step 7):
|
|||
|
|
```python
|
|||
|
|
# 从缓存或数据库加载已发布的模板
|
|||
|
|
template_version = await template_service.get_published_template(
|
|||
|
|
tenant_id="szmp@ash@2026",
|
|||
|
|
scene="default"
|
|||
|
|
)
|
|||
|
|
# 返回:system_instruction + variables
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **解析变量**:
|
|||
|
|
```python
|
|||
|
|
resolver = VariableResolver(
|
|||
|
|
channel_type="wechat",
|
|||
|
|
tenant_name="深圳某项目",
|
|||
|
|
session_id="kf_001_wx123_1708765432000"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
system_prompt = resolver.resolve(
|
|||
|
|
template=template_version.system_instruction,
|
|||
|
|
variables=template_version.variables,
|
|||
|
|
extra_context={"persona_name": "AI助手"}
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **解析结果**:
|
|||
|
|
```
|
|||
|
|
你是 AI助手,一位专业的客服助手。
|
|||
|
|
当前时间:2026-02-27 20:18
|
|||
|
|
渠道:wechat
|
|||
|
|
|
|||
|
|
你需要遵循以下原则:
|
|||
|
|
- 礼貌、专业、耐心
|
|||
|
|
- 优先使用知识库内容回答
|
|||
|
|
- 无法回答时建议转人工
|
|||
|
|
|
|||
|
|
公司信息:XX科技
|
|||
|
|
服务时间:9:00-21:00
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **注入行为规则**(如果有):
|
|||
|
|
```python
|
|||
|
|
# 从数据库加载行为规则
|
|||
|
|
rules = await behavior_service.get_enabled_rules(tenant_id)
|
|||
|
|
|
|||
|
|
# 拼接到 system_prompt
|
|||
|
|
behavior_text = "\n".join([f"- {rule}" for rule in rules])
|
|||
|
|
system_prompt += f"\n\n行为约束:\n{behavior_text}"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
5. **传递给 LLM**:
|
|||
|
|
```python
|
|||
|
|
messages = [
|
|||
|
|
{"role": "system", "content": system_prompt},
|
|||
|
|
{"role": "user", "content": "你好"}
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
response = await llm_client.generate(messages)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.4 更新模板
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
PUT /admin/prompt-templates/{tpl_id}
|
|||
|
|
X-Tenant-Id: szmp@ash@2026
|
|||
|
|
X-API-Key: your_api_key
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"system_instruction": "你是 {{persona_name}},一位专业且友好的客服助手。\n...",
|
|||
|
|
"variables": [
|
|||
|
|
{
|
|||
|
|
"name": "company_name",
|
|||
|
|
"default": "XX科技有限公司", # 修改了默认值
|
|||
|
|
"description": "公司全称"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**效果**:
|
|||
|
|
- 创建新版本(version=2,status=draft)
|
|||
|
|
- 旧版本(version=1)仍然是 published 状态
|
|||
|
|
- **模板不会立即生效**,需要发布 version 2
|
|||
|
|
|
|||
|
|
### 4.5 回滚模板
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
POST /admin/prompt-templates/{tpl_id}/rollback
|
|||
|
|
X-Tenant-Id: szmp@ash@2026
|
|||
|
|
X-API-Key: your_api_key
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"version": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**效果**:
|
|||
|
|
- version 2 变为 archived
|
|||
|
|
- version 1 重新变为 published
|
|||
|
|
- 缓存清除,立即生效
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 高级特性
|
|||
|
|
|
|||
|
|
### 5.1 变量验证
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# variable_resolver.py:115-144
|
|||
|
|
def validate_variables(template, defined_variables):
|
|||
|
|
"""
|
|||
|
|
验证模板中的所有变量是否已定义
|
|||
|
|
|
|||
|
|
返回:
|
|||
|
|
{
|
|||
|
|
"valid": True/False,
|
|||
|
|
"missing": ["未定义的变量列表"],
|
|||
|
|
"used_variables": ["模板中使用的所有变量"]
|
|||
|
|
}
|
|||
|
|
"""
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用场景**:
|
|||
|
|
- 前端编辑模板时实时验证
|
|||
|
|
- 发布前检查是否有未定义的变量
|
|||
|
|
|
|||
|
|
### 5.2 变量提取
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# variable_resolver.py:103-113
|
|||
|
|
def extract_variables(template):
|
|||
|
|
"""
|
|||
|
|
从模板中提取所有变量名
|
|||
|
|
|
|||
|
|
返回:["persona_name", "current_time", "company_name"]
|
|||
|
|
"""
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**使用场景**:
|
|||
|
|
- 前端显示模板使用的变量列表
|
|||
|
|
- 自动生成变量定义表单
|
|||
|
|
|
|||
|
|
### 5.3 缓存策略
|
|||
|
|
|
|||
|
|
**TemplateCache** 实现:
|
|||
|
|
```python
|
|||
|
|
# template_service.py:32-72
|
|||
|
|
class TemplateCache:
|
|||
|
|
def __init__(self, ttl_seconds=300):
|
|||
|
|
self._cache = {} # key: (tenant_id, scene)
|
|||
|
|
self._ttl = 300 # 5 分钟
|
|||
|
|
|
|||
|
|
def get(self, tenant_id, scene):
|
|||
|
|
# 检查是否过期
|
|||
|
|
if time.time() - cached_at < self._ttl:
|
|||
|
|
return version
|
|||
|
|
else:
|
|||
|
|
del self._cache[key] # 自动清理过期缓存
|
|||
|
|
|
|||
|
|
def invalidate(self, tenant_id, scene=None):
|
|||
|
|
# 发布/回滚时清除缓存
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**缓存失效时机**:
|
|||
|
|
- 发布新版本
|
|||
|
|
- 回滚到旧版本
|
|||
|
|
- 更新模板(创建新版本时不清除,因为新版本是 draft)
|
|||
|
|
- TTL 过期(5 分钟)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 最佳实践
|
|||
|
|
|
|||
|
|
### 6.1 模板设计建议
|
|||
|
|
|
|||
|
|
1. **使用语义化的变量名**:
|
|||
|
|
```
|
|||
|
|
✅ {{company_name}}、{{service_hours}}
|
|||
|
|
❌ {{var1}}、{{x}}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **为所有自定义变量提供默认值**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"name": "company_name",
|
|||
|
|
"default": "XX公司", // 必须提供
|
|||
|
|
"description": "公司名称"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **避免在模板中硬编码业务数据**:
|
|||
|
|
```
|
|||
|
|
❌ 你是小明,为 XX 公司提供服务
|
|||
|
|
✅ 你是 {{persona_name}},为 {{company_name}} 提供服务
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **合理使用内置变量**:
|
|||
|
|
- `current_time`:适用于时间敏感的场景
|
|||
|
|
- `channel_type`:适用于多渠道差异化话术
|
|||
|
|
- `session_id`:适用于调试和追踪
|
|||
|
|
|
|||
|
|
### 6.2 版本管理建议
|
|||
|
|
|
|||
|
|
1. **小步迭代**:
|
|||
|
|
- 每次修改创建新版本
|
|||
|
|
- 在测试环境验证后再发布
|
|||
|
|
- 保留历史版本以便回滚
|
|||
|
|
|
|||
|
|
2. **版本命名规范**(在 description 中):
|
|||
|
|
```
|
|||
|
|
v1.0 - 初始版本
|
|||
|
|
v1.1 - 优化语气,增加公司信息变量
|
|||
|
|
v1.2 - 修复变量引用错误
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **灰度发布**(未来扩展):
|
|||
|
|
- 可以为不同租户发布不同版本
|
|||
|
|
- 可以按百分比逐步切换版本
|
|||
|
|
|
|||
|
|
### 6.3 性能优化建议
|
|||
|
|
|
|||
|
|
1. **利用缓存**:
|
|||
|
|
- 模板内容很少变化,缓存命中率高
|
|||
|
|
- 5 分钟 TTL 平衡了实时性和性能
|
|||
|
|
|
|||
|
|
2. **避免频繁发布**:
|
|||
|
|
- 发布操作会清除缓存
|
|||
|
|
- 建议批量修改后统一发布
|
|||
|
|
|
|||
|
|
3. **监控缓存命中率**:
|
|||
|
|
```python
|
|||
|
|
logger.debug(f"Cache hit for template: tenant={tenant_id}, scene={scene}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. 故障排查
|
|||
|
|
|
|||
|
|
### 7.1 模板未生效
|
|||
|
|
|
|||
|
|
**症状**:发布后仍使用旧模板或硬编码 SYSTEM_PROMPT
|
|||
|
|
|
|||
|
|
**排查步骤**:
|
|||
|
|
1. 检查版本状态:`GET /admin/prompt-templates/{tpl_id}`
|
|||
|
|
- 确认目标版本的 status 是否为 `published`
|
|||
|
|
2. 检查缓存:等待 5 分钟或重启服务
|
|||
|
|
3. 检查日志:
|
|||
|
|
```
|
|||
|
|
[AC-AISVC-51] Cache hit for template: tenant=xxx, scene=default
|
|||
|
|
[AC-AISVC-51] Loaded published template from DB: tenant=xxx, scene=default
|
|||
|
|
[AC-AISVC-51] No published template found, using fallback
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 变量未替换
|
|||
|
|
|
|||
|
|
**症状**:生成的 system_prompt 中仍有 `{{variable}}` 占位符
|
|||
|
|
|
|||
|
|
**排查步骤**:
|
|||
|
|
1. 检查变量定义:确认变量在 `variables` 中定义
|
|||
|
|
2. 检查变量名拼写:必须完全匹配(区分大小写)
|
|||
|
|
3. 检查日志:
|
|||
|
|
```
|
|||
|
|
WARNING: Unknown variable in template: xxx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.3 租户隔离问题
|
|||
|
|
|
|||
|
|
**症状**:租户 A 看到了租户 B 的模板
|
|||
|
|
|
|||
|
|
**排查步骤**:
|
|||
|
|
1. 检查请求头:确认 `X-Tenant-Id` 正确
|
|||
|
|
2. 检查数据库:
|
|||
|
|
```sql
|
|||
|
|
SELECT * FROM prompt_templates WHERE tenant_id = 'xxx';
|
|||
|
|
```
|
|||
|
|
3. 检查代码:所有查询必须带 `tenant_id` 过滤
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. 总结
|
|||
|
|
|
|||
|
|
### 8.1 核心流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
创建模板 → 编辑内容 → 发布版本 → 缓存加载 → 变量解析 → 传递给 LLM
|
|||
|
|
↓ ↓ ↓ ↓ ↓ ↓
|
|||
|
|
draft draft published 内存缓存 占位符替换 生成回复
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 8.2 关键特性
|
|||
|
|
|
|||
|
|
- ✅ **版本管理**:支持多版本、发布/回滚、历史追溯
|
|||
|
|
- ✅ **热更新**:发布后立即生效,无需重启
|
|||
|
|
- ✅ **租户隔离**:多租户数据完全隔离
|
|||
|
|
- ✅ **缓存优化**:5 分钟 TTL,减少数据库查询
|
|||
|
|
- ✅ **变量系统**:内置变量 + 自定义变量,支持动态值
|
|||
|
|
- ✅ **降级策略**:模板不可用时自动回退到硬编码
|
|||
|
|
|
|||
|
|
### 8.3 扩展方向
|
|||
|
|
|
|||
|
|
- 🔄 **场景路由**:根据 intent 或 channel 自动选择不同 scene
|
|||
|
|
- 🔄 **A/B 测试**:同一场景支持多个模板并行测试
|
|||
|
|
- 🔄 **模板继承**:子模板继承父模板并覆盖部分内容
|
|||
|
|
- 🔄 **变量类型**:支持 string/number/boolean/array 等类型
|
|||
|
|
- 🔄 **条件渲染**:支持 `{{#if}}...{{/if}}` 等逻辑控制
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**文档生成时间**:2026-02-27 20:18
|
|||
|
|
**相关代码版本**:v0.6.0
|
|||
|
|
**维护状态**:✅ 活跃维护
|