共计 2049 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点:为什么我们需要区分 skill 和 prompt?
在构建对话系统时,很多开发者容易将 skill 和 prompt 混为一谈,这会导致一些典型问题:

- 意图识别错误 :当系统无法明确区分是触发一个完整技能(skill) 还是简单文本补全 (prompt) 时,NLU 模块会产生误判
- 上下文丢失:prompt 通常是单次请求响应,而 skill 需要维护对话状态,混用会导致状态机管理混乱
- 性能瓶颈:不恰当的使用会让系统要么过度消耗资源(skill 处理简单请求),要么无法完成复杂任务(用 prompt 链式调用)
概念对比:从技术本质理解差异
1. 触发方式
- Skill:
- 通过意图识别明确触发
- 需要完整的 NLU 管道处理
-
示例:” 帮我订明天去北京的机票 ” → 机票预订 skill
-
Prompt:
- 通过模板匹配或直接输入触发
- 可能绕过部分 NLU 处理
- 示例:” 续写下文:春天来了,” → 文本补全 prompt
2. 生命周期
- Skill:
- 多轮对话保持活跃
- 需要维护会话状态
-
可被显式终止(如 ” 取消订票 ”)
-
Prompt:
- 单次请求 - 响应周期
- 无状态设计
- 每次调用相互独立
3. 上下文继承
- Skill:
- 自动继承对话历史
- 可访问领域特定数据库
-
支持槽位填充
-
Prompt:
- 需显式传递上下文
- 依赖模板变量
- 最大长度受限
代码示例:Python 实现对比
Skill 处理类示例
class BookingSkill:
"""机票预订 skill 实现"""
def __init__(self):
self.state = {
'step': 0, # 0= 未开始, 1= 选择日期, 2= 选择航班
'slots': {'destination': None, 'date': None}
}
def handle(self, user_input: str) -> tuple[str, bool]:
"""
处理用户输入
:param user_input: 用户当前语句
:return: (响应文本, 是否完成)
"""
try:
if self.state['step'] == 0:
# NLU 提取目的地逻辑...
self.state['slots']['destination'] = "北京"
self.state['step'] = 1
return "请问您要哪天出发?", False
# 后续步骤处理...
except Exception as e:
logging.error(f"BookingSkill error: {str(e)}")
return "系统出错,请稍后再试", True
Prompt 模板示例
from string import Template
summary_prompt = Template("""
请用不超过 50 字总结以下文本:$text
总结:""")
def generate_summary(text: str) -> str:
try:
prompt = summary_prompt.substitute(text=text)
# 调用 LLM API...
return "这里是生成的摘要..."
except KeyError as e:
logging.warning(f"Missing template variable: {e}")
raise
架构建议:生产环境部署方案
Skill 集群部署
- 按领域垂直拆分微服务(旅游、餐饮等独立部署)
- 使用 Redis 维护对话状态
- 通过 API 网关实现 skill 路由
Prompt 优化策略
- 建立模板版本控制系统
- 实现 LRU 缓存热门 prompt
- 对长 prompt 进行分块处理
避坑指南:三个关键问题解决方案
1. Prompt 注入攻击
- 现象:用户输入包含恶意模板指令
- 解决方案:
- 对用户输入进行 HTML 转义
- 使用白名单校验变量内容
- 示例防御代码:
from html import escape def safe_substitute(template: str, params: dict) -> str: escaped = {k: escape(str(v)) for k,v in params.items()} return template.format(**escaped)
2. Skill 状态同步
- 现象:分布式环境下状态不一致
- 解决方案:
- 采用乐观锁控制并发
- 设置状态 TTL 自动过期
- 使用 ETag 进行版本控制
3. 混合使用冲突
- 现象:prompt 调用打断 skill 流程
- 解决方案:
- 建立优先级机制
- 显式状态检查(如 ” 当前正在订票,是否确定取消?”)
- 设置超时自动释放
性能考量:实测数据对比
| 指标 | Skill 处理 | Prompt 处理 |
|---|---|---|
| 平均延迟(ms) | 120-300 | 50-150 |
| 内存占用(MB) | 40-100 | 10-30 |
| 并发能力(RPS) | 100-500 | 1000-5000 |
| 上下文长度 | 无硬性限制 | 通常 2048token |
开放思考:混合架构的可能性
在实际业务中,完全隔离 skill 和 prompt 可能并不现实。值得我们深入探讨:
- 如何设计熔断机制,当 prompt 连续失败时自动降级到 skill?
- 能否建立统一的上下文管理中间件,同时支持两种模式?
- 在模型微调时,应该如何平衡 skill 专用模型和通用 prompt 模型的关系?
这些问题的答案可能因业务场景而异,但思考过程本身就能帮助我们更好地理解两者的本质区别。
正文完
