1.问题引入

就是目前会存在一种情况,就是我们是使用第三方框架的,用的是langchain4j,它里面会有相应的依赖,然后会有文档告诉我们去创建相应的实例,但是如果这个框架(比如langchain4j)没有相应的这个模型相应的实现方法(比如说公司就是不用那种大众的大模型,想用偏门的模型)那我们应该怎么做才可以实现相应的调用呢?

2.关于生成图片的模型

其实这个时候就需要我们看底层了,今天拿调用生成图片大模型来举例(哈哈哈哈,咋说勒,周日上课,呜呜呜我不知道早上啊看错课表了,当时忙着期末周去了,后面老师有个视频没给我录下,那个是关于调用生成图像大模型的)其实那些框架就是实现了接口,向相应的大模型发送http请求,所以我们也同理,需要去实现相应的接口,重写里面的方法,就可以建立起与大模型的连接

找了一个网页硅基流动(一个人工智能基础设施平台),里面有挺多模型的,就是在里面找了一个免费的图像生成模型(Kolors)然后就是点进里面的API文档里面去

之后可以看到这样的界面

主要是看http请求吧我们是需要发这个的

然后就是关于实现接口了,在生成图片模型中,我们需要实现ImageModel这个接口

//自定义一个文生图模型
class SiliconFlowImageModel implements ImageModel {
    //这就是一个http客户端,用来发送http请求
    private final String apiKey;
    //这里其实是一个客户端就行了,也可以是原始java自带的HttpClient
    private final OkHttpClient client = new OkHttpClient();
    public SiliconFlowImageModel(String apiKey) {
        this.apiKey = apiKey;
    }

    @Override
    public Response<Image> generate(String prompt) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        String json = String.format("{\"prompt\":\"%s\",\"model\":\"%s\", \"size\":\"512x512\"}", prompt,"Kwai-Kolors/Kolors");

        Request request = new Request.Builder()
                .url("http://api.siliconflow.cn/v1/images/generations")
                .post(RequestBody.create( json,mediaType))
                //使用以下格式进行身份验证:Bearer <您的 API 密钥>
                .addHeader("Authorization", "Bearer " + apiKey)
                .build();
        try(okhttp3.Response response = client.newCall(request).execute()) {
           if(!response.isSuccessful()) {
               throw new RuntimeException("Unexpected code " + response.code());
           }
           String responseBody = response.body().string();

           //这里是下面的内容了哈哈哈,都放一起了,好看一丢丢~
           int start = responseBody.indexOf("http");
           int end = responseBody.indexOf("\"", start);
           String imageUrl = responseBody.substring(start, end);
           Image image = Image.builder().url(imageUrl).build();
            Response<Image> result = Response.from(image);
            return result;
        }catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}

发送完请求我们可以接受到响应嘛,上上面不是有那个200的输出的json格式嘛,就根据那个截取生成图片的地址,然后在main方法里面创建实例和调用

public static void main(String[] args) {
        ImageModel imageModel = new SiliconFlowImageModel("你的密钥");
        Response<Image> response = imageModel.generate("请生成一个小猫的图片");
        System.out.println("生成图片的地址"+response.content().url());
    }

没咯没咯,我的天,还有好多东西,快补呜呜呜,好了,完整代码就是以下这样的:

import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.image.ImageModel;
import dev.langchain4j.model.output.Response;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

public class MyImageModelTest {
    public static void main(String[] args) {
        ImageModel imageModel = new SiliconFlowImageModel("你的密钥");
        Response<Image> response = imageModel.generate("请生成一个小猫的图片");
        System.out.println("生成图片的地址"+response.content().url());
    }
}

//自定义一个文生图模型
class SiliconFlowImageModel implements ImageModel {
    //这就是一个http客户端,用来发送http请求
    private final String apiKey;
    private final OkHttpClient client = new OkHttpClient();
    public SiliconFlowImageModel(String apiKey) {
        this.apiKey = apiKey;
    }

    @Override
    public Response<Image> generate(String prompt) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        String json = String.format("{\"prompt\":\"%s\",\"model\":\"%s\", \"size\":\"512x512\"}", prompt,"Kwai-Kolors/Kolors");

        Request request = new Request.Builder()
                .url("http://api.siliconflow.cn/v1/images/generations")
                .post(RequestBody.create( json,mediaType))
               .addHeader("Authorization", "Bearer " + apiKey)
               .build();
        try(okhttp3.Response response = client.newCall(request).execute()) {
           if(!response.isSuccessful()) {
               throw new RuntimeException("Unexpected code " + response.code());
           }
           String responseBody = response.body().string();
           int start = responseBody.indexOf("http");
           int end = responseBody.indexOf("\"", start);
           String imageUrl = responseBody.substring(start, end);
           Image image = Image.builder().url(imageUrl).build();
            Response<Image> result = Response.from(image);
            return result;
        }catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}

3关于聊天模型的调用 

同理,也是去构造http请求

硅基流动找到免费deepsek模型api手册https://docs.siliconflow.cn/cn/api-reference/chat-completions/chat-completions

然后发送请求,接着解析响应,代码就是长这样

import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.ModelProvider;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class MychatModelTest {
    public static void main(String[] args) {
        ChatModel chatModel = new SiliconFlowChatModel("你的硅基流动网站的密钥");
        String response = chatModel.chat("你是谁");
        System.out.println("AI Response: " + response);
    }
}

class SiliconFlowChatModel implements ChatModel {
    private final String apiKey;
    private final OkHttpClient client = new OkHttpClient();
    private final ObjectMapper objectMapper = new ObjectMapper();
    private static final String API_URL = "https://api.siliconflow.cn/v1/chat/completions";
    private static final String MODEL_NAME = "Qwen/QwQ-32B";

    public SiliconFlowChatModel(String apiKey) {
        this.apiKey = apiKey;
    }

    @Override
    public ChatResponse doChat(ChatRequest chatRequest) {
        try {
            // 1. 构造请求体
            String requestBody = buildRequestBody(chatRequest.messages());

            // 2. 创建HTTP请求
            Request request = buildHttpRequest(requestBody);

            // 3. 发送请求并获取响应
            try (okhttp3.Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new RuntimeException("API request failed: " + response.code() + " - " + response.body().string());
                }

                // 4. 解析响应并返回结果
                return parseResponse(response.body().string());
            }
        } catch (IOException e) {
            throw new RuntimeException("Failed to call SiliconFlow API", e);
        }
    }

    private String buildRequestBody(List<ChatMessage> messages) throws IOException {
        return objectMapper.writeValueAsString(Map.of(
                "model", MODEL_NAME,
                "messages", messages.stream()
                        .map(this::buildMessageMap)
                        .toList()
        ));
    }
    private Map<String, String> buildMessageMap(ChatMessage msg) {
        return Map.of(
                "role", getRole(msg),
                "content", getContent(msg)
        );
    }
    private String getRole(ChatMessage msg) {
        //return msg instanceof UserMessage ? "user" : "assistant";
        //(这里咋说呢,我当时觉得很奇怪,deepseek给我构造的请求,
        //它这里还有判断,但是如果我只发一次请求,那我就是user了啊,
        //后面看它的解释说是存在记忆存储的部分,
        //但是我这种就是很简单的实现接口,感觉直接写user也行)
        return "user";
    }
    private String getContent(ChatMessage msg) {
        // 使用 toString() 方法获取消息内容
        return msg.toString();
    }
    private Request buildHttpRequest(String requestBody) {
        return new Request.Builder()
                .url(API_URL)
                .post(RequestBody.create(requestBody, MediaType.parse("application/json")))
                .addHeader("Authorization", "Bearer " + apiKey)
                .build();
    }
    private ChatResponse parseResponse(String responseBody) throws IOException {
        Map<String, Object> responseMap = objectMapper.readValue(responseBody, Map.class);
        Map<String, Object> choice = ((List<Map<String, Object>>) responseMap.get("choices")).get(0);
        Map<String, String> message = (Map<String, String>) choice.get("message");
        String aiResponse = message.get("content");

        return ChatResponse.builder()
                .aiMessage(new AiMessage(aiResponse))
                .build();
    }
    @Override
    public ModelProvider provider() {
        return ModelProvider.OTHER;
    }
}

让我碎碎念一下,这个ai编程和传统的编程模型真的很不一样,给我看呆了,全是基于对话的方式了,谁懂我今天就是跟ai对话,它自动调用我写的工具类的震撼,太牛逼了哈哈哈

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐