skills - 提示语(Prompt)的动态赋能
2026年1月22日 下午10:58:43
在 Solon AI 中,ChatPrompt(实现类为 Prompt) 不仅仅是一个简单的消息集合,它是一个具备感知能力的“执行上下文”。通过 attrs(属性)机制,开发者可以为 AI 的执行过程注入动态参数与运行时资源,这是构建工业级 Agent 的核心基础。
1、Prompt 及运行时属性
ChatPrompt 接口通过 attrs() 提供了一个全生命周期的属性桶(Attribute Bucket)。与传统的静态元数据(Metadata)不同,attrs 专为运行态设计:
- 动态性: 支持挂载
ChatSession(有状态会话)、业务拦截器状态、或数据库连接等动态对象。 - 本地化隔离:
attrs中的数据仅在后端流转,不参与提示词染色。这意味着你可以放心地放入user_id、role_level等敏感业务属性,而不用担心它们被泄露给远端大模型。 - 语义萃取: 提供了
getUserContent()逆序查找算法。它能穿透多轮对话的噪音,精准定位用户最后一次输入的有效意图,确保 Skill 的判断始终基于当前的最新上下文。
接口参考:
public interface ChatPrompt {
//获取属性
Map<String, Object> attrs();
//获取属性
default Object attr(String key) {
return attrs().get(key);
}
//获取属性
default <T> T attrAs(String key) {
return (T) attrs().get(key);
}
//获取属性
default <T> T attrOrDefault(String key, T def) {
return (T) attrs().getOrDefault(key, def);
}
//获取消息
List<ChatMessage> getMessages();
//获取首条消息
ChatMessage getFirstMessage();
//获取最后消息
ChatMessage getLastMessage();
//获取用户消息内容
String getUserContent();
//获取系统消息内容
String getSystemContent();
//是否为空
boolean isEmpty();
//是否为空
static boolean isEmpty(ChatPrompt prompt) {
return prompt == null || prompt.isEmpty();
}
}
2、动态赋能:基于业务上下文的 Skill 决策逻辑
基于 Prompt 的属性机制,Skill 获得了超越普通工具(Tool)的“工程智力”,主要体现在以下三个维度:
A. 环境感知的准入检查 (isSupported)
Skill 可以通过 Prompt.attr() 实时感知业务环境,实现动态唤醒:
- 权限管控:只有当
attr("role")为管理员时,才激活“系统管理技能”。 - 状态过滤:根据
attr("step")的进度,动态决定当前是否应该唤醒某个特定环节的技能包。
B. 运行时资源共享 (onAttach)
Skill 可以在执行生命周期内操作 Prompt 的属性,实现黑板模式的协作:
- 上下文补全:在 Skill 被附着(Attach)时,根据
attrs中的用户信息,预先从数据库加载业务背景存入attrs。 - 信息共享:多个协同的 Skill 之间可以通过修改
attrs共享中间计算结果,避免重复查库或重复计算。
C. 指令的动态增强 (getInstruction)
Skill 不再提供死板的提示词,而是可以根据属性动态生成。
- 个性化偏好:读取 attr("language_style"),动态调整注入给大模型的 System Instruction,实现一套代码适配万千租户的业务规约。
3、代码实战:多租户权限感知技能
在这个示例中,我们实现一个“订单管理专家”技能。它会根据 attrs 里的租户 ID 锁定数据范围,并根据用户角色决定是否开放“取消订单”的工具。
public class OrderManagerSkill implements Skill {
@Override
public boolean isSupported(ChatPrompt prompt) {
// 1. 语义检查:用户当前意图是否与“订单”相关(逆序获取最新意图)
boolean isOrderTask = prompt.getUserContent().contains("订单");
// 2. 环境检查:必须持有合法的租户 ID 属性才能激活
boolean hasTenant = prompt.attr("tenant_id") != null;
return isOrderTask && hasTenant;
}
@Override
public String getInstruction(ChatPrompt prompt) {
// 3. 动态指令:从 attrs 获取租户名,注入隔离指令
// 这样模型就知道它只能处理该租户的数据,而不需要前端在 Prompt 里写明
String tenantName = prompt.attrOrDefault("tenant_name", "未知租户");
return "你现在是[" + tenantName + "]的订单主管。请只处理该租户下的订单数据,禁止跨租户查询。";
}
@Override
public Collection<FunctionTool> getTools(ChatPrompt prompt) {
List<FunctionTool> tools = new ArrayList<>();
// 基础查询工具(所有激活技能的用户都有)
tools.add(new OrderQueryTool());
// 4. 权限隔离:只有属性中标记为 ADMIN 的用户,才动态挂载“取消订单”工具
if ("ADMIN".equals(prompt.attr("user_role"))) {
tools.add(new OrderCancelTool());
}
return tools;
}
}