Chúng tôi đã nâng cấp giao diện tương thích với OpenAI với các tối ưu hóa sâu hơn dành riêng cho các mô hình trong dòng Claude. Bây giờ bạn có thể kiểm soát tư duy và lưu trữ một cách chính xác và thuận tiện hơn. Tư duy xen kẽ trong các cuộc hội thoại nhiều lượt giờ đây thân thiện hơn với người dùng, cho phép tích hợp liền mạch mà không cần thêm tham số. Nó cũng hỗ trợ kích hoạt các tính năng beta do Anthropic cung cấp.
1. Tư duy mô hình (Tư duy mở rộng)
1.1 Ưu điểm của tư duy xen kẽ
Khi tư duy xen kẽ không được kích hoạt, mô hình chỉ thực hiện tư duy một lần vào đầu lượt trợ lý; các phản hồi tiếp theo được tạo ra ngay sau khi nhận kết quả từ công cụ, mà không tạo ra các khối tư duy mới:
User → [Tư duy] → Gọi công cụ → Kết quả công cụ → Phản hồi
Khi tư duy xen kẽ được kích hoạt, mô hình chèn một khối tư duy mới mỗi khi nó nhận được kết quả từ công cụ, tạo thành một chuỗi lý luận:
User → [Tư duy] → Gọi công cụ → Kết quả công cụ → [Tư duy] → Phản hồi
↑ Tư duy xen kẽ
Điều này cho phép mô hình:
- Thực hiện lý luận thứ cấp dựa trên kết quả công cụ, thay vì chỉ đơn giản là nối các đầu ra lại với nhau.
- Chuỗi lý luận giữa nhiều lần gọi công cụ, nơi mỗi quyết định dựa trên phân tích của bước trước đó.
Tham khảo: Tư duy xen kẽ của Anthropic
1.2 Kích hoạt tư duy
Bạn có thể kích hoạt tư duy theo bốn cách, chọn bất kỳ một trong số đó:
| Phương pháp | Ví dụ | Mô tả |
|---|---|---|
reasoning_effort |
"reasoning_effort": "low" |
Tham số tiêu chuẩn của OpenAI, đặt ở cấp độ cao nhất của thân yêu cầu |
reasoning.effort |
"reasoning": {"effort": "low"} |
Tương đương với phương pháp trước, đặt trong đối tượng lý luận |
reasoning.max_tokens |
"reasoning": {"max_tokens": 1024} |
Kiểm soát chính xác số lượng token tối đa cho tư duy |
Tên mô hình với -think |
"model": "claude-sonnet-4-5-think" |
Cách đơn giản nhất, không yêu cầu tham số bổ sung |
Ưu tiên (khi nhiều phương pháp được sử dụng):reasoning_effort>reasoning.max_tokens>reasoning.effort>-thinksuffix
Các giá trị có thể cho nỗ lực: minimal / low / medium / high / xhigh
1.3 Trả về tư duy
Thông điệp phản hồi sẽ bao gồm hai trường mới:
reasoning_content: Nội dung tư duy (chuỗi), để dễ dàng hiển thị.reasoning_details: Thông tin cấu trúc hoàn chỉnh về tư duy, cần được trả về nguyên trạng trong các cuộc hội thoại nhiều lượt; cấu trúc nội bộ có thể khác nhau giữa các nhà cung cấp.
Ví dụ không streaming (bỏ qua các trường không liên quan):
{
"choices": [{
"message": {
"role": "assistant",
"content": "Xin chào! Tôi có thể giúp gì cho bạn hôm nay?",
"reasoning_content": "Người dùng chỉ đang chào hỏi...",
"reasoning_details": {
"type": "thinking",
"thinking": "Người dùng chỉ đang chào hỏi...",
"signature": "Er8CCkYI..."
}
}
}]
}
Trong các phản hồi streaming, nội dung tư duy sẽ được gửi theo từng phần qua delta.reasoning_content và delta.reasoning_details. Để biết logic nối kết streaming hoàn chỉnh, hãy tham khảo ví dụ đầy đủ bên dưới.
1.4 Giữ lại tư duy trong các cuộc hội thoại nhiều lượt (Tư duy xen kẽ được tích hợp sẵn, không cần tham số bổ sung)
Để cho phép mô hình tiếp tục khả năng lý luận của nó trong các cuộc hội thoại nhiều lượt, chỉ cần đặt reasoning_details đã được trả về trước đó nguyên trạng vào thông điệp trợ lý của lượt tiếp theo:
messages = [
{"role": "user", "content": "Thời tiết ở Boston như thế nào?"},
{
"role": "assistant",
"content": response.choices[0].message.content,
"tool_calls": response.choices[0].message.tool_calls,
"reasoning_details": response.choices[0].message.reasoning_details,
},
{
"role": "tool",
"tool_call_id": "toolu_xxx",
"content": '{"temperature": 45, "condition": "mưa"}',
}
]
AIHubMix sẽ tự động kích hoạt tư duy xen kẽ khi nó phát hiện thông tin tư duy lịch sử trong yêu cầu, cho phép mô hình tiếp tục lý luận sâu sau khi nhận được kết quả gọi công cụ mà không cần thêm tham số.
1.5 Ví dụ hoàn chỉnh
Hai ví dụ sau đây minh họa quy trình hoàn chỉnh của cuộc gọi công cụ nhiều lượt + tư duy xen kẽ: yêu cầu của người dùng → mô hình suy nghĩ và gọi một công cụ → chèn kết quả công cụ (bảo tồn reasoning_details) → mô hình tư duy xen kẽ đưa ra phản hồi cuối cùng.
Không streaming · Tư duy xen kẽ
import os
import json
from openai import OpenAI
client = OpenAI(
base_url="https://aihubmix.com/v1",
api_key=os.environ.get("AIHUBMIX_API_KEY", "sk-***"),
)
# ── Định nghĩa công cụ ───────────────────────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Lấy thời tiết hiện tại cho một địa điểm",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Tên thành phố"}},
"required": ["location"]
}
}
}]
# ── Thực thi công cụ giả ───────────────────────────────────────
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "mưa", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "nắng", "humidity": "45%", "wind": "5 mph S"},
}
def execute_tool(name: str, args: dict) -> str:
if name == "get_weather":
key = next((k for k in WEATHER_DB if k in args.get("location", "").lower()), None)
return json.dumps(WEATHER_DB.get(key, {"temperature": "65°F", "condition": "trong xanh"}))
return "{}"
# ── Vòng lặp hội thoại nhiều lượt ─────────────────────────────
messages = [
{"role": "user", "content": "Thời tiết ở Boston như thế nào? Sau đó hãy gợi ý tôi nên mặc gì."}
]
turn = 0
while True:
turn += 1
print(f"\n── Lượt {turn} ──")
response = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
msg = response.choices[0].message
# In quá trình tư duy
if msg.reasoning_content:
label = "Tư duy xen kẽ" if turn > 1 else "Tư duy"
print(f"[{label}] {msg.reasoning_content}")
# In nội dung phản hồi
if msg.content:
print(f"[Phản hồi] {msg.content}")
# In các cuộc gọi công cụ
if msg.tool_calls:
for tc in msg.tool_calls:
print(f"[Cuộc gọi công cụ: {tc.function.name}] {tc.function.arguments}")
# Xây dựng thông điệp trợ lý, bảo tồn reasoning_details (quan trọng!)
assistant_msg = {"role": "assistant", "content": msg.content}
if msg.tool_calls:
assistant_msg["tool_calls"] = msg.tool_calls
if msg.reasoning_details:
assistant_msg["reasoning_details"] = msg.reasoning_details # trả lại không thay đổi
messages.append(assistant_msg)
# Không có tool_calls có nghĩa là cuộc hội thoại đã hoàn tất
if not msg.tool_calls:
break
# Thực thi các công cụ và thêm kết quả vào thông điệp
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
print(f"[Kết quả công cụ: {tc.function.name}] {result}")
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
Streaming · Tư duy xen kẽ
import os
import sys
import json
from openai import OpenAI
client = OpenAI(
base_url="https://aihubmix.com/v1",
api_key=os.environ.get("AIHUBMIX_API_KEY", "sk-***"),
)
# ── Định nghĩa công cụ & thực thi giả ─────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Lấy thời tiết hiện tại cho một địa điểm",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Tên thành phố"}},
"required": ["location"]
}
}
}]
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "mưa", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "nắng", "humidity": "45%", "wind": "5 mph S"},
}
def execute_tool(name: str, args: dict) -> str:
if name == "get_weather":
key = next((k for k in WEATHER_DB if k in args.get("location", "").lower()), None)
return json.dumps(WEATHER_DB.get(key, {"temperature": "65°F", "condition": "trong xanh"}))
return "{}"
# ── Bộ thu thập phản hồi streaming ────────────────────────────────
def stream_and_collect(turn: int, **kwargs):
"""Streaming phản hồi, in tư duy/nội dung theo thời gian thực, tích lũy reasoning_details/tool_calls."""
rd = {} # reasoning_details tích lũy
content = "" # nội dung phản hồi tích lũy
tc_map = {} # tool_calls tích lũy (theo chỉ số)
cur = "none" # phần đầu ra hiện tại: none / thinking / content
stream = client.chat.completions.create(stream=True, **kwargs)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
# ── Xử lý tư duy ──
rd_delta = getattr(delta, "reasoning_details", None)
if rd_delta and isinstance(rd_delta, dict):
for k, v in rd_delta.items():
if k == "type":
rd[k] = v
elif isinstance(v, str):
rd[k] = rd.get(k, "") + v
elif v is not None:
rd[k] = v
# In các phần tư duy theo thời gian thực
thinking_chunk = rd_delta.get("thinking", "")
if thinking_chunk:
if cur != "thinking":
cur = "thinking"
label = "Tư duy xen kẽ" if turn > 1 else "Tư duy"
sys.stdout.write(f"\n[{label}] ")
sys.stdout.write(thinking_chunk)
sys.stdout.flush()
# ── Xử lý nội dung ──
if delta.content:
if cur != "content":
if cur == "thinking":
sys.stdout.write("\n")
cur = "content"
sys.stdout.write("\n[Phản hồi] ")
sys.stdout.write(delta.content)
sys.stdout.flush()
content += delta.content
# ── Xử lý tool_calls ──
for tc in delta.tool_calls or []:
i = tc.index
if i not in tc_map:
tc_map[i] = {"id": "", "type": "function",
"function": {"name": "", "arguments": ""}}
if tc.id:
tc_map[i]["id"] = tc.id
if tc.function:
tc_map[i]["function"]["name"] += tc.function.name or ""
tc_map[i]["function"]["arguments"] += tc.function.arguments or ""
# Kết thúc phần đầu ra hiện tại
if cur in ("thinking", "content"):
sys.stdout.write("\n")
tool_calls = [tc_map[i] for i in sorted(tc_map)] if tc_map else None
return {
"content": content or None,
"reasoning_details": rd or None,
"tool_calls": tool_calls,
}
# ── Vòng lặp hội thoại nhiều lượt ─────────────────────────────
messages = [
{"role": "user", "content": "Thời tiết ở Boston như thế nào? Sau đó hãy gợi ý tôi nên mặc gì."}
]
turn = 0
while True:
turn += 1
print(f"\n── Lượt {turn} ──")
result = stream_and_collect(
turn,
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
# In các cuộc gọi công cụ
if result["tool_calls"]:
for tc in result["tool_calls"]:
print(f"[Cuộc gọi công cụ: {tc['function']['name']}] {tc['function']['arguments']}")
# Xây dựng thông điệp trợ lý, bảo tồn reasoning_details (quan trọng!)
assistant_msg = {"role": "assistant", "content": result["content"]}
if result["tool_calls"]:
assistant_msg["tool_calls"] = result["tool_calls"]
if result["reasoning_details"]:
assistant_msg["reasoning_details"] = result["reasoning_details"] # trả lại không thay đổi
messages.append(assistant_msg)
# Không có tool_calls có nghĩa là cuộc hội thoại đã hoàn tất
if not result["tool_calls"]:
break
# Thực thi các công cụ và thêm kết quả vào thông điệp
for tc in result["tool_calls"]:
args = json.loads(tc["function"]["arguments"])
tool_result = execute_tool(tc["function"]["name"], args)
print(f"[Kết quả công cụ: {tc['function']['name']}] {tool_result}")
messages.append({"role": "tool", "tool_call_id": tc["id"], "content": tool_result})
1.6 Quy tắc ánh xạ cường độ tư duy
Chế độ Nỗ lực:
- Opus 4.6 / Sonnet 4.6 và cao hơn: ánh xạ đến mức độ nỗ lực Tư duy thích ứng của Anthropic.
- Các mô hình khác: được tính toán bằng công thức cho
budget_tokens:
budget_tokens = max(min(max_tokens × effort_ratio, 128000), 1024)
| nỗ lực | effort_ratio |
|---|---|
| xhigh | 0.95 |
| high | 0.80 |
| medium | 0.50 |
| low | 0.20 |
| minimal | 0.10 |
Ánh xạ nỗ lực tư duy thích ứng:
| Nỗ lực đầu vào | Opus 4.6 | Sonnet 4.6 |
|---|---|---|
| xhigh | max | high |
| high | high | high |
| medium | medium | medium |
| low | low | low |
| minimal | low | low |
Chế độ max_tokens: Được gán trực tiếp như budget_tokens của Anthropic.
-think suffix: Opus/Sonnet 4.6+ sử dụng tư duy thích ứng (nỗ lực=medium); các mô hình khác đặt budget_tokens = min(10240, max_tokens - 1), với max_tokens mặc định là 4096.
2. Lưu trữ prompt
Bạn có thể sử dụng Lưu trữ prompt khi thực hiện các yêu cầu đến mô hình Claude qua giao diện Chat. Bằng cách thiết lập các điểm dừng cache_control trong các thông điệp, các khối văn bản lớn (như thẻ vai trò, dữ liệu RAG, chương sách, v.v.) có thể được lưu trữ để tái sử dụng, cho phép các yêu cầu tiếp theo truy cập trực tiếp vào bộ nhớ cache và giảm đáng kể chi phí.
Tài liệu chính thức của Claude: Lưu trữ prompt
2.1 Chi phí lưu trữ
| Hoạt động | Hệ số giá (so với giá đầu vào gốc) |
|---|---|
| Ghi cache (TTL 5 phút) | 1.25x |
| Ghi cache (TTL 1 giờ) | 2x |
| Đọc cache | 0.1x |
2.2 Các mô hình được hỗ trợ và độ dài cache tối thiểu
| Mô hình | Số lượng token cache tối thiểu |
|---|---|
| Claude Opus 4.8 | 1024 |
| Claude Opus 4.7 | 2048 |
| Claude Opus 4.6 / Opus 4.5 | 4096 |
| Claude Sonnet 4.6 / Sonnet 4.5 / Opus 4.1 / Opus 4 / Sonnet 4 / Sonnet 3.7 (không còn sử dụng) | 1024 |
| Claude Haiku 4.5 | 4096 |
| Claude Haiku 3.5 (không còn sử dụng) / Haiku 3 | 2048 |
Giới hạn số lượng điểm dừng: Tối đa 4 cache_control điểm dừng cho mỗi yêu cầu.2.3 TTL cache
| TTL | Cú pháp | Tình huống áp dụng |
|---|---|---|
| 5 phút (mặc định) | "cache_control": {"type": "ephemeral"} |
Các phiên ngắn, yêu cầu định kỳ |
| 1 giờ | "cache_control": {"type": "ephemeral", "ttl": "1h"} |
Các phiên dài, để tránh ghi cache lặp lại |
Chi phí ghi cho TTL 1 giờ cao hơn, nhưng chúng có thể tiết kiệm tổng chi phí bằng cách giảm ghi lặp lại trong các phiên dài. Tất cả các mô hình từ Claude 4.5 trở lên từ tất cả các nhà cung cấp (bao gồm Anthropic, Amazon Bedrock, Google Vertex AI) đều hỗ trợ TTL 1 giờ.
2.4 Cách sử dụng
Bạn có thể thiết lập các điểm dừng cache bằng cách sử dụng trường cache_control trong system, user (bao gồm cả hình ảnh), và tools. Các ví dụ sau chỉ hiển thị cấu trúc chính, bỏ qua các khối văn bản lớn.
Lưu trữ thông điệp hệ thống (TTL mặc định 5 phút):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [
{"type": "text", "text": "Bạn là một trợ lý AI"},
{
"type": "text",
"text": "(ngữ cảnh dài)",
"cache_control": {"type": "ephemeral"}
}
]
},
{
"role": "user",
"content": [{"type": "text", "text": "Xin chào"}]
}
]
}
Lưu trữ thông điệp người dùng (TTL 1 giờ):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [{"type": "text", "text": "Bạn là một trợ lý AI"}]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "(ngữ cảnh dài)",
"cache_control": {"type": "ephemeral", "ttl": "1h"}
},
{"type": "text", "text": "Xin chào"}
]
}
]
}
Lưu trữ thông điệp hình ảnh:
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"detail": "auto", "url": "data:image/jpeg;base64,/9j/4AAQ..."},
"cache_control": {"type": "ephemeral"}
},
{"type": "text", "text": "Đây là gì?"}
]
}
Lưu trữ định nghĩa công cụ:
cache_control được đặt ở cấp độ cao nhất của đối tượng công cụ (cùng với type và function):
{
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Lấy thời tiết hiện tại cho một địa điểm",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
},
"cache_control": {"type": "ephemeral", "ttl": "1h"}
}]
}
2.5 Xem trạng thái cache
Trường usage trong phản hồi sẽ trả về claude_cache_tokens_details, ghi lại thông tin cache chi tiết:
Yêu cầu đầu tiên (Tạo cache):
{
"usage": {
"prompt_tokens": 22,
"completion_tokens": 890,
"total_tokens": 912,
"claude_cache_tokens_details": {
"cache_creation_input_tokens": 6266,
"cache_read_input_tokens": 0,
"cache_write_5_minutes_input_tokens": 6266,
"cache_write_1_hour_input_tokens": 0
}
}
}
Các yêu cầu tiếp theo (Cache Hit):
{
"usage": {
"prompt_tokens": 22,
"completion_tokens": 810,
"total_tokens": 832,
"prompt_tokens_details": {
"cached_tokens": 6266
},
"claude_cache_tokens_details": {
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 6266,
"cache_write_5_minutes_input_tokens": 0,
"cache_write_1_hour_input_tokens": 0
}
}
}
| Trường | Ý nghĩa |
|---|---|
cache_creation_input_tokens |
Số lượng token được ghi vào cache trong yêu cầu này |
cache_read_input_tokens |
Số lượng token được đọc từ cache trong yêu cầu này |
cache_write_5_minutes_input_tokens |
Số lượng token được ghi vào cache TTL 5 phút |
cache_write_1_hour_input_tokens |
Số lượng token được ghi vào cache TTL 1 giờ |
prompt_tokens_details.cached_tokens |
Số lượng token đã được lưu trữ khi cache được hit, tương thích với định dạng OpenAI |
3. Tiêu đề yêu cầu cho anthropic-beta
Bạn có thể kích hoạt các tính năng beta của mô hình Claude qua tiêu đề HTTP anthropic-beta, mà AIHubMix sẽ chuyển tiếp đến API của Anthropic.
Cách sử dụng
Thêm anthropic-beta vào tiêu đề yêu cầu, với giá trị là định danh tính năng beta tương ứng:
curl "https://aihubmix.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AIHUBMIX_API_KEY" \
-H "anthropic-beta: context-1m-2025-08-07" \
-d '{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [
{"type": "text", "text": "Bạn là một trợ lý AI"},
{
"type": "text",
"text": "(ngữ cảnh dài)",
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": [{"type": "text", "text": "xin chào"}]}
]
}'
Để biết các định danh beta có sẵn cụ thể, vui lòng tham khảo Tài liệu API của Anthropic.
Cập nhật lần cuối: 2026-06-01