diff --git a/docs/zh/core/llms.md b/docs/zh/core/llms.md new file mode 100644 index 0000000..358d14c --- /dev/null +++ b/docs/zh/core/llms.md @@ -0,0 +1,283 @@ +# LLMs 大语言模型 + +Agents-Flex 提供了关于大语言模型的抽象实现接口 `Llm.java`,它支持 `chat` 以及 `chatStream` 两种不同的对话方式。 + +针对不同的厂商,Agents-Flex 提供了不同的实现类以及通信协议,其中通信协议包括了 `HTTP`、`SSE` 以及 `WebSocket` 等客户端。 + +## 大模型支持 + +目前,Agents-Flex 已支持以下的大语言模型: + +- OpenAI(ChatGPT,以及所有的兼容 OpenAI 接口的大模型) +- ChatGLM(智普大模型) +- Coze (调用 Coze 的智能体) +- DeepSeek +- Gitee AI +- Moonshot(月之暗面) +- Ollama(通过 Ollama 部署的所有大模型) +- Qianfan(百度千帆部署的大模型) +- Qwen(千问大模型,阿里云百炼平台部署的大模型) +- Spark(星火大模型) + + +## 简单对话 +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + + // 设置你的 OpenAI API Key + config.setApiKey("sk-rts5NF6n*******"); + + Llm llm = new OpenAILlm(config); + String response = llm.chat("请问你叫什么名字"); + + System.out.println(response); +} +``` + +## 流式对话 + +```java +public static void main(String[] args) { + + OpenAILlmConfig config = new OpenAILlmConfig(); + // 设置你的 OpenAI API Key + config.setApiKey("sk-rts5NF6n*******"); + + Llm llm = new OpenAILlm(config); + + llm.chatStream("你叫什么名字", new StreamResponseListener() { + + @Override + public void onMessage(ChatContext context, AiMessageResponse response) { + System.out.println(response.getMessage().getContent()); + } + + }); +} +``` + +## 流式对话之停止对话 + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + + // 设置你的 OpenAI API Key + config.setApiKey("sk-rts5NF6n*******"); + + Llm llm = new OpenAILlm(config); + llm.chatStream("你叫什么名字", new StreamResponseListener() { + @Override + public void onMessage(ChatContext context, AiMessageResponse response) { + System.out.println(response.getMessage().getContent()); + + //停止对话 + context.getClient().stop(); + } + }); +} +``` + + +## 流式对话之更多的监听 + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + + // 设置你的 OpenAI API Key + config.setApiKey("sk-rts5NF6n*******"); + + Llm llm = new OpenAILlm(config); + llm.chatStream("你叫什么名字", new StreamResponseListener() { + @Override + public void onMessage(ChatContext context, AiMessageResponse response) { + AiMessage message = response.getMessage(); + System.out.println(message.getContent()); + } + + @Override + public void onStart(ChatContext context) { + System.out.println("开始"); + } + + @Override + public void onStop(ChatContext context) { + System.out.println("结束"); + } + + @Override + public void onFailure(ChatContext context, Throwable throwable) { + System.out.println("错误"); + } + }); +} +``` + +## 图片识别对话 + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + + // 设置你的 OpenAI API Key + config.setApiKey("sk-5gqOcl*****"); + config.setModel("gpt-4-turbo"); + + + Llm llm = new OpenAILlm(config); + ImagePrompt prompt = new ImagePrompt("What's in this image?"); + prompt.setImageUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"); + + //或者 prompt.setImageFile(new File("/your-image-path.png")) + //或者 prompt.setImageStream(imageInputStream) + //或者 prompt.setImageBase64("image base64 data....") + + AiMessageResponse response = llm.chat(prompt); + System.out.println(response); +} +``` + +## 方法调用(Function Calling) + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + config.setApiKey("sk-rts5NF6n*******"); + + OpenAILlm llm = new OpenAILlm(config); + + FunctionPrompt prompt = new FunctionPrompt("今天北京的天气怎么样", WeatherFunctions.class); + AiMessageResponse response = llm.chat(prompt); + + System.out.println(response.callFunctions()); + // "Today it will be dull and overcast in 北京" +} +``` + +`WeatherFunctions.class` 代码如下: + +```java +public class WeatherFunctions { + + @FunctionDef(name = "get_the_weather_info", description = "get the weather info") + public static String getWeatherInfo( @FunctionParam(name = "city", description = "the city name") String name) { + return "Today it will be dull and overcast in " + name; + } +} +``` + + +## 历史对话 + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + config.setApiKey("sk-rts5NF6n*******"); + + OpenAILlm llm = new OpenAILlm(config); + + //第一步:创建一个 HistoriesPrompt + HistoriesPrompt prompt = new HistoriesPrompt(); + + System.out.println("您想问什么?"); + Scanner scanner = new Scanner(System.in); + String userInput = scanner.nextLine(); + + while (userInput != null) { + + // 第二步:将用户输入添加到 HistoriesPrompt 中 + prompt.addMessage(new HumanMessage(userInput)); + + // 第三步:调用 chatStream 方法,进行对话 + llm.chatStream(prompt, (context, response) -> { + System.out.println(">>>> " + response.getMessage().getContent()); + }); + + userInput = scanner.nextLine(); + } +} +``` + +关于 HistoriesPrompt 更多的配置: + +```java +HistoriesPrompt prompt = new HistoriesPrompt(); + +//设置系统消息 +prompt.setSystemMessage(new SystemMessage('你是一个数据库开发工程师....')); + +//设置最大历史消息数量 +prompt.setMaxAttachedMessageCount(10); + +//设置是否开启历史消息截断 +prompt.setHistoryMessageTruncateEnable(true); + +//设置历史消息截断长度 +prompt.setHistoryMessageTruncateLength(1000); + +//自定义历史消息截断处理器 +prompt.setHistoryMessageTruncateProcessor(...); + +//设置历史消息存储器 +prompt.setMemory(...); +``` + +## 历史对话 + 方法调用 + +```java +public static void main(String[] args) { + OpenAILlmConfig config = new OpenAILlmConfig(); + config.setApiKey("sk-rts5NF6n*******"); + + OpenAILlm llm = new OpenAILlm(config); + + //第一步:创建一个 HistoriesPrompt + HistoriesPrompt prompt = new HistoriesPrompt(); + + System.out.println("您想问什么?"); + Scanner scanner = new Scanner(System.in); + String userInput = scanner.nextLine(); + + while (userInput != null) { + + // 第二步:创建 HumanMessage,并添加方法调用 + HumanMessage humanMessage = new HumanMessage(userInput); + humanMessage.addFunctions(WeatherFunctions.class); + + // 第三步:将 HumanMessage 添加到 HistoriesPrompt 中 + prompt.addMessage(humanMessage); + + // 第四步:调用 chatStream 方法,进行对话 + llm.chatStream(prompt, new StreamResponseListener() { + @Override + public void onMessage(ChatContext context, AiMessageResponse response) { + boolean functionCall = response.isFunctionCall(); + if (functionCall) { + System.out.println("do func >>> "); + StringBuilder text = new StringBuilder("调用工具结果如下:\n"); + List callers = response.getFunctionCallers(); + for (FunctionCaller caller : callers) { + String name = caller.getFunction().getName(); + Object callRes = caller.call(); + text.append("调用[").append(name).append("]的结果为:").append(callRes).append("\n"); + } + HumanMessage msg = new HumanMessage(text.toString()); + prompt.addMessage(msg); + llm.chatStream(prompt, new StreamResponseListener() { + @Override + public void onMessage(ChatContext context, AiMessageResponse response) { + System.out.println("after func >>>> " + response.getMessage().getContent()); + } + }); + } else { + System.out.println("normal >>>> " + response.getMessage().getContent()); + } + } + }); + + userInput = scanner.nextLine(); + } +} +```