跳转到主要内容
PRODUCT DOCUMENTS

快速找到所需文档,高效完成接入与排障

浏览产品文档与友盟 Skill,展开目录并阅读正文。

Java

Maven 依赖(pom.xml 中添加)

<dependencies>
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.12.0</version>
    </dependency>
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp-sse</artifactId>
        <version>4.12.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.17.0</version>
    </dependency>
</dependencies>

如果你已使用 Spring Boot 3,可直接用 Spring 自带的 RestTemplate / WebClient,无需额外引入 OkHttp。

1) 非流式聊天 - UmengAiClient.java

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class UmengAiClient {
    private static final String BASE_URL = "https://ai.umeng.com";
    private static final String API_KEY = "YOUR_API_KEY";

    // OkHttp 默认 readTimeout 仅 10 秒,大模型响应普遍超过 10 秒,必须显式调大
    private final OkHttpClient client = new OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .readTimeout(120, TimeUnit.SECONDS)
        .build();
    private final ObjectMapper mapper = new ObjectMapper();

    public String chat(String prompt) throws Exception {
        Map<String, Object> body = Map.of(
            "model", "auto",
            "enableThinking", false,
            "messages", List.of(Map.of("role", "user", "content", prompt))
        );

        Request req = new Request.Builder()
            .url(BASE_URL + "/api/llm/chat")
            .header("Authorization", "Bearer " + API_KEY)
            .header("Content-Type", "application/json")
            .post(RequestBody.create(
                mapper.writeValueAsBytes(body),
                MediaType.get("application/json")))
            .build();

        try (Response resp = client.newCall(req).execute()) {
            JsonNode json = mapper.readTree(resp.body().byteStream());
            if (!json.path("success").asBoolean()) {
                throw new RuntimeException("接口返回失败: " + json.path("msg").asText());
            }
            JsonNode data = json.path("data");
            System.out.printf("路由模型=%s, 算力点=%d%n",
                data.path("meta").path("actual_model").asText(),
                data.path("usage").path("cost_credits").asInt());
            return data.path("content").asText();
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println("回答: " + new UmengAiClient().chat("用一句话介绍牛顿第一定律"));
    }
}

2) 流式聊天(SSE) - 逐字接收

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class UmengAiStreamClient {
    private static final String BASE_URL = "https://ai.umeng.com";
    private static final String API_KEY = "YOUR_API_KEY";

    public static void main(String[] args) throws Exception {
        // SSE 长连接必须调大 readTimeout
        OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(300, TimeUnit.SECONDS)
            .build();
        ObjectMapper mapper = new ObjectMapper();

        Map<String, Object> body = Map.of(
            "model", "auto",
            "enableThinking", false,
            "messages", List.of(Map.of("role", "user", "content", "请用 Python 写一个 LRU 缓存"))
        );

        Request req = new Request.Builder()
            .url(BASE_URL + "/api/llm/chat/stream")
            .header("Authorization", "Bearer " + API_KEY)
            .header("Accept", "text/event-stream")
            .post(RequestBody.create(
                mapper.writeValueAsBytes(body),
                MediaType.get("application/json")))
            .build();

        CountDownLatch latch = new CountDownLatch(1);

        EventSources.createFactory(client).newEventSource(req, new EventSourceListener() {
            @Override public void onEvent(EventSource es, String id, String type, String data) {
                try {
                    JsonNode node = mapper.readTree(data);
                    if ("delta".equals(type)) {
                        System.out.print(node.path("delta").asText());
                    } else if ("done".equals(type)) {
                        System.out.printf("%n[完成] tokens=%d%n", node.path("total_tokens").asInt());
                        latch.countDown();
                    }
                } catch (Exception e) { e.printStackTrace(); }
            }
            @Override public void onFailure(EventSource es, Throwable t, Response r) {
                t.printStackTrace();
                latch.countDown();
            }
        });

        latch.await();
    }
}

3) 图像生成

// readTimeout 调至 180 秒(图像生成需 20~60 秒)
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(180, TimeUnit.SECONDS)
    .build();

Map<String, Object> body = Map.of(
    "model", "doubao-seedream-5-0-pro-260628",
    "messages", List.of(Map.of("role", "user", "content", "一只在滑雪的柴犬")),
    "imageParams", Map.of("size", "1024x1024", "quality", "low", "n", 1)
);

// 返回 content 为 Markdown 图片链接
JsonNode json = mapper.readTree(resp.body().byteStream());
String markdown = json.path("data").path("content").asText();
String imageUrl = markdown.substring(markdown.indexOf("(") + 1, markdown.lastIndexOf(")"));
System.out.println("图片地址: " + imageUrl);

4) 视频生成(两步:提交 + 轮询)

OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build();
ObjectMapper mapper = new ObjectMapper();
MediaType JSON = MediaType.parse("application/json");

// ① 提交任务
Map<String, Object> body = Map.of(
    "model", "wan2.5-t2v-preview",
    "messages", List.of(Map.of("role", "user", "content", "一只橘猫在窗台上晒太阳")),
    "videoParams", Map.of("resolution", "480P", "ratio", "16:9", "duration", 5)
);
Request submit = new Request.Builder()
    .url(BASE_URL + "/api/llm/chat")
    .addHeader("Authorization", "Bearer " + API_KEY)
    .post(RequestBody.create(mapper.writeValueAsString(body), JSON))
    .build();

String requestId;
try (Response resp = client.newCall(submit).execute()) {
    JsonNode data = mapper.readTree(resp.body().string()).path("data");
    requestId = data.path("request_id").asText();
    System.out.println("任务已提交: " + requestId);
}

// ② 轮询结果
for (int i = 1; i <= 40; i++) {
    Request query = new Request.Builder()
        .url(BASE_URL + "/api/llm/chat/video/result")
        .addHeader("Authorization", "Bearer " + API_KEY)
        .post(RequestBody.create("{\"requestId\":\"" + requestId + "\"}", JSON))
        .build();

    JsonNode data;
    try (Response resp = client.newCall(query).execute()) {
        data = mapper.readTree(resp.body().string()).path("data");
    }
    String status = data.path("status").asText();
    System.out.println("第 " + i + " 次轮询,状态: " + status);

    if ("SUCCEEDED".equals(status)) {
        System.out.println("视频地址: " + data.path("video_url").asText());
        System.out.println("扣费: " + data.path("credits").asDouble() + " 算力点");
        break;
    }
    if ("FAILED".equals(status)) break;
    TimeUnit.SECONDS.sleep(15);
}