skills - helloworld
2026年1月22日 下午10:19:50
1、引入依赖
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai</artifactId>
</dependency>
2、构建技能组件(Skill)
@Component
public class WeatherSkill extends AbsSkill {
//封装权限(准入控制)
@Override
public boolean isSupported(ChatPrompt prompt) {
//演示:获取更多属性,用于准入控制(需要请求明传入)
ChatSession session = prompt.attrAs("session");
return prompt.getUserContent().contains("天气");
}
//封装指令
@Override
public String getInstruction(ChatPrompt prompt) {
return "如果有什么天气问题,可以问我";
}
//封装能力
@ToolMapping(description = "查询天气预报")
public String getWeather(@Param(description = "城市位置") String location) {
return "晴,14度";
}
}
3、聊天模型配置与构建
@Configuration
public class ChatConfig {
@Bean
public ChatModel chatModelForSkill(WeatherSkill weatherSkill) {
return ChatModel.of(_Constants.chat_apiUrl)
.provider(_Constants.chat_provider)
.model(_Constants.chat_model)
.defaultSkillAdd(weatherSkill)
.build();
}
}
4、与 Web 控制器集成
@Mapping("chat")
@Controller
public class ChatController {
@Inject
ChatModel chatModel;
@Produces(MimeType.TEXT_PLAIN_VALUE)
@Mapping("call")
public String call(String query) throws Exception {
//仅用于演示
ChatSession session = InMemoryChatSession.builder().build();
//演示:添加提示词属性(用于 Skill)
Prompt prompt = Prompt.of(query).attrPut("session", session);
return chatModel.prompt(prompt)
.session(session)
.call()
.getMessage()
.getContent();
}
@Produces(MimeType.TEXT_EVENT_STREAM_VALUE)
@Mapping("stream")
public Flux<String> stream(String prompt) throws Exception {
return Flux.from(chatModel.prompt(prompt).stream())
.subscribeOn(Schedulers.boundedElastic()) //加这个打印效果更好
.filter(resp -> resp.hasContent())
.map(resp -> resp.getContent())
.concatWithValues("[DONE]"); //有些前端框架,需要 [DONE] 实识用作识别
}
}