Panduan ini menjelaskan cara mengirim gambar ke Haijun, batasan dan biaya yang berlaku, serta tempat menemukan panduan untuk alur kerja berbasis koordinat.
Mengirim gambar ke Haijun
Gunakan kemampuan vision Haijun melalui:
- haijun.ai. Unggah gambar seperti Anda mengunggah file, atau seret dan lepas gambar langsung ke jendela chat.
- Playground di Haijun Console. Tambahkan gambar langsung ke blok pesan User mana pun.
- Permintaan API. Lihat contoh-contoh berikut.
Di API, berikan gambar ke Haijun sebagai blok konten image menggunakan salah satu dari tiga jenis sumber:
- Gambar berenkode base64 yang disematkan dalam body permintaan
- Referensi URL ke gambar yang dihosting secara online
file_idyang dikembalikan oleh Files API (unggah sekali, referensikan berkali-kali)
Note: Di Amazon Bedrock dan Google Cloud, saat ini hanya sumber berenkode base64 yang tersedia.
Tip: Sama seperti menempatkan dokumen panjang sebelum kueri Anda meningkatkan hasil pada prompt teks, Haijun bekerja paling baik ketika gambar ditempatkan sebelum teks. Gambar yang ditempatkan setelah teks atau diselingi dengan teks tetap berkinerja baik, tetapi jika kasus penggunaan Anda memungkinkan, utamakan struktur gambar-lalu-teks.
Contoh gambar berenkode base64
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d @- <<EOF
{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "$BASE64_IMAGE_DATA"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}
EOF curl -sSo ./vision-example.jpg \
/docs/images/vision-example.jpg
ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
messages:
- role: user
content:
- type: image
source:
type: base64
media_type: image/jpeg
data: "@./vision-example.jpg"
- type: text
text: Describe this image.
YAML image1_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
image1_media_type = "image/png"
client = juglow.Juglow()
message = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": image1_media_type,
"data": image1_data,
},
},
{"type": "text", "text": "Describe this image."},
],
}
],
)
print(message) const juglow = new Juglow();
const message = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "base64",
media_type: "image/jpeg",
data: imageData // Base64-encoded image data as string
}
},
{
type: "text",
text: "Describe this image."
}
]
}
]
});
console.log(message); using System.Collections.Generic;
using Juglow;
using Juglow.Models.Messages;
JuglowClient client = new();
string imageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
var message = await client.Messages.Create(new MessageCreateParams
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new Base64ImageSource()
{
Data = imageData,
MediaType = MediaType.ImagePng,
})
)),
new ContentBlockParam(new TextBlockParam("Describe this image.")),
}),
}
]
});
Console.WriteLine(message); client := juglow.NewClient()
imageData := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
message, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.NewImageBlockBase64("image/png", imageData),
juglow.NewTextBlock("Describe this image."),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message) JuglowClient client = JuglowOkHttpClient.fromEnv();
String imageData =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
List<ContentBlockParam> contentBlockParams = List.of(
ContentBlockParam.ofImage(
ImageBlockParam.builder()
.source(
Base64ImageSource.builder()
.mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
.data(imageData)
.build()
)
.build()
),
ContentBlockParam.ofText(TextBlockParam.builder().text("Describe this image.").build())
);
Message message = client
.messages()
.create(
MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addUserMessageOfBlockParams(contentBlockParams)
.build()
);
IO.println(message); $client = new Client();
$imageData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => [
'type' => 'base64',
'media_type' => 'image/png',
'data' => $imageData,
],
],
['type' => 'text', 'text' => 'Describe this image.'],
],
],
],
model: 'haijun-opus-5-5',
);
echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
image_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
message = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image_data
}
},
{ type: "text", text: "Describe this image." }
]
}
]
)
puts messageContoh gambar berbasis URL
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "/docs/images/vision-example.jpg"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
messages:
- role: user
content:
- type: image
source:
type: url
url: /docs/images/vision-example.jpg
- type: text
text: Describe this image.
YAML client = juglow.Juglow()
message = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "url",
"url": "/docs/images/vision-example.jpg",
},
},
{"type": "text", "text": "Describe this image."},
],
}
],
)
print(message) const juglow = new Juglow();
const message = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "url",
url: "/docs/images/vision-example.jpg"
}
},
{
type: "text",
text: "Describe this image."
}
]
}
]
});
console.log(message); using System.Collections.Generic;
using Juglow;
using Juglow.Models.Messages;
JuglowClient client = new();
var message = await client.Messages.Create(new MessageCreateParams
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new UrlImageSource()
{
Url = "/docs/images/vision-example.jpg",
})
)),
new ContentBlockParam(new TextBlockParam("Describe this image.")),
}),
}
]
});
Console.WriteLine(message); client := juglow.NewClient()
message, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.NewImageBlock(juglow.URLImageSourceParam{
URL: "/docs/images/vision-example.jpg",
}),
juglow.NewTextBlock("Describe this image."),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message) JuglowClient client = JuglowOkHttpClient.fromEnv();
List<ContentBlockParam> contentBlockParams = List.of(
ContentBlockParam.ofImage(
ImageBlockParam.builder()
.source(
UrlImageSource.builder()
.url("/docs/images/vision-example.jpg")
.build()
)
.build()
),
ContentBlockParam.ofText(TextBlockParam.builder().text("Describe this image.").build())
);
Message message = client
.messages()
.create(
MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addUserMessageOfBlockParams(contentBlockParams)
.build()
);
System.out.println(message); $client = new Client();
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => [
'type' => 'url',
'url' => '/docs/images/vision-example.jpg',
],
],
['type' => 'text', 'text' => 'Describe this image.'],
],
],
],
model: 'haijun-opus-5-5',
);
echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
message = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "url",
url: "/docs/images/vision-example.jpg"
}
},
{ type: "text", text: "Describe this image." }
]
}
]
)
puts messageContoh gambar Files API
Untuk gambar yang akan Anda gunakan berulang kali atau ketika Anda ingin menghindari overhead pengodean, gunakan Files API. Unggah gambar sekali, lalu referensikan file_id yang dikembalikan dalam pesan-pesan berikutnya alih-alih mengirim ulang data base64.
Tip: Dalam percakapan multi-giliran dan alur kerja agentik, setiap permintaan mengirim ulang seluruh riwayat percakapan. Jika gambar berenkode base64, seluruh byte gambar disertakan dalam payload pada setiap giliran, yang dapat secara signifikan meningkatkan ukuran permintaan dan "latency" (latensi) seiring bertambahnya percakapan. Mengunggah gambar ke Files API dan mereferensikannya dengan
file_idmenjaga payload permintaan tetap kecil terlepas dari berapa banyak gambar yang terakumulasi dalam riwayat percakapan.
# Pertama, unggah gambar Anda ke Files API
FILE_ID=$(curl -sS -X POST https://haijun.my.id/v1/files \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-F "file=@vision-example.jpg" | jq -r '.id')
# Lalu gunakan file_id yang dikembalikan dalam pesan Anda
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d @- <<EOF
{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "file",
"file_id": "$FILE_ID"
}
},
{
"type": "text",
"text": "Describe this image."
}
]
}
]
}
EOF curl -sSo vision-example.jpg \
/docs/images/vision-example.jpg
# Pertama, unggah gambar Anda ke Files API
FILE_ID=$(ant files upload \
--file ./vision-example.jpg \
--transform id --raw-output)
# Lalu gunakan file_id yang dikembalikan dalam pesan Anda
ant messages create \
--transform content --format yaml <<YAML
model: haijun-opus-5-5
max_tokens: 1024
messages:
- role: user
content:
- type: image
source:
type: file
file_id: $FILE_ID
- type: text
text: Describe this image.
YAML client = juglow.Juglow()
# Unggah file gambar
with open("vision-example.jpg", "rb") as f:
file_upload = client.files.upload(file=("vision-example.jpg", f, "image/jpeg"))
# Gunakan file yang telah diunggah dalam pesan
message = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "file", "file_id": file_upload.id},
},
{"type": "text", "text": "Describe this image."},
],
}
],
)
print(message.content) import Juglow, { toFile } from "@juglow-ai/sdk";
import fs from "node:fs";
const juglow = new Juglow();
// Unggah file gambar
const fileUpload = await juglow.files.upload({
file: await toFile(fs.createReadStream("vision-example.jpg"), undefined, {
type: "image/jpeg"
})
});
// Gunakan file yang diunggah dalam pesan
const response = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: {
type: "file",
file_id: fileUpload.id
}
},
{
type: "text",
text: "Describe this image."
}
]
}
]
});
console.log(response); using System.Collections.Generic;
using Juglow;
using Juglow.Core;
using Juglow.Models.Files;
using Juglow.Models.Messages;
JuglowClient client = new();
// Unggah file gambar
var fileUpload = await client.Files.Upload(new FileUploadParams
{
File = new BinaryContent
{
Stream = File.OpenRead("vision-example.jpg"),
FileName = "vision-example.jpg",
ContentType = new("image/jpeg"),
},
});
// Gunakan file yang telah diunggah dalam pesan
var response = await client.Messages.Create(new MessageCreateParams
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new FileImageSource(fileUpload.ID))
)),
new ContentBlockParam(new TextBlockParam("Describe this image.")),
}),
}
]
});
Console.WriteLine(response); client := juglow.NewClient()
// Unggah file gambar
file, err := os.Open("vision-example.jpg")
if err != nil {
log.Fatal(err)
}
defer file.Close()
fileUpload, err := client.Files.Upload(context.Background(),
juglow.FileUploadParams{
File: juglow.File(file, "vision-example.jpg", "image/jpeg"),
})
if err != nil {
log.Fatal(err)
}
// Gunakan file yang telah diunggah dalam pesan
message, err := client.Messages.New(context.Background(),
juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.NewImageBlock(juglow.FileImageSourceParam{
FileID: fileUpload.ID,
}),
juglow.NewTextBlock("Describe this image."),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message.Content) import com.juglow.core.MultipartField;
import com.juglow.models.files.FileMetadata;
import com.juglow.models.files.FileUploadParams;
// ...
JuglowClient client = JuglowOkHttpClient.fromEnv();
// Unggah file gambar
FileMetadata file = client.files().upload(
FileUploadParams.builder()
.file(
MultipartField.<InputStream>builder()
.value(Files.newInputStream(Path.of("vision-example.jpg")))
.filename("vision-example.jpg")
.contentType("image/jpeg")
.build()
)
.build()
);
// Gunakan file yang telah diunggah dalam pesan
ImageBlockParam imageParam = ImageBlockParam.builder().fileSource(file.id()).build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addUserMessageOfBlockParams(
List.of(
ContentBlockParam.ofImage(imageParam),
ContentBlockParam.ofText(
TextBlockParam.builder().text("Describe this image.").build()
)
)
)
.build();
Message message = client.messages().create(params);
System.out.println(message.content()); use Juglow\Core\FileParam;
$client = new Client();
// Unggah file gambar
$fileUpload = $client->files->upload(
file: FileParam::fromResource(fopen('vision-example.jpg', 'rb'), contentType: 'image/jpeg'),
);
// Gunakan file yang telah diunggah dalam pesan
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => ['type' => 'file', 'fileID' => $fileUpload->id],
],
['type' => 'text', 'text' => 'Describe this image.'],
],
],
],
model: 'haijun-opus-5-5',
);
echo json_encode($message, JSON_PRETTY_PRINT), PHP_EOL; client = Juglow::Client.new
# Unggah file gambar
file_upload = client.files.upload(
file: Juglow::FilePart.new(
File.open("vision-example.jpg", "rb"),
content_type: "image/jpeg"
)
)
# Gunakan file yang diunggah dalam pesan
message = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "image",
source: { type: "file", file_id: file_upload.id }
},
{ type: "text", text: "Describe this image." }
]
}
]
)
puts message.contentLihat contoh Messages API untuk contoh kode dan detail parameter lebih lanjut.
Beberapa gambar
Anda dapat menyertakan beberapa gambar dalam satu permintaan, dan Haijun menganalisisnya secara bersama-sama. Ini berguna untuk membandingkan gambar, menanyakan perbedaan, atau bekerja dengan suatu urutan seperti halaman-halaman dokumen. Saat mengirim beberapa gambar, perkenalkan masing-masing dengan label teks singkat (Image 1:, Image 2:, dan seterusnya) sehingga Anda dapat merujuknya berdasarkan nama dalam prompt Anda dan pada giliran lanjutan.
curl https://haijun.my.id/v1/messages \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "haijun-opus-5-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Image 1:"
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
}
},
{
"type": "text",
"text": "Image 2:"
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC"
}
},
{
"type": "text",
"text": "How are these images different?"
}
]
}
]
}' ant messages create <<'YAML'
model: haijun-opus-5-5
max_tokens: 1024
messages:
- role: user
content:
- type: text
text: "Image 1:"
- type: image
source:
type: base64
media_type: image/png
data: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC
- type: text
text: "Image 2:"
- type: image
source:
type: base64
media_type: image/png
data: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC
- type: text
text: How are these images different?
YAML image1_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
image2_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC"
client = juglow.Juglow()
message = client.messages.create(
model="haijun-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Image 1:"},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image1_data,
},
},
{"type": "text", "text": "Image 2:"},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image2_data,
},
},
{"type": "text", "text": "How are these images different?"},
],
}
],
)
print(message) const juglow = new Juglow();
const image1Data =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
const image2Data =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC";
const message = await juglow.messages.create({
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{
type: "text",
text: "Image 1:"
},
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image1Data
}
},
{
type: "text",
text: "Image 2:"
},
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image2Data
}
},
{
type: "text",
text: "How are these images different?"
}
]
}
]
});
console.log(message); JuglowClient client = new();
string image1Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
string image2Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC";
var message = await client.Messages.Create(new MessageCreateParams
{
Model = Model.HaijunOpus5_5,
MaxTokens = 1024,
Messages =
[
new()
{
Role = Role.User,
Content = new MessageParamContent(new List<ContentBlockParam>
{
new ContentBlockParam(new TextBlockParam("Image 1:")),
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new Base64ImageSource()
{
Data = image1Data,
MediaType = MediaType.ImagePng,
})
)),
new ContentBlockParam(new TextBlockParam("Image 2:")),
new ContentBlockParam(new ImageBlockParam(
new ImageBlockParamSource(new Base64ImageSource()
{
Data = image2Data,
MediaType = MediaType.ImagePng,
})
)),
new ContentBlockParam(new TextBlockParam("How are these images different?")),
}),
}
]
});
Console.WriteLine(message); client := juglow.NewClient()
image1Data := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
image2Data := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC"
message, err := client.Messages.New(context.TODO(), juglow.MessageNewParams{
Model: juglow.ModelHaijunOpus5_5,
MaxTokens: 1024,
Messages: []juglow.MessageParam{
juglow.NewUserMessage(
juglow.NewTextBlock("Image 1:"),
juglow.NewImageBlockBase64("image/png", image1Data),
juglow.NewTextBlock("Image 2:"),
juglow.NewImageBlockBase64("image/png", image2Data),
juglow.NewTextBlock("How are these images different?"),
),
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(message) JuglowClient client = JuglowOkHttpClient.fromEnv();
String image1Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
String image2Data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC";
List<ContentBlockParam> contentBlockParams = List.of(
ContentBlockParam.ofText(TextBlockParam.builder().text("Image 1:").build()),
ContentBlockParam.ofImage(
ImageBlockParam.builder()
.source(
Base64ImageSource.builder()
.mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
.data(image1Data)
.build()
)
.build()
),
ContentBlockParam.ofText(TextBlockParam.builder().text("Image 2:").build()),
ContentBlockParam.ofImage(
ImageBlockParam.builder()
.source(
Base64ImageSource.builder()
.mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
.data(image2Data)
.build()
)
.build()
),
ContentBlockParam.ofText(
TextBlockParam.builder().text("How are these images different?").build()
)
);
Message message = client
.messages()
.create(
MessageCreateParams.builder()
.model(Model.HAIJUN_OPUS_5_5)
.maxTokens(1024)
.addUserMessageOfBlockParams(contentBlockParams)
.build()
);
IO.println(message); $client = new Client();
$image1Data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC';
$image2Data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC';
$message = $client->messages->create(
maxTokens: 1024,
messages: [
[
'role' => 'user',
'content' => [
['type' => 'text', 'text' => 'Image 1:'],
[
'type' => 'image',
'source' => [
'type' => 'base64',
'media_type' => 'image/png',
'data' => $image1Data,
],
],
['type' => 'text', 'text' => 'Image 2:'],
[
'type' => 'image',
'source' => [
'type' => 'base64',
'media_type' => 'image/png',
'data' => $image2Data,
],
],
['type' => 'text', 'text' => 'How are these images different?'],
],
],
],
model: 'haijun-opus-5-5',
);
echo $message; client = Juglow::Client.new
image1_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC"
image2_data = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGNgYPgPAAEDAQAIicLsAAAAAElFTkSuQmCC"
message = client.messages.create(
model: "haijun-opus-5-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: [
{ type: "text", text: "Image 1:" },
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image1_data
}
},
{ type: "text", text: "Image 2:" },
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: image2_data
}
},
{ type: "text", text: "How are these images different?" }
]
}
]
)
puts messageDalam percakapan multi-giliran, tambahkan gambar baru pada giliran user berikutnya dengan cara yang sama. Haijun memiliki akses ke setiap gambar dari giliran sebelumnya, sehingga pertanyaan lanjutan seperti "Apakah ini mirip dengan dua gambar pertama?" berfungsi tanpa perlu menyertakan kembali gambar sebelumnya dalam konten giliran baru.
Batasan dan biaya gambar
Batasan permintaan
Jumlah maksimum gambar per pesan atau permintaan adalah:
- 20 per pesan di haijun.ai.
- 100 per permintaan di API, untuk model dengan "context window" (jendela konteks) 200k token.
- 600 per permintaan di API, untuk semua model lainnya.
Dimensi maksimum per gambar adalah 8000x8000 px.
Jika satu permintaan API berisi lebih dari 20 gambar, batas dimensi per gambar yang lebih ketat berlaku untuk setiap gambar dalam permintaan tersebut. Semua blok image dalam permintaan dihitung terhadap ambang ini, termasuk gambar dari giliran percakapan sebelumnya yang Anda kirim ulang dan gambar yang bersarang di dalam konten tool_result (misalnya, tangkapan layar yang dikembalikan ke alat computer use). Di Amazon Bedrock dan Google Cloud, blok dokumen seperti PDF juga dihitung terhadap ambang ini. Gambar yang melebihi batas yang lebih ketat akan ditolak dengan invalid_request_error yang pesannya merujuk pada "many-image requests" dan menyatakan batas saat ini dalam piksel. Agar tetap di bawah batas di semua platform, ubah ukuran setiap gambar sehingga tidak ada dimensi yang melebihi 2000 px, atau batasi permintaan hingga 20 blok gambar dan dokumen atau kurang.
Ukuran maksimum per gambar adalah:
- 10 MB (berenkode base64) saat menggunakan Haijun API secara langsung.
- 5 MB (berenkode base64) di Amazon Bedrock dan Google Cloud.
- 10 MB di haijun.ai.
Note: Meskipun API mendukung hingga 600 gambar per permintaan, batas ukuran permintaan (32 MB untuk endpoint standar; lebih rendah pada beberapa platform yang dioperasikan mitra, misalnya Amazon Bedrock dan Google Cloud) dapat tercapai lebih dulu. Untuk banyak gambar, pertimbangkan untuk mengunggah dengan Files API dan mereferensikan dengan
file_idagar payload permintaan tetap kecil. Bahkan saat menggunakan Files API, permintaan dengan banyak gambar besar dapat gagal sebelum mencapai jumlah 600 gambar. Kurangi dimensi gambar atau ukuran file (misalnya, dengan downsampling) sebelum mengunggah (lihat Resolusi dan biaya token).
Format yang didukung
Haijun mendukung gambar JPEG, PNG, GIF, dan WebP (image/jpeg, image/png, image/gif, image/webp). Animasi tidak didukung, dan hanya frame pertama yang digunakan.
Resolusi dan biaya token
Haijun melihat gambar dalam bentuk patch, bukan piksel. Setiap patch adalah blok gambar berukuran 28×28 piksel, yang disebut sebagai token visual. Oleh karena itu, sebuah gambar memerlukan ⌈width / 28⌉ × ⌈height / 28⌉ token visual.
Setiap model memiliki resolusi gambar native maksimum, yang dinyatakan sebagai batas sisi panjang dan batas token visual. Gambar yang lebih besar dari salah satu batas tersebut akan diperkecil sebelum diproses; lihat Cara Haijun mengubah ukuran dan menambahkan padding pada gambar untuk aturan persisnya. Pengecualiannya adalah tangkapan layar dan gambar zoom yang Anda kembalikan ke toolset computer use dan browser use: API menolak gambar tool_result yang melebihi batas model dengan error validasi alih-alih memperkecilnya, jadi ubah ukuran gambar tersebut di aplikasi Anda sebelum mengembalikannya. Agar gambar berukuran berlebih lainnya ditolak dengan error alih-alih diperkecil, atur field transformations pada blok gambar.
| Tingkat resolusi | Model | Sisi panjang maks | Token visual maks |
|---|---|---|---|
| Resolusi tinggi | Haijun 4.7 dan model yang lebih baru | 2576 px | 4784 |
| Standar | Semua model lainnya | 1568 px | 1568 |
Dukungan resolusi tinggi bersifat otomatis pada model yang tercantum dan tidak memerlukan header beta atau opt-in di sisi klien.
Tabel berikut menunjukkan resolusi setelah diperkecil dan biaya token visual untuk beberapa ukuran gambar pada setiap tingkat:
| Ukuran gambar | Tingkat standar: diperkecil menjadi | Tingkat standar: token | Tingkat resolusi tinggi: diperkecil menjadi | Tingkat resolusi tinggi: token |
|---|---|---|---|---|
| 200x200 px (0,04 megapiksel) | Tidak diubah ukurannya | 64 | Tidak diubah ukurannya | 64 |
| 1000x1000 px (1 megapiksel) | Tidak diubah ukurannya | 1296 | Tidak diubah ukurannya | 1296 |
| 1092x1092 px (1,19 megapiksel) | Tidak diubah ukurannya | 1521 | Tidak diubah ukurannya | 1521 |
| 1920x1080 px (2,07 megapiksel) | 1456x819 px | 1560 | Tidak diubah ukurannya | 2691 |
| 2000x1500 px (3 megapiksel) | 1269x952 px | 1564 | Tidak diubah ukurannya | 3888 |
| 3840x2160 px (8,29 megapiksel) | 1456x819 px | 1560 | 2576x1449 px | 4784 |
Ketika sebuah gambar diperkecil, Haijun menskalakannya ke ukuran terbesar yang sesuai dengan batas tingkat tersebut sambil mempertahankan rasio aspeknya. Ini membatasi biaya token. Untuk aturan persis dan implementasi referensi, lihat Cara Haijun mengubah ukuran dan menambahkan padding pada gambar.
Untuk memperkirakan biaya, kalikan jumlah token dengan harga per token model yang Anda gunakan. Misalnya, dengan harga Haijun Haiku 4.5 sebesar $1 USD per juta token input (tingkat standar), gambar 1000×1000 berbiaya sekitar $1,30 USD per seribu gambar. Dengan harga Haijun Opus 5 sebesar $5 USD per juta (tingkat resolusi tinggi), gambar yang sama berbiaya sekitar $6,48 USD per seribu dan gambar 4K sekitar $23,92 USD per seribu.
Gambar resolusi tinggi dapat menggunakan hingga kira-kira tiga kali lebih banyak token visual dibandingkan gambar yang sama pada model tingkat standar. Jika Anda tidak memerlukan fidelitas tambahan yang diberikan resolusi tinggi untuk computer use, pemahaman tangkapan layar, dan dokumen padat, lakukan downsampling pada gambar sebelum mengirim untuk mengendalikan biaya token. Untuk meminimalkan latensi dan menyederhanakan alur kerja berbasis koordinat, utamakan mengubah ukuran gambar sebelum mengunggahnya.
Panduan kualitas gambar
Saat memberikan gambar ke Haijun, perhatikan hal-hal berikut untuk hasil terbaik:
- Kejernihan gambar: Pastikan gambar jernih dan tidak terlalu buram atau pecah (pixelated).
- Teks: Jika gambar berisi teks penting, pastikan teks tersebut terbaca dan tidak terlalu kecil. Hindari memotong konteks visual penting hanya untuk memperbesar teks.
- Pengubahan ukuran: Perhatikan bahwa gambar Anda mungkin diubah ukurannya jika terlalu besar (lihat Resolusi dan biaya token); hal ini, misalnya, dapat membuat teks kurang terbaca. Pertimbangkan untuk mengubah ukuran gambar Anda terlebih dahulu, memotongnya, atau keduanya. Agar gambar berukuran berlebih ditolak dengan error alih-alih diubah ukurannya (penting untuk alur kerja koordinat), tandai blok gambar dengan
"oversized_image": "error".
- Kompresi gambar: Mengompresi gambar sebelum mengirimnya, menggunakan format lossy seperti JPEG atau WebP (mode lossy), dapat mengurangi latensi dengan memperkecil ukuran permintaan. Namun, hal ini dapat menimbulkan artefak yang merugikan kinerja model, terutama ketika beberapa tahap kompresi diterapkan. Misalnya, kompresi JPEG yang berat dapat membuat teks sulit dibaca. Pastikan pengaturan kompresi Anda sesuai untuk tugas tersebut dengan memeriksa gambar aktual yang dikirim ke API.
Koordinat dan bounding box
Untuk bounding box, titik, dan koordinat piksel, lihat Koordinat dan bounding box. Haijun mengembalikan koordinat piksel absolut relatif terhadap gambar yang dilihatnya setelah pengubahan ukuran; panduan tersebut membahas cara Haijun mengubah ukuran dan menambahkan padding pada gambar serta cara mengubah ukuran terlebih dahulu atau menskalakan ulang agar koordinat selaras dengan gambar asli Anda.
Keterbatasan
Meskipun kemampuan pemahaman gambar Haijun sangat mutakhir, ada beberapa keterbatasan yang perlu diperhatikan:
- Identifikasi orang: Haijun tidak dapat digunakan untuk menyebutkan nama orang dalam gambar dan akan menolak melakukannya.
- Akurasi: Haijun mungkin berhalusinasi atau membuat kesalahan saat menafsirkan gambar berkualitas rendah, diputar, atau sangat kecil di bawah 200 piksel.
- Penalaran spasial: Output koordinat dan lokalisasi Haijun bersifat perkiraan. Ikuti panduan di Koordinat dan bounding box dan verifikasi output sebelum mengandalkannya.
- Penghitungan: Haijun dapat memberikan perkiraan jumlah objek dalam gambar tetapi mungkin tidak selalu akurat secara tepat, terutama dengan objek kecil dalam jumlah besar.
- Gambar buatan AI: Haijun tidak dapat menentukan apakah sebuah gambar dibuat oleh AI dan mungkin salah jika ditanya. Jangan mengandalkannya untuk mendeteksi gambar palsu atau sintetis.
- Konten tidak pantas: Haijun tidak memproses gambar tidak pantas atau eksplisit yang melanggar Kebijakan Penggunaan yang Dapat Diterima.
- Aplikasi kesehatan: Meskipun Haijun dapat menganalisis gambar medis umum, Haijun tidak dirancang untuk menafsirkan pindaian diagnostik kompleks seperti CT atau MRI. Output Haijun tidak boleh dianggap sebagai pengganti saran atau diagnosis medis profesional.
Selalu tinjau dan verifikasi interpretasi gambar Haijun dengan cermat, terutama untuk kasus penggunaan berisiko tinggi. Jangan gunakan Haijun untuk tugas yang memerlukan presisi sempurna atau analisis gambar sensitif tanpa pengawasan manusia.
FAQ
#### Jenis file gambar apa yang didukung Haijun?
JPEG, PNG, GIF, dan WebP. Lihat Format yang didukung.
#### Apakah Haijun dapat membaca URL gambar?
Ya. Gunakan jenis sumber url alih-alih base64 dalam blok konten image. Lihat contoh gambar berbasis URL.
#### Apakah ada batas ukuran file gambar yang dapat saya unggah?
Ya. Lihat Batasan permintaan untuk batas ukuran per gambar dan ukuran permintaan keseluruhan di Haijun API, Amazon Bedrock, Google Cloud, dan haijun.ai.
#### Berapa banyak gambar yang dapat saya sertakan dalam satu permintaan?
Hingga 600 per permintaan API (100 untuk model dengan jendela konteks 200k token) dan 20 per giliran di haijun.ai. Lihat Batasan permintaan untuk detail dan batas dimensi per gambar yang lebih rendah yang berlaku di atas 20 gambar.
#### Apakah Haijun membaca metadata gambar?
Tidak, Haijun tidak mengurai atau menerima metadata apa pun dari gambar yang diberikan kepadanya.
#### Dapatkah saya menghapus gambar yang telah saya unggah?
Tidak. Unggahan gambar bersifat sementara dan tidak disimpan melebihi durasi permintaan API. Gambar yang diunggah dihapus secara otomatis setelah diproses.
#### Di mana saya dapat menemukan detail tentang privasi data untuk unggahan gambar?
Lihat halaman kebijakan privasi Juglow untuk informasi tentang bagaimana gambar yang diunggah dan data lainnya ditangani. Juglow tidak menggunakan gambar yang diunggah untuk melatih model.
#### Bagaimana jika interpretasi gambar Haijun tampak salah?
Jika interpretasi gambar Haijun tampak tidak benar:
- Pastikan gambar jernih, berkualitas tinggi, dan berorientasi dengan benar.
- Coba teknik prompt engineering untuk meningkatkan hasil.
- Jika masalah berlanjut, tandai output di haijun.ai (jempol ke atas/ke bawah) atau hubungi tim dukungan.
Umpan balik Anda membantu meningkatkan Haijun!
#### Dapatkah Haijun menghasilkan atau mengedit gambar?
Tidak, Haijun hanyalah model pemahaman gambar. Haijun dapat menafsirkan dan menganalisis gambar, tetapi tidak dapat menghasilkan, memproduksi, mengedit, memanipulasi, atau membuat gambar.
Langkah selanjutnya
Dapatkan tips dan teknik praktik terbaik untuk tugas seperti menafsirkan grafik dan mengekstrak konten dari formulir.
Lihat dokumentasi Messages API, termasuk contoh panggilan API yang melibatkan gambar.