Skip to content

Commit b255fb3

Browse files
author
chengjie
committed
feat: 支持通过环境变量和租户配置注入自定义 Prompts
- 新增 src/prompt_manager.py 实现 Prompts 热注入 - 支持环境变量配置(全局) - 支持租户配置覆盖(租户级) - 优先级:租户配置 > 环境变量 > LightRAG 默认值 - 扩展租户配置模型 - TenantConfigModel 添加 custom_prompts 字段 - ConfigUpdateRequest/ConfigResponse 添加 custom_prompts 字段 - 支持 5 个可配置项:system_prompt, user_prompt, continue_prompt, examples, entity_types - 集成到多租户管理器 - 在创建 LightRAG 实例前调用 apply_custom_prompts() - 添加日志记录已应用的 Prompts - 提供 CDN 优化 Prompts 模板文档 - 强制 5 字段关系格式(避免 4/5 fields 错误) - 强制关系描述(避免 missing description 错误) - CDN 技术文档专用实体类型(product, feature, error_code, configuration) 目标:减少实体/关系格式错误,优化 CDN 技术文档处理
1 parent 696bc39 commit b255fb3

6 files changed

Lines changed: 882 additions & 0 deletions

File tree

api/tenant_config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ConfigUpdateRequest(BaseModel):
2525
rerank_config: Optional[Dict[str, Any]] = None
2626
ds_ocr_config: Optional[Dict[str, Any]] = None # 🆕 DeepSeek-OCR 配置
2727
mineru_config: Optional[Dict[str, Any]] = None # 🆕 MinerU 配置
28+
custom_prompts: Optional[Dict[str, Any]] = None # 🆕 Custom Prompts 配置
2829

2930

3031
class ConfigResponse(BaseModel):
@@ -35,6 +36,7 @@ class ConfigResponse(BaseModel):
3536
rerank_config: Optional[Dict[str, Any]]
3637
ds_ocr_config: Optional[Dict[str, Any]] # 🆕 DeepSeek-OCR 配置
3738
mineru_config: Optional[Dict[str, Any]] # 🆕 MinerU 配置
39+
custom_prompts: Optional[Dict[str, Any]] # 🆕 Custom Prompts 配置
3840
created_at: Optional[datetime]
3941
updated_at: Optional[datetime]
4042
merged_config: Optional[Dict[str, Any]] = None
@@ -141,6 +143,7 @@ async def get_tenant_config(tenant_id: str):
141143
rerank_config=mask_config(tenant_config.rerank_config),
142144
ds_ocr_config=mask_config(tenant_config.ds_ocr_config), # 🆕 DeepSeek-OCR
143145
mineru_config=mask_config(tenant_config.mineru_config), # 🆕 MinerU
146+
custom_prompts=tenant_config.custom_prompts, # 🆕 Custom Prompts(无需脱敏)
144147
created_at=tenant_config.created_at,
145148
updated_at=tenant_config.updated_at,
146149
merged_config=masked_merged
@@ -208,6 +211,7 @@ async def update_tenant_config(
208211
rerank_config=mask_config(new_config.rerank_config),
209212
ds_ocr_config=mask_config(new_config.ds_ocr_config), # 🆕 DeepSeek-OCR
210213
mineru_config=mask_config(new_config.mineru_config), # 🆕 MinerU
214+
custom_prompts=new_config.custom_prompts, # 🆕 Custom Prompts(无需脱敏)
211215
created_at=new_config.created_at,
212216
updated_at=new_config.updated_at,
213217
merged_config=None
@@ -309,6 +313,7 @@ async def refresh_tenant_config(tenant_id: str):
309313
rerank_config=mask_config(tenant_config.rerank_config),
310314
ds_ocr_config=mask_config(tenant_config.ds_ocr_config), # 🆕 DeepSeek-OCR
311315
mineru_config=mask_config(tenant_config.mineru_config), # 🆕 MinerU
316+
custom_prompts=tenant_config.custom_prompts, # 🆕 Custom Prompts(无需脱敏)
312317
created_at=tenant_config.created_at,
313318
updated_at=tenant_config.updated_at,
314319
merged_config=masked_merged

docs/cdn_prompts_template.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# CDN 技术文档优化 Prompts
2+
3+
针对 CDN 技术支持文档的实体和关系提取优化 Prompts。
4+
5+
## 使用方法
6+
7+
### 方式 1:环境变量(全局配置)
8+
9+
`.env` 文件中添加:
10+
11+
```bash
12+
# CDN 实体类型
13+
LIGHTRAG_ENTITY_TYPES='["product", "feature", "error_code", "configuration", "api_endpoint", "company", "technology"]'
14+
15+
# CDN 实体提取 System Prompt
16+
LIGHTRAG_ENTITY_EXTRACTION_SYSTEM_PROMPT="You are a technical documentation expert specializing in CDN (Content Delivery Network) systems. Your task is to extract structured information about CDN products, features, error codes, configurations, and technical relationships from support documentation."
17+
```
18+
19+
### 方式 2:租户配置(租户级覆盖)
20+
21+
通过 API 更新租户配置:
22+
23+
```bash
24+
curl -X PUT "http://localhost:8000/tenants/siraya/config" \
25+
-H "Content-Type: application/json" \
26+
-d @- <<'EOF'
27+
{
28+
"custom_prompts": {
29+
"entity_types": [
30+
"product",
31+
"feature",
32+
"error_code",
33+
"configuration",
34+
"api_endpoint",
35+
"company",
36+
"technology"
37+
],
38+
"entity_extraction_system_prompt": "You are a technical documentation expert specializing in CDN (Content Delivery Network) systems. Your task is to extract structured information about CDN products, features, error codes, configurations, and technical relationships from support documentation.",
39+
"entity_extraction_user_prompt": "# Technical Documentation Analysis\n\nExtract entities and relationships from the following CDN technical support documentation.\n\n## Critical Format Requirements\n\n1. **Entities** (4 fields, MANDATORY):\n ```\n entity{tuple_delimiter}name{tuple_delimiter}type{tuple_delimiter}description\n ```\n - name: Use UPPERCASE for technical terms\n - type: MUST be one of: {entity_types}\n - description: Brief, technical description (10-20 words)\n\n2. **Relations** (5 fields, ALL MANDATORY):\n ```\n relation{tuple_delimiter}source{tuple_delimiter}target{tuple_delimiter}keywords{tuple_delimiter}description\n ```\n - source/target: Entity names (UPPERCASE)\n - keywords: Relationship type (e.g., \"uses\", \"configures\", \"causes\", \"resolves\")\n - description: MANDATORY - Explain how source relates to target (10-20 words)\n\n## Entity Types\n\n- **product**: CDN products or services (e.g., \"CDN SERVICE\", \"EDGE COMPUTING\")\n- **feature**: Product features (e.g., \"CACHE CONTROL\", \"GZIP COMPRESSION\")\n- **error_code**: HTTP status codes or error messages (e.g., \"ERROR 403\", \"STATUS 502\")\n- **configuration**: Configuration parameters (e.g., \"TTL SETTING\", \"ORIGIN SERVER\")\n- **api_endpoint**: API paths or endpoints (e.g., \"API /v1/purge\")\n- **company**: Company names or brands\n- **technology**: Technologies or protocols (e.g., \"HTTP/3\", \"TLS 1.3\")\n\n## Important Rules\n\n1. ⚠️ **NEVER skip the description field in relations** - this causes processing failures\n2. ✅ Use technical terminology from the document\n3. ✅ Focus on actionable relationships (e.g., \"ERROR 403~AUTHENTICATION FAILURE\" instead of vague connections)\n4. ✅ Preserve exact error codes and configuration names\n\n## Examples\n\n```\nentity{tuple_delimiter}CDN SERVICE{tuple_delimiter}product{tuple_delimiter}Content delivery network platform providing global edge caching\nentity{tuple_delimiter}CACHE CONTROL{tuple_delimiter}feature{tuple_delimiter}Feature for managing cache expiration and validation policies\nentity{tuple_delimiter}ERROR 403{tuple_delimiter}error_code{tuple_delimiter}HTTP forbidden error indicating access denied by server\nentity{tuple_delimiter}ORIGIN SERVER{tuple_delimiter}configuration{tuple_delimiter}Upstream server that hosts the original content\nrelation{tuple_delimiter}CDN SERVICE{tuple_delimiter}CACHE CONTROL{tuple_delimiter}provides{tuple_delimiter}CDN SERVICE offers CACHE CONTROL as a core feature for optimizing content delivery performance\nrelation{tuple_delimiter}ERROR 403{tuple_delimiter}ORIGIN SERVER{tuple_delimiter}originates_from{tuple_delimiter}ERROR 403 is returned by ORIGIN SERVER when authentication or authorization fails\n```\n\n---\n\n# Input Text\n\n{input_text}\n\n---\n\n# Output Format\n\nReturn ONLY the extracted entities and relations in the format above. Use {completion_delimiter} to separate multiple extractions.\n",
40+
"entity_continue_extraction_user_prompt": "## Continuation Extraction\n\nThe previous extraction reached the token limit. Continue extracting entities and relationships from where we left off.\n\n⚠️ **CRITICAL**: Continue to follow the 5-field relation format:\n```\nrelation{tuple_delimiter}source{tuple_delimiter}target{tuple_delimiter}keywords{tuple_delimiter}description\n```\n\nNEVER skip the description field.\n\n---\n\n# Additional Text\n\n{input_text}\n\n---\n\n# Output\n\nContinue extraction using the same format. Use {completion_delimiter} to separate items.\n",
41+
"entity_extraction_examples": [
42+
"entity{tuple_delimiter}CDN PLATFORM{tuple_delimiter}product{tuple_delimiter}Global content delivery network service with edge caching\nentity{tuple_delimiter}SSL CERTIFICATE{tuple_delimiter}configuration{tuple_delimiter}Digital certificate for HTTPS encryption and authentication\nentity{tuple_delimiter}ERROR 502{tuple_delimiter}error_code{tuple_delimiter}Bad gateway error indicating origin server communication failure\nrelation{tuple_delimiter}CDN PLATFORM{tuple_delimiter}SSL CERTIFICATE{tuple_delimiter}requires{tuple_delimiter}CDN PLATFORM requires valid SSL CERTIFICATE for secure HTTPS connections\nrelation{tuple_delimiter}ERROR 502{tuple_delimiter}ORIGIN SERVER{tuple_delimiter}indicates_failure{tuple_delimiter}ERROR 502 occurs when CDN cannot reach ORIGIN SERVER or receives invalid response"
43+
]
44+
}
45+
}
46+
EOF
47+
```
48+
49+
## 配置优先级
50+
51+
租户配置 > 环境变量 > LightRAG 默认值
52+
53+
## 效果预期
54+
55+
使用优化后的 Prompts,实体和关系提取将:
56+
-**减少格式错误**:强调 5 字段关系格式,减少 "4/5 fields" 错误
57+
-**技术术语规范化**:使用 UPPERCASE 统一技术实体名称
58+
-**关系描述强制要求**:避免 "Relation XXX has no description" 错误
59+
-**CDN 领域优化**:针对 CDN 文档特点(产品、功能、错误码、配置)定制实体类型
60+
61+
## 测试步骤
62+
63+
1. **配置租户 Prompts**
64+
```bash
65+
curl -X PUT "http://localhost:8000/tenants/siraya/config" \
66+
-H "Content-Type: application/json" \
67+
-d @cdn_tenant_config.json
68+
```
69+
70+
2. **验证配置生效**
71+
```bash
72+
curl "http://localhost:8000/tenants/siraya/config"
73+
```
74+
75+
3. **清理旧数据**(如果需要重新处理文档):
76+
```bash
77+
# 清理 Redis LLM 缓存
78+
docker exec rag-dragonflydb redis-cli --scan --pattern "siraya_llm_response_cache:*" | \
79+
xargs -I {} docker exec rag-dragonflydb redis-cli DEL {}
80+
81+
# 清理实例缓存(强制重新创建 LightRAG 实例)
82+
curl -X POST "http://localhost:8000/tenants/siraya/config/refresh"
83+
```
84+
85+
4. **上传文档测试**
86+
```bash
87+
curl -X POST "http://localhost:8000/insert?tenant_id=siraya&doc_id=cdn_faq_v2" \
88+
-F "file=@cdn_support_docs.md" \
89+
-F "parser=auto"
90+
```
91+
92+
5. **监控日志**
93+
```bash
94+
docker logs -f rag-api 2>&1 | grep -E "(Applied custom prompts|Chunk [0-9]+ of|found 4/5 fields)"
95+
```
96+
97+
## 日志示例
98+
99+
成功应用 Prompts 后,日志应显示:
100+
101+
```
102+
[Tenant siraya] Applied custom prompts: system_prompt, user_prompt, continue_prompt, examples(1), entity_types(7)
103+
✓ LightRAG instance created for tenant: siraya (workspace=siraya, VLM enabled)
104+
```
105+
106+
处理文档时,应看到 **** "found 4/5 fields" 警告。
107+
108+
## 故障排查
109+
110+
### 问题 1:Prompts 未生效
111+
112+
**症状**:日志中没有 "Applied custom prompts" 消息
113+
114+
**解决**
115+
```bash
116+
# 1. 检查配置是否保存
117+
curl "http://localhost:8000/tenants/siraya/config" | jq .custom_prompts
118+
119+
# 2. 强制刷新实例缓存
120+
curl -X POST "http://localhost:8000/tenants/siraya/config/refresh"
121+
122+
# 3. 重启服务(如果是开发环境)
123+
docker compose -f docker-compose.dev.yml restart rag-api
124+
```
125+
126+
### 问题 2:仍有格式错误
127+
128+
**症状**:日志仍显示 "found 4/5 fields on RELATION"
129+
130+
**可能原因**
131+
1. LLM 缓存未清理(使用旧结果)
132+
2. Prompt 格式占位符错误(检查 `{tuple_delimiter}` 等占位符)
133+
134+
**解决**
135+
```bash
136+
# 清理 LLM 缓存
137+
docker exec rag-dragonflydb redis-cli --scan --pattern "siraya_llm_response_cache:*" | \
138+
xargs -I {} docker exec rag-dragonflydb redis-cli DEL {}
139+
140+
# 清理文档状态并重新上传
141+
docker exec rag-dragonflydb redis-cli DEL "siraya_doc_status:{doc_id}"
142+
```
143+
144+
### 问题 3:Entity Types 未应用
145+
146+
**症状**:提取的实体类型不符合预期
147+
148+
**注意**:当前实现中,`entity_types` 通过 Prompt 注入,不需要额外的 `addon_params` 配置。
149+
150+
## 参考资料
151+
152+
- [LightRAG Prompt 格式说明](../docs/lightrag_entity_extraction_format.md)
153+
- [租户配置 API 文档](../api/tenant_config.py)
154+
- [Prompt Manager 源码](../src/prompt_manager.py)

0 commit comments

Comments
 (0)