本篇文章主要介绍LangChain4j对ChatGPT角色设置、提示词模版的使用,最后实现一个只做汉语到英语的翻译助手,对于别的事情一概不做。
实现一个仅支持英文的翻译助手,需要两个方面的内容:
- 角色设定:指定是一个专业英文翻译官
- 模版:如何设置合理的提示词模版,当要翻译其它语言就返回不会翻译
角色设定
角色设置就是规定大模型可以干什么,比如你是一个诗人、或者你是画家。这样让大模型更专注于某个领域知识的回答。在Spring AI 专栏# 05. Spring AI 实现ChatGPT的人设(角色)定义 中有详细的说明。
回顾一下大模型的消息类型;
角色的设定主要利用大模型消息的特性来实现,其中的
SystemMessage
可以指定角色。因为其特性比其他类型的消息优先级更高。
模版使用
-
@UserMessage/@SystemMessage + @V
@UserMessage("You are a good friend of mine. Answer using slang. {{message}}") String chat(@V("message") String userMessage);
在使用上的几点说明:
- 如果只有一个参数,可以使用 {{it}}, 无需在使用@V指定参数名称。
- @UserMessage/@SystemMessage注解 可以直接指定字符串也可以使用
fromResource
字段可以引用一个文件。
-
使用 @StructuredPrompt 先定义一个模版请求类,然后将注解加 @StructuredPrompt 注解即可
@Getter @AllArgsConstructor @StructuredPrompt("xxx {{aa}}, yyyyy {{bb}}") // 按照需要定义 class XxxxPrompt { private String aa; private String bb; }
-
PromptTemplate
PromptTemplate promptTemplate = PromptTemplate.from("Say 'hi' in {{it}}."); Prompt prompt = promptTemplate.apply("German"); System.out.println(prompt.text()); // Say 'hi' in German.
实现原理
底层使用就是String 类的字符串替换,没有用到其它技术,主要实现类(默认) DefaultTemplate
// 生成提示词字符串
public String render(Map<String, Object> variables) {
ensureAllVariablesProvided(variables);
String result = template;
for (Map.Entry<String, Object> entry : variables.entrySet()) {
result = replaceAll(result, entry.getKey(), entry.getValue());
}
return result;
}
// 使用值替换到{{变量名}}
private static String replaceAll(String template, String variable, Object value) {
if (value == null || value.toString() == null) {
throw illegalArgument("Value for the variable '%s' is null", variable);
}
return template.replace(inDoubleCurlyBrackets(variable), value.toString());
}
private static String inDoubleCurlyBrackets(String variable) {
return "{{" + variable + "}}";
}
LangChain4j框架在设计上给开发者通过SPI方式留出扩展点,可以自定义模型解析方式。默认提供了一个DefaultTemplate实现类。
翻译助手
Translator
package org.ivy.chatmemory.service;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
@AiService
public interface Translator {
// 指定角色
@SystemMessage("You are a professional translator. You can only translate Chinese text to English. If other languages You response I can not translate, ")
// 翻译文本
@UserMessage("Translate the following text: {{text}} to {{language}}")
String translate(@V("text") String text, @V("language") String language);
}
Controller
package org.ivy.chatmemory.controller;
import org.ivy.chatmemory.service.Translator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TranslatorController {
private final Translator translator;
public TranslatorController(Translator translator) {
this.translator = translator;
}
@GetMapping("/translate")
public String translate(@RequestParam("text") String text, @RequestParam("language") String language) {
return translator.translate(text, language);
}
}
测试
翻译为英文
翻译为日语
当让翻译助手将中文翻译为日语时,提示不会翻译!
总结与示例代码
本文实现了一个仅支持英文的翻译助手,主要实践实现角色定义和提示词的使用,如何设定角色,如何使用提示词模板。
示例代码:template