前提条件
登录模型推理服务控制台。
第一步:获取App Key和模型ID
方式一
快速获取方式
在左侧菜单栏进入“概览”,点击“API接入”
在API快捷接入页面:
选择服务组:从下拉菜单中选择第一步创建的服务组。如果尚未创建,可点击“确认创建并选择”快速创建默认服务组
选择模型:从模型下拉菜单中选择需要接入的模型
选择完成后,页面下方将自动展示该模型支持的所有编程语言的示例代码
方式二
在左侧菜单栏进入“服务接入”,点击“+创建服务组”,填写服务组名称、服务组描述、生效时间、配置服务等信息。
创建服务组后,从服务组上面获取APP KEY。
说明
请妥善保管App Key,避免公开共享,以防安全风险和资金损失。强烈建议您不要将其直接写入到调用模型的代码中。
通过模型广场选择模型并在详情页内获取模型ID。
说明
每个模型配有免费token额度用于体验,免费额度用完或到期后请前往在线推理页面开通token付费服务或将模型部署为我的服务(按卡时或包周期付费)。
第二步:获取调用模型服务的示例代码并发起调用
支持挑选Python、Java、Golang、PHP、Nodejs、curl中任一调用模型服务。
根据选择的语言和框架,可能需要按照必要的依赖库,具体可见以下示例代码的说明:
Python
说明
推荐安装Python3.x版, openai库可用如下命令安装:
pip3 install openai -i https://mirrors.aliyun.com/pypi/simple/--trusted-host mirrors.aliyun.com
文本生成
import openai
from openai import OpenAI
# 需要补充一下属性
baseUrl = "https://wishub-x6.ctyun.cn/v1/"
# 从环境变量获取API密钥,如果没有设置,也可以直接终端执行export XIRANG_app_key="xxx"
appKey="your_app_key" # 替换为实际的App Key
model_id = "xirang_model_id" # 替换为实际的modelId
prompt="你好,3.01+103.1等于多少" #对话问题,可替换
def main():
client = OpenAI(base_url=baseUrl, api_key=appKey)
messages = [
{"role": "user", "content": prompt}
]
try:
res = client.chat.completions.create(
model=model_id,
messages=messages,
stream=False
)
print(res.choices[0].message.content or "", end="", flush=True)
except openai.APIStatusError as e:
print(f"APIStatusError: {e.status_code}, {e.message}, {e.body}")
except openai.APIError as e:
print(f"APIError: {e.body}")
except Exception as e:
print(f"Exception: {e}")
if __name__ == "__main__":
main()
图像理解
import requests
url = "https://wishub-x6.ctyun.cn/v1/chat/completions"
headers = {
"Authorization": "Bearer your_app_key", # 替换为您的实际app_key
"Content-Type": "application/json"
}
payload = {
"model": "xirang_model_id", # 替换为实际的modelId
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "描述下这张图"
},
{
"type": "image_url",
"image_url": {
"url": "https://hangzhou7.zos.ctyun.cn/keywords-txt/20250708181010/184-200x200.jpg" # 需要替换图片路径
}
}
]
}
],
"stream_options": {
"include_usage": True
},
"parallel_tool_calls": True,
"stream": False
}
try:
response = requests.post(
url,
headers=headers,
json=payload # 自动序列化为JSON并设置Content-Type
)
# 检查响应状态
response.raise_for_status()
print("请求成功!")
print("响应JSON内容:")
print(response.json())
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
if hasattr(e, 'response') and e.response is not None:
print(f"错误状态码: {e.response.status_code}")
print(f"错误响应内容: {e.response.text}")
Image文本生图
import requests
import base64
import os
def generate_image_simple(prompt):
"""极简图像生成函数"""
"""
your_app_key和xirang_model_id需要替换为实际的值
"""
url = "https://wishub-x6.ctyun.cn/v1/images/generations"
headers = {
"Authorization": "Bearer your_app_key",
"Content-Type": "application/json"
}
data = {
"model": "xirang_model_id",
"prompt": prompt,
"n": 1,
"size": "1024x1024"
}
try:
# 跳过SSL验证并发送请求
response = requests.post(url, headers=headers, json=data, timeout=10)
image_data = response.json()["data"][0]["b64_json"]
# 保存图像
filename = f"{prompt[:10]}.png"
with open(filename, "wb") as f:
f.write(base64.b64decode(image_data))
print(f"图片已保存为: {filename}")
return filename
except Exception as e:
print(f"错误: {str(e)}")
return None
# 使用示例
if __name__ == "__main__":
generate_image_simple("星空下的鲸鱼") //可替换别的文本
embedding文本向量化
import json
import requests
URL = "https://wishub-x6.ctyun.cn/v1/embeddings"
headers = {
"Authorization": "Bearer your_app_key", # 替换为您的实际app_key
"Content-Type": "application/json"
}
data = {
"model": "xirang_model_id", # 替换为实际的模型ID
"input" : "A cute baby sea otter" # 替换文本描述
}
try:
response = requests.post(URL, headers=headers, json=data)
if response.status_code != 200:
print(response.json())
else:
embedding = response.json()["data"][0]["embedding"]
print(f"response embedding is {embedding}")
except Exception as e:
print(f"Exception: {e}")
rerank重排序
import requests
"""
your_app_key和xirang_model_id需要替换为实际的值
"""
API_URL = "https://wishub-x6.ctyun.cn/v1/rerank"
API_KEY = "your_app_key"
MODEL_ID = "xirang_model_id"
def call_rerank(query, documents, top_n=3):
"""
调用天翼云 Rerank API
- query: 查询文本
- documents: 待排序文档列表
- top_n: 返回最相关的文档数量
"""
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
data = {
"query": query,
"documents": documents,
"model": MODEL_ID,
"top_n": top_n
}
try:
response = requests.post(API_URL, headers=headers, json=data, timeout=10)
response.raise_for_status() # 检查HTTP错误
results = response.json()
# 打印格式化结果
print(f"\n查询: '{query}'")
print(f"返回的前 {top_n} 个最相关文档:")
for idx, item in enumerate(results["results"]):
doc = documents[item["index"]]
score = item["relevance_score"]
print(f"{idx+1}. [得分: {score:.4f}] {doc}")
return results
except Exception as e:
print(f"请求失败: {str(e)}")
return None
# 示例用法
if __name__ == "__main__":
# 示例数据
query = "Python教程"
documents = [
"Python基础语法",
"Python高级特性",
"Java编程入门",
"Python数据分析实战"
]
# 调用Rerank API
call_rerank(query, documents, top_n=2)
Java
适用于Spring AI框架调用Open API
支持对文本生成、图像理解、文本生成、enbedding文本向量化以及rerank重排序API的调用
环境变量配置
spring:
ai:
openai:
api-key: your_app_key #替换成👆自己的API KEY
base-url: https://wishub-x6.ctyun.cn
chat:
options:
model: xirang_model_id #替换成👆自己要用的模型
embedding:
options:
model: xirang_model_id #替换成👆自己要用的模型
image:
options:
model: xirang_model_id #替换成👆自己要用的模型
rerank:
option:
model: xirang_model_id #替换成👆自己要用的模型
server:
port: 9090
servlet:
encoding:
charset: UTF-8
force: true
enabled: true
项目依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>aitest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>aitest</name>
<description>aitest</description>
<properties>
<java.version>17</java.version>
<spring-ai.version>0.8.1</spring-ai.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
配置类
package com.demo.aitest;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
@Configuration
public class OpenAIConfig {
@Value("${spring.ai.openai.api-key}")
private String apiKey;
@Value("${spring.ai.openai.base-url}")
private String baseUrl;
@Value("${spring.ai.openai.chat.options.model}")
private String chatModel;
@Value("${spring.ai.openai.chat.options.model}")
private String embeddingModel;
@Autowired
private OpenAIProperties openAIProperties;
@Bean
public OpenAiApi openAiApi(){
return new OpenAiApi(baseUrl, apiKey);
}
@Bean
public OpenAiChatClient openAiChatClient(OpenAiApi openAiApi) {
OpenAiChatOptions options = new OpenAiChatOptions();
options.setModel(chatModel);
options.setFrequencyPenalty(0.0f);
options.setMaxTokens(2000);
return new OpenAiChatClient(openAiApi, options);
}
public OpenAiEmbeddingClient openAiEmbeddingClient(OpenAiApi openAiApi, RetryTemplate retryTemplate){
OpenAiEmbeddingOptions options = OpenAiEmbeddingOptions.builder()
.withModel(embeddingModel)
.build();
return new OpenAiEmbeddingClient(openAiApi, MetadataMode.INFERENCE, options, retryTemplate);
}
@Bean
public RetryTemplate retryTemplate(){
return new RetryTemplate();
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
OpenAPI Http客户端
package com.demo.aitest.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
@Service
@Slf4j
public class HttpClientService {
@Value("${spring.ai.openai.api-key}")
private String apiKey;
@Value("${spring.ai.openai.base-url}")
private String baseUrl;
@Autowired
private RestTemplate restTemplate;
@Autowired
private ObjectMapper mapper;
public ResponseEntity<Object> callOpenAPI(String url, Object requestBody) throws JsonProcessingException {
String fullUrl = baseUrl + url;
log.info("Calling Open API: {}", fullUrl);
if(log.isDebugEnabled()){
log.debug("Request Body: {}", mapper.writeValueAsString(requestBody));
}
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", "Bearer " + apiKey);
ResponseEntity<String> response = restTemplate.exchange(fullUrl, HttpMethod.POST, new HttpEntity<>(requestBody, headers), String.class);
return ResponseEntity.ok(response.getBody());
} catch (Exception e) {
log.error("Open API call failed: {} | Error: {}", fullUrl, e.getMessage());
return ResponseEntity.internalServerError().body(e.getMessage());
}
}
}
ChatController
已封装对文本生成API的支持
package com.demo.aitest.controller;
import com.demo.aitest.controller.request.MultimodalRequest;
import com.demo.aitest.service.HttpClientService;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
@RestController
public class ChatController {
private static final Logger logger = LoggerFactory.getLogger(ChatController.class);
@Autowired
private OpenAiChatClient chatClient;
@GetMapping("/chat")
public String chat(@RequestParam String message) {
try {
ChatResponse response = chatClient.call(new Prompt(message));
String content = response.getResult().getOutput().getContent();
logger.info("Response received successfully");
return content;
} catch (Exception e) {
logger.error("Error processing chat request: {}", e.getMessage());
throw e;
}
}
@GetMapping(value = "/chat/stream", produces = "text/event-stream;charset=UTF-8")
public SseEmitter streamChat(@RequestParam String message) {
SseEmitter emitter = new SseEmitter(-1L); // 无限超时
try {
// Create prompt with UserMessage
Prompt prompt = new Prompt(new UserMessage(message));
// Stream the response
chatClient.stream(prompt).subscribe(
chunk -> {
try {
if (chunk != null && chunk.getResult() != null) {
String content = chunk.getResult().getOutput().getContent();
if (content != null && !content.isEmpty()) {
emitter.send(content);
}
}
} catch (IOException e) {
logger.error("Error sending chunk: {}", e.getMessage());
emitter.completeWithError(e);
}
},
error -> {
logger.error("Error in stream: {}", error.getMessage());
emitter.completeWithError(error);
},
() -> {
logger.info("Stream completed successfully");
emitter.complete();
}
);
} catch (Exception e) {
logger.error("Error processing streaming chat request: {}", e.getMessage());
emitter.completeWithError(e);
}
return emitter;
}
}
图像理解请求
package com.demo.aitest.controller.request;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class MultimodalRequest {
private String model;
private List<Message> messages;
@JsonProperty(value = "stream_options")
private StreamOptions streamOptions;
@JsonProperty(value = "parallel_tool_calls")
private boolean parallelToolCalls;
private boolean stream;
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public static class Message {
private String role;
@JsonProperty(value = "content")
private List<Content> content;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public static class Content {
@JsonProperty(value = "type")
private String type;
@JsonProperty(value = "text")
private String text;
@JsonProperty(value = "image_url")
private ImageUrl imageUrl;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public static class ImageUrl {
private String url;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public static class StreamOptions {
@JsonProperty(value = "include_usage")
private boolean includeUsage;
}
}
文本生图请求
package com.demo.aitest.controller.request;
public class ImageGenerationRequest {
private String model;
private String prompt;
private Integer n;
private String size;
}
ImageController
package com.demo.aitest.controller;
import com.demo.aitest.controller.request.ImageGenerationRequest;
import com.demo.aitest.controller.request.MultimodalRequest;
import com.demo.aitest.service.HttpClientService;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ImageController {
@Value("${spring.ai.openai.chat.options.model}")
private String chatModel;
@Value("${spring.ai.openai.image.options.model}")
private String imageModel;
@Autowired
private HttpClientService httpClientService;
@PostMapping("/image/understanding")
public ResponseEntity<?> multiModalChat(@RequestBody MultimodalRequest multiModalRequest) throws JsonProcessingException {
if(StringUtils.isBlank(multiModalRequest.getModel())){
multiModalRequest.setModel(chatModel);
}
return httpClientService.callOpenAPI("/v1/chat/completions", multiModalRequest);
}
@PostMapping("/image/generation")
public ResponseEntity<?> multiModalChat(@RequestBody ImageGenerationRequest imageGenerationRequest) throws JsonProcessingException {
if(StringUtils.isBlank(imageGenerationRequest.getModel())){
imageGenerationRequest.setModel(imageModel);
}
return httpClientService.callOpenAPI("/v1/images/generations", imageGenerationRequest);
}
}
Embedding Controller
package com.demo.aitest.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.embedding.EmbeddingResponse;
import org.springframework.ai.openai.OpenAiEmbeddingClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
@RestController
public class EmbeddingController {
private static final Logger logger = LoggerFactory.getLogger(EmbeddingController.class);
@Autowired
private OpenAiEmbeddingClient openAiEmbeddingClient;
@PostMapping("/embedding")
public ResponseEntity<?> embedding(String text) {
try {
EmbeddingResponse embeddingResponse = openAiEmbeddingClient.embedForResponse(Collections.singletonList(text));
logger.info("Response received successfully");
return ResponseEntity.ok(embeddingResponse);
} catch (Exception e) {
logger.error("Error processing chat request: {}", e.getMessage());
throw e;
}
}
}
Rerank请求
package com.demo.aitest.controller.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class RerankRequest {
private String query;
private String[] documents;
private String model;
@JsonProperty(value = "top_n")
private Integer topn;
}
Rerank Controller
package com.demo.aitest.controller;
import com.demo.aitest.controller.request.RerankRequest;
import com.demo.aitest.service.HttpClientService;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class RerankController {
@Value("${spring.ai.openai.rerank.options.model}")
private String rerankModel;
private final HttpClientService httpClientService;
@Autowired
public RerankController(HttpClientService httpClientService) {
this.httpClientService = httpClientService;
}
@PostMapping("/rerank")
public ResponseEntity<?> rerank(@RequestBody RerankRequest rerankRequest) throws JsonProcessingException {
if(StringUtils.isBlank(rerankRequest.getModel())){
rerankRequest.setModel(rerankModel);
}
return httpClientService.callOpenAPI("/v1/rerank", rerankRequest);
}
}
访问地址:
●文本生成:GET http://localhost:9090/chat?message=Hello
●文本生图:http://localhost:9090/image/generation
{"model": "xirang_model_id", "prompt": "A cute baby sea otter", "n": 1, "size": "512x512"}
图像理解:POST http://localhost:9090/image/understanding
{"model": "88003ac1ca7a4e4e8efa7caee648323b", "messages": [{"role": "user", "content": [{"type": "text", "text": "描述下这张图"}, {"type": "image_url", "image_url": {"url": "
"}}]}], "stream_options": {"include_usage": true}, "parallel_tool_calls": true, "stream": false}
embedding向量化:GET http://localhost:9090/embedding?text=A cute baby sea otter
rerank重排序:POST http://localhost:9090/rerank
{"query": "Python教程", "documents": ["Python基础语法", "Python高级特性", "Java编程入门"], "model": "xirang_model_id", "top_n": 2}
Golang
注意
golang版本要求1.18以上。
go.mod引用相关类库 go get 。
文本生成
package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai" // 统一使用这个库
)
func main() {
baseUrl := "https://wishub-x6.ctyun.cn/v1" // api前缀地址
appkey := "your_app_key" // 替换成自己的App Key
modelId := "xirang_model_id" // 替换成自己要用的模型
prompt := "你是谁" // 对话问题
// 创建自定义配置
config := openai.DefaultConfig(appkey)
config.BaseURL = baseUrl
// 使用配置创建客户端
client := openai.NewClientWithConfig(config)
// 构建请求参数
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: modelId,
Messages: []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Content: prompt,
},
},
},
)
if err != nil {
panic(err)
}
// 打印模型输出
fmt.Println(resp.Choices[0].Message.Content)
}
图像理解
package main
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
url := "https://wishub-x6.ctyun.cn/v1/chat/completions"
apiKey := "your_app_key" // 替换为自己的App key
modelId := "xirang_model_id" // 替换为实际的model Id
// 创建不验证证书的 HTTP 客户端
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
// 构建请求负载
payload := map[string]interface{}{
"model": modelId,
"messages": []map[string]interface{}{
{
"role": "user",
"content": []map[string]interface{}{
{
"type": "text",
"text": "描述下这张图",
},
{
"type": "image_url",
"image_url": map[string]interface{}{
"url": "https://hangzhou7.zos.ctyun.cn/keywords-txt/20250708181010/184-200x200.jpg",
},
},
},
},
},
"stream_options": map[string]interface{}{
"include_usage": true,
},
"parallel_tool_calls": true,
"stream": false,
}
// 将负载转换为 JSON
jsonPayload, err := json.Marshal(payload)
if err != nil {
fmt.Printf("JSON 编码错误: %v\n", err)
return
}
// 创建请求
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonPayload))
if err != nil {
fmt.Printf("创建请求错误: %v\n", err)
return
}
// 设置请求头
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
// 发送请求
resp, err := client.Do(req)
if err != nil {
fmt.Printf("请求发送错误: %v\n", err)
return
}
defer resp.Body.Close()
// 读取响应
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("读取响应错误: %v\n", err)
return
}
// 检查状态码
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
fmt.Println("请求成功!")
fmt.Println("响应JSON内容:")
// 美化输出 JSON
var prettyJSON bytes.Buffer
err = json.Indent(&prettyJSON, body, "", " ")
if err != nil {
fmt.Println(string(body))
} else {
fmt.Println(prettyJSON.String())
}
} else {
fmt.Printf("请求失败,状态码: %d\n", resp.StatusCode)
fmt.Printf("错误响应内容: %s\n", string(body))
}
}
Image文本生图
package main
import (
"crypto/tls"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
type ImageResponse struct {
Created int `json:"created"`
Data []struct {
URL string `json:"url"`
B64JSON string `json:"b64_json"`
} `json:"data"`
}
func generateImage(prompt, apiKey, modelId, outputDir, size string) (string, error) {
// 创建输出目录
if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
return "", fmt.Errorf("创建目录失败: %v", err)
}
// API配置
url := "https://wishub-x6.ctyun.cn/v1/images/generations"
// 构建请求体
requestBody := map[string]interface{}{
"model": modelId,
"prompt": prompt,
"n": 1,
"size": size,
}
jsonBody, err := json.Marshal(requestBody)
if err != nil {
return "", fmt.Errorf("JSON编码失败: %v", err)
}
// 创建请求
req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonBody)))
if err != nil {
return "", fmt.Errorf("创建请求失败: %v", err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
// 配置HTTP客户端
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{},
},
}
// 发送请求
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("请求失败: %v", err)
}
defer resp.Body.Close()
// 检查响应状态
if resp.StatusCode != http.StatusOK {
body, _ := ioutil.ReadAll(resp.Body)
return "", fmt.Errorf("API错误: %s\n响应: %s", resp.Status, string(body))
}
// 解析响应
var imgResp ImageResponse
if err := json.NewDecoder(resp.Body).Decode(&imgResp); err != nil {
return "", fmt.Errorf("解析响应失败: %v", err)
}
if len(imgResp.Data) == 0 || imgResp.Data[0].B64JSON == "" {
return "", fmt.Errorf("未找到图像数据")
}
// 解码Base64图像
imgData, err := base64.StdEncoding.DecodeString(imgResp.Data[0].B64JSON)
if err != nil {
return "", fmt.Errorf("Base64解码失败: %v", err)
}
// 创建文件名
safePrompt := strings.Map(func(r rune) rune {
if r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' {
return r
}
return '_'
}, prompt)
if len(safePrompt) > 50 {
safePrompt = safePrompt[:50]
}
filename := fmt.Sprintf("%s_%d.png", safePrompt, time.Now().Unix())
filepath := filepath.Join(outputDir, filename)
// 保存图像
if err := ioutil.WriteFile(filepath, imgData, 0644); err != nil {
return "", fmt.Errorf("保存文件失败: %v", err)
}
return filepath, nil
}
func main() {
apiKey := "your_app_key" // 替换为实际的app key
modelId := "xirang_model_id" // 替换为实际的modelId
outputDir := "images"
size := "1024x1024"
prompt := "一只戴帽子的可爱小海獭"
filepath, err := generateImage(prompt, apiKey, modelId, outputDir, size)
if err != nil {
log.Fatalf("错误: %v", err)
}
log.Printf("图像已保存至: %s", filepath)
}
embedding文本向量化
package main
import (
"context"
"fmt"
openai "github.com/sashabaranov/go-openai"
)
func main() {
baseUrl := "https://wishub-x6.ctyun.cn/v1" // API前缀地址
appkey := "your_app_key" // 替换成自己的App Key
modelId := "xirang_model_id" // 替换成实际的模型ID
text := "测试文本" // 需要生成嵌入向量的文本
// 创建自定义配置
config := openai.DefaultConfig(appkey)
config.BaseURL = baseUrl
// 创建客户端
client := openai.NewClientWithConfig(config)
// 构建Embedding请求
resp, err := client.CreateEmbeddings(
context.Background(),
openai.EmbeddingRequest{
Model: openai.EmbeddingModel(modelId),
Input: []string{text}, // 注意Input是字符串切片
},
)
if err != nil {
panic(err)
}
// 打印结果
fmt.Printf("嵌入向量维度: %d\n", len(resp.Data[0].Embedding))
fmt.Printf("前5个向量值: %v\n", resp.Data[0].Embedding[:5])
fmt.Printf("使用令牌数: %d\n", resp.Usage.TotalTokens)
}
rerank 重排序
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
apiURL := "https://wishub-x6.ctyun.cn/v1/rerank"
apiKey := "your_app_key" // 替换成自己的App Key
modelID := "xirang_model_id" //替换成实际的modelId
// 请求数据
requestData := map[string]interface{}{
"query": "Python教程",
"documents": []string{"Python基础语法", "Python高级特性", "Java编程入门"},
"model": modelID,
"top_n": 2,
}
// 编码为 JSON
jsonData, _ := json.Marshal(requestData)
// 创建请求
req, _ := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
// 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("请求失败: %v", err)
return
}
defer resp.Body.Close()
// 读取响应
body, _ := ioutil.ReadAll(resp.Body)
// 解析结果
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
fmt.Printf("解析结果失败: %v", err)
return
}
// 打印结果
fmt.Printf("查询: '%s'\n", requestData["query"])
fmt.Println("返回结果:")
if results, ok := result["results"].([]interface{}); ok {
for i, item := range results {
doc := item.(map[string]interface{})
fmt.Printf("%d. [得分: %.4f] %s\n",
i+1,
doc["relevance_score"].(float64),
requestData["documents"].([]string)[int(doc["index"].(float64))],
)
}
} else {
fmt.Println("无效的响应格式")
}
}
PHP
注意
php版本要求8.3.13以上;
安装composer组件;
运行以下命令:
composer require openai-php/client
composer dump-autoload
文本生成
<?php
require __DIR__ . '/vendor/autoload.php';
use OpenAI\Client;
$baseUrl="https://wishub-x6.ctyun.cn/v1"; //api前缀地址
//从环境变量获取API密钥,如果没有设置,也可以直接终端执行export XIRANG_app_key="xxx"
$appkey = "your_app_key";
$modelId="xirang_model_id"; //替换成自己要用的模型
$prompt="你好,介绍一下自己"; //#对话问题
$client = OpenAI::factory()
->withApiKey($appkey)
->withBaseUri($baseUrl)
->make();
$response = $client->chat()->create([
'model' => $modelId,
'messages' => [
['role' => 'user', 'content' => $prompt],
],
]);
foreach ($response->choices as $result) {
echo $result->message->content;
}
?>
图像理解
<?php
$url = 'https://wishub-x6.ctyun.cn/v1/chat/completions';
$apiKey = 'your_app_key';
$modelId = 'xirang_model_id';
// 请求负载
$payload = [
'model' => $modelId,
'messages' => [
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => '描述下这张图'
],
[
'type' => 'image_url',
'image_url' => [
'url' => 'https://hangzhou7.zos.ctyun.cn/keywords-txt/20250708181010/184-200x200.jpg'
]
]
]
]
],
'stream_options' => [
'include_usage' => true
],
'parallel_tool_calls' => true,
'stream' => false
];
// 初始化 cURL
$ch = curl_init();
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
// 禁用 SSL 验证 (仅用于开发环境)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// 检查错误
if (curl_errno($ch)) {
echo '请求失败: ' . curl_error($ch);
} else {
if ($httpCode >= 200 && $httpCode < 300) {
echo "请求成功!\n";
echo "响应JSON内容:\n";
// 美化输出 JSON
$json = json_decode($response);
if ($json === null) {
echo $response;
} else {
echo json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
} else {
echo "请求失败,状态码: $httpCode\n";
echo "错误响应内容: $response\n";
}
}
// 关闭 cURL 资源
curl_close($ch);
?>
Image文本生图
<?php
function generateImage($prompt, $apiKey, $outputDir = 'images', $size = '1024x1024') {
// 创建输出目录
if (!is_dir($outputDir) && !mkdir($outputDir, 0777, true)) {
throw new Exception("创建目录失败: $outputDir");
}
// API配置
$url = 'https://wishub-x6.ctyun.cn/v1/images/generations';
// 构建请求体
$data = [
'model' => 'xirang_model_id', // 替换为实际的modelId
'prompt' => $prompt,
'n' => 1,
'size' => $size
];
// 使用 cURL 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
// 关闭 SSL 验证 (仅用于测试环境)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
// 检查 cURL 错误
if (curl_errno($ch)) {
$errorMsg = curl_error($ch);
curl_close($ch);
throw new Exception("cURL请求失败: " . $errorMsg);
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 检查HTTP状态码
if ($httpCode >= 400) {
throw new Exception("API返回错误状态码: $httpCode");
}
$responseData = json_decode($response, true);
// 检查API错误
if (isset($responseData['error'])) {
throw new Exception('API错误: ' . $responseData['error']['message']);
}
if (empty($responseData['data'][0]['b64_json'])) {
throw new Exception('未找到图像数据');
}
// 获取Base64图像数据
$imageData = base64_decode($responseData['data'][0]['b64_json']);
// 创建安全文件名
$safePrompt = preg_replace('/[^a-zA-Z0-9]/', '_', substr($prompt, 0, 50));
$filename = $safePrompt . '_' . time() . '.png';
$filepath = $outputDir . '/' . $filename;
// 保存图像
if (!file_put_contents($filepath, $imageData)) {
throw new Exception("保存文件失败: $filepath");
}
return $filepath;
}
// 使用示例
try {
$apiKey = 'your_app_key'; // 替换为实际的app key
$imagePath = generateImage('一只戴帽子的可爱小海獭', $apiKey);
echo "✅ 图像已保存至: $imagePath\n";
} catch (Exception $e) {
echo "❌ 错误: " . $e->getMessage() . "\n";
exit(1);
}
embedding文本向量化
<?php
require __DIR__ . '/vendor/autoload.php';
use OpenAI\Client;
$baseUrl = "https://wishub-x6.ctyun.cn/v1"; // API前缀地址
$appkey = "your_app_key"; // 替换成自己的App Key
$modelId = "xirang_model_id"; // 替换成Embedding模型ID
$text = "这是一段测试文本"; // 需要生成嵌入向量的文本
$client = OpenAI::factory()
->withApiKey($appkey)
->withBaseUri($baseUrl)
->make();
// 调用Embedding API
$response = $client->embeddings()->create([
'model' => $modelId,
'input' => $text, // 支持字符串或字符串数组
]);
// 处理结果
$embedding = $response->embeddings[0]->embedding; // 获取第一个文本的嵌入向量
$tokenUsage = $response->usage->totalTokens; // 获取使用的令牌数
// 打印结果
echo "嵌入向量维度: " . count($embedding) . "\n";
echo "前5个向量值: \n";
print_r(array_slice($embedding, 0, 5)); // 显示前5个值
echo "\n使用令牌数: " . $tokenUsage . "\n";
?>
rerank 重排序
<?php
$apiUrl = "https://wishub-x6.ctyun.cn/v1/rerank";
$apiKey = "your_app_key"; //替换成自己的App Key
$modelId = "xirang_model_id"; // 替换成实际的model Id
// 请求数据
$data = [
'query' => 'Python教程',
'documents' => ['Python基础语法', 'Python高级特性', 'Java编程入门'],
'model' => $modelId,
'top_n' => 2
];
// 准备请求
$options = [
'http' => [
'method' => 'POST',
'header' => "Authorization: Bearer $apiKey\r\n" .
"Content-Type: application/json\r\n",
'content' => json_encode($data),
'timeout' => 10 // 超时时间
]
];
// 发送请求
$context = stream_context_create($options);
$response = file_get_contents($apiUrl, false, $context);
if ($response === false) {
die("请求失败");
}
// 解析结果
$result = json_decode($response, true);
// 打印结果
echo "查询: '{$data['query']}'\n";
echo "返回结果:\n";
if (isset($result['results'])) {
foreach ($result['results'] as $i => $item) {
$docIndex = $item['index'];
$docText = $data['documents'][$docIndex];
printf("%d. [得分: %.4f] %s\n",
$i + 1,
$item['relevance_score'],
$docText
);
}
} else {
echo "无效的响应格式\n";
print_r($result);
}
?>
Nodejs
注意
测试用的node版本>=v17.9.1,npm版本>=8.11.0;
运行前需执行一下命令:
npm init -y
npm install openai在生成的package.json文件中添加"type":"module";
替换baseUrl,appkey,modelId,prompt等字段的值。
文本生成
import OpenAI from 'openai';
const baseUrl="https://wishub-x6.ctyun.cn/v1" //api前缀地址
//从环境变量获取API密钥,如果没有设置,也可以直接终端执行export XIRANG_app_key="xxx"
const appkey= "your_app_key"
const modelId="xirang_model_id" //模型id
const prompt="你好啊,给一篇100字左右的作文" //对话问题
const client = new OpenAI({
apiKey: appkey,
baseURL:baseUrl
});
async function chatCompletion() {
const completion = await client.chat.completions.create({
model: modelId,
messages: [{ role: 'user', content: prompt }],
});
console.log(completion.choices[0]?.message?.content);
}
chatCompletion();
图像理解
import https from 'https';
import axios from 'axios';
const url = 'https://wishub-x6.ctyun.cn/v1/chat/completions';
const apiKey = 'your_app_key';
// 创建不验证证书的 HTTPS Agent
const agent = new https.Agent({
rejectUnauthorized: false
});
// 请求负载
const payload = {
model: 'xirang_model_id',
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: '描述下这张图'
},
{
type: 'image_url',
image_url: {
url: 'https://hangzhou7.zos.ctyun.cn/keywords-txt/20250708181010/184-200x200.jpg'
}
}
]
}
],
stream_options: {
include_usage: true
},
parallel_tool_calls: true,
stream: false
};
// 配置请求
const config = {
method: 'post',
url: url,
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
data: payload,
httpsAgent: agent // 使用自定义的 HTTPS Agent
};
// 发送请求
axios(config)
.then(response => {
console.log('请求成功!');
console.log('响应JSON内容:');
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error('请求失败:', error.message);
if (error.response) {
console.error(`错误状态码: ${error.response.status}`);
console.error('错误响应内容:', error.response.data);
}
});
Image文本生图
import https from 'https';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// 获取当前文件的目录路径(替代 __dirname)
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function generateImage(prompt, apiKey, outputDir = 'images', size = '1024x1024') {
// 创建输出目录
const fullOutputDir = path.resolve(__dirname, outputDir);
if (!fs.existsSync(fullOutputDir)) {
fs.mkdirSync(fullOutputDir, { recursive: true });
}
// API配置
const url = 'https://wishub-x6.ctyun.cn/v1/images/generations';
// 构建请求体
const postData = JSON.stringify({
model: 'xirang_model_id', // 替换为实际的model Id
prompt: prompt,
n: 1,
size: size
});
// 请求选项
const options = {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
}
};
// 发送请求
const response = await new Promise((resolve, reject) => {
const req = https.request(url, options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode >= 400) {
reject(`API错误: ${res.statusCode} - ${data}`);
return;
}
try {
resolve(JSON.parse(data));
} catch (e) {
reject(`JSON解析失败: ${e.message} - 响应数据: ${data}`);
}
});
});
req.on('error', (error) => {
reject(`请求失败: ${error.message}`);
});
req.write(postData);
req.end();
});
// 检查响应
if (!response.data || !response.data[0] || !response.data[0].b64_json) {
throw new Error('未找到图像数据');
}
// 解码Base64图像
const imageData = Buffer.from(response.data[0].b64_json, 'base64');
// 创建安全文件名
const safePrompt = prompt.substring(0, 50).replace(/[^a-zA-Z0-9]/g, '_');
const filename = `${safePrompt}_${Date.now()}.png`;
const filepath = path.join(fullOutputDir, filename);
// 保存图像
fs.writeFileSync(filepath, imageData);
return filepath;
}
// 使用示例
(async () => {
try {
const apiKey = 'your_app_key'; // 替换为实际的model Id
const imagePath = await generateImage('一只戴帽子的可爱小海獭', apiKey);
console.log(`✅ 图像已保存至: ${imagePath}`);
} catch (error) {
console.error(`❌ 错误: ${error.message}`);
process.exit(1);
}
})();
embedding文本向量化
import OpenAI from 'openai';
const baseUrl = "https://wishub-x6.ctyun.cn/v1"; // API前缀地址
const appkey = "your_app_token"; // 替换为你的实际API密钥
const modelId = "xirang_model_id"; // 替换为支持Embedding的模型ID
const text = "这是一段测试文本"; // 需要生成嵌入向量的文本
const client = new OpenAI({
apiKey: appkey,
baseURL: baseUrl
});
async function createEmbedding() {
try {
// 调用Embedding API
const embedding = await client.embeddings.create({
model: modelId,
input: text, // 支持字符串或字符串数组
});
// 处理结果
const vector = embedding.data[0].embedding; // 获取嵌入向量
const tokenUsage = embedding.usage.total_tokens; // 获取令牌使用量
// 打印结果
console.log(`嵌入向量维度: ${vector.length}`);
console.log(`前5个向量值: [${vector.slice(0, 5).join(', ')}]`);
console.log(`使用令牌数: ${tokenUsage}`);
// 完整向量可这样访问(注意向量可能很长):
// console.log("完整嵌入向量:", vector);
} catch (error) {
console.error("API调用失败:", error);
}
}
createEmbedding();
rerank文本向量化
import https from 'https';
import axios from 'axios';
const apiUrl = "https://wishub-x6.ctyun.cn/v1/rerank";
const apiKey = "your_app_key";
const modelId = "xirang_model_id";
// 请求数据
const requestData = {
query: "Python教程",
documents: ["Python基础语法", "Python高级特性", "Java编程入门"],
model: modelId,
top_n: 2
};
// 发送请求
axios.post(apiUrl, requestData, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
timeout: 10000 // 10秒超时
})
.then(response => {
// 处理结果
const results = response.data.results;
console.log(`查询: '${requestData.query}'`);
console.log("返回结果:");
results.forEach((item, i) => {
const docIndex = item.index;
const docText = requestData.documents[docIndex];
console.log(`${i+1}. [得分: ${item.relevance_score.toFixed(4)}] ${docText}`);
});
})
.catch(error => {
if (error.response) {
console.error(`请求失败: ${error.response.status}`, error.response.data);
} else {
console.error("请求失败:", error.message);
}
});
cURL
注意
以下curl脚本在Linux(MAC)和windows环境均可运行
参照第一步替换公共字段appkey和modelId的值
其他字段的替换方式如下:
文本生成的示例代码可替换content字段的值
图像理解的示例代码可替换image_url中的图片地址,产品可通过运营后台-banner位上传样例图片
文本生图的示例代码替换prompt,n,size为文本描述,图像数和图片大小
embedding的示例代码可替换input为字符串或数组类型
rerank的示例代码可替换query和documents为检索的关键词和文本数组
文本生成
curl --location "https://wishub-x6.ctyun.cn/v1/chat/completions" --header "Content-Type: application/json; charset=utf-8" --header "Authorization: Bearer your_app_key" --data "{\"messages\": [{\"role\": \"user\", \"content\": \"你好\"}], \"model\": \"xirang_model_id\"}"
图像理解
curl --location "https://wishub-x6.ctyun.cn/v1/chat/completions" \
--header "Authorization: Bearer your_app_key" \
--header "Content-Type: application/json" \
--data "{\"model\": \"xirang_model_id\", \"messages\": [{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \"描述下这张图\"}, {\"type\": \"image_url\", \"image_url\": {\"url\": \"https://hangzhou7.zos.ctyun.cn/keywords-txt/20250708181010/184-200x200.jpg\"}}]}], \"stream_options\": {\"include_usage\": true}, \"parallel_tool_calls\": true, \"stream\": false}"
Image文本生图
curl "https://wishub-x6.ctyun.cn/v1/images/generations" --header "Content-Type: application/json; charset=utf-8" --header "Authorization: Bearer your_app_key" --header "Accept: */*" --header "Accept-Encoding: gzip, deflate, br" --data "{\"model\": \"xirang_model_id\", \"prompt\": \"A cute baby sea otter\", \"n\": 1, \"size\": \"512x512\"}"
embedding文本向量化
curl --location "https://wishub-x6.ctyun.cn/v1/embeddings" --header "Authorization: Bearer your_app_key" --header "User-Agent: PostmanRuntime-ApipostRuntime/1.1.0" --header "Accept-Encoding: gzip, deflate" --header "Content-Type: application/json" --data "{\"input\": [\"A cute baby sea otter\"], \"model\": \"xirang_model_id\"}"
rerank重排序
curl --location "https://wishub-x6.ctyun.cn/v1/rerank" --header "Accept: */*" --header "Accept-Encoding: gzip, deflate, br" --header "Authorization: Bearer your_app_key" --header "Content-Type: application/json" --data "{\"query\": \"Python教程\", \"documents\": [\"Python基础语法\", \"Python高级特性\", \"Java编程入门\"], \"model\": \"xirang_model_id\", \"top_n\": 2}"