Tuần này Anthropic âm thầm ra mắt một tính năng giải quyết một vấn đề mà mình đã phải chắp vá tạm bợ suốt mấy tháng: mid-conversation tool changes, hiện đang beta trên Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 và Claude Opus 5. Ý tưởng đơn giản — thêm hoặc bớt tool giữa các turn của một cuộc hội thoại mà không làm mất prompt cache của tất cả những gì đã có trước đó. Nếu bạn từng xây một agent session chạy dài, bạn sẽ hiểu ngay vì sao cái vế “không làm mất cache” chính là toàn bộ giá trị của tính năng này.
Vấn đề nó thực sự giải quyết
Prompt caching hoạt động bằng cách hash một phần prefix của request — system prompt, tools array, rồi đến messages — và tái sử dụng KV cache cho bất kỳ phần nào chưa thay đổi. Vấn đề, mà mình đã học được theo cách tốn kém khi chạy một agent session nhiều giờ trên một codebase quý trước, là mảng tools nằm ở vị trí sớm hơn trong prefix được hash đó so với field system. Đổi một định nghĩa tool, thêm một MCP server giữa session, bỏ một tool không còn cần nữa — là làm mất cache của toàn bộ cuộc hội thoại, không chỉ turn nơi thay đổi xảy ra. Với một session có hơn 40 turn context tích lũy, đó không phải là sai số nhỏ; đó là hóa đơn ghi cache đầy đủ cho mọi turn tiếp theo cho đến khi session kết thúc.
Cách giải quyết tạm bợ của mình đến giờ khá thô: nạp sẵn mọi tool mà agent có thể cần ngay từ đầu session, kể cả những tool chỉ dùng trong 5% trường hợp, chỉ để tránh việc thay đổi tool list giữa session. Đó là một đánh đổi sai — bạn trả một chi phí nhỏ liên tục (thêm token trong mỗi prefix được cache, tăng độ mơ hồ khi model chọn tool) để tránh một chi phí một lần lớn hơn nhiều (mất cache toàn bộ). Mid-conversation tool changes cho phép bạn thực sự làm đúng: bắt đầu gọn nhẹ, mở rộng hoặc thu hẹp bộ tool khi hình dạng của task trở nên rõ ràng hơn, mà không bị phạt cache.
Cơ chế trông như thế nào
Tính năng này cần header beta mid-conversation-tool-changes-2026-07-01. Về cấu trúc, đây là phần tương ứng cho tools của mid-conversation system messages mà Anthropic đã ra mắt trước đó — bạn chèn một thay đổi có phạm vi áp dụng từ thời điểm đó trở đi mà không viết lại lịch sử:
import anthropic
client = anthropic.Anthropic()
# Turn 1: agent bắt đầu với bộ tool tối thiểu
response = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
tools=[read_file_tool, grep_tool],
messages=[{"role": "user", "content": "Find where the auth middleware lives"}],
extra_headers={"anthropic-beta": "mid-conversation-tool-changes-2026-07-01"},
)
# Turn N: task giờ cần quyền deploy — thêm tool mà không làm mất
# cache đã tích lũy qua các turn trước
response = client.messages.create(
model="claude-opus-5",
max_tokens=4096,
tools=[read_file_tool, grep_tool, deploy_tool], # deploy_tool được thêm vào
messages=conversation_history + [
{"role": "user", "content": "Now deploy the fix to staging"}
],
extra_headers={"anthropic-beta": "mid-conversation-tool-changes-2026-07-01"},
)
Chi tiết vận hành quan trọng: đây là việc thêm/bớt tool trong cùng một dòng lineage được cache, không phải một prefix hoàn toàn mới. Bạn không đang lừa cache — bạn đang nói rõ với API “tool đã thay đổi tại đây, giữ nguyên mọi thứ trước turn này.”
Nó quan trọng ở đâu trong kiến trúc agent thực tế
Mình chạy một vài agent session sống lâu — một research agent tích lũy context qua nhiều ngày, một build agent bắt đầu với tool chỉ đọc và chỉ được cấp quyền ghi/deploy sau khi plan được duyệt. Cả hai đều đúng hình dạng mà tính năng này nhắm tới: leo thang quyền giữa task, không phải một bộ tool cố định quyết định từ đầu.
Trường hợp build-agent thú vị hơn ở góc độ kỹ thuật an toàn, và nó khớp tốt với pattern “không có standing privileges” mà mình viết về CrowdStrike Agentic Identity Provider tuần này: bắt đầu session chỉ với read_file, grep, run_tests. Khi agent đề xuất plan và con người duyệt, lúc đó mới thêm write_file và deploy vào tools array cho turn tiếp theo. Trước đây, làm điều này nghĩa là hoặc chịu mất cache toàn bộ đúng vào thời điểm task trở nên đắt đỏ nhất (ngay trước khi deploy, tất nhiên — định luật Murphy của caching), hoặc cấp quyền ghi từ đầu và chỉ dựa vào hướng dẫn trong prompt để chặn, một control yếu hơn nhiều so với việc tool đơn giản là không gọi được.
# Pattern: leo thang quyền dựa trên approval, giữ nguyên cache
BASE_TOOLS = [read_file_tool, grep_tool, run_tests_tool]
ESCALATED_TOOLS = BASE_TOOLS + [write_file_tool, deploy_tool]
def get_tools_for_turn(plan_approved: bool) -> list:
return ESCALATED_TOOLS if plan_approved else BASE_TOOLS
Đó là một hàm nhỏ, nhưng điểm mấu chốt là giờ đây nó là một hàm nhỏ miễn phí — không có thuế cache khi gọi khác nhau theo từng turn.
Điểm cần lưu ý khi rollout
Hai điều cần chú ý nếu áp dụng ngay bây giờ, vì đây vẫn là beta:
- Hỗ trợ model còn hẹp. Chỉ Fable 5, Mythos 5, Opus 4.8 và Opus 5. Nếu bạn đang chạy bất kỳ model nào khác trong production — kể cả các dòng Sonnet cũ hơn — tính năng này âm thầm không áp dụng, và bạn cần kiểm tra xem header beta có thực sự có tác dụng hay bị bỏ qua.
- Không phải mọi loại thay đổi tool đều được xử lý như nhau. Bỏ một tool mà model vừa gọi ở turn trước có mức rủi ro khác với việc thêm một tool mới — hãy đảm bảo test suite của bạn có một turn mà model cố gọi một tool đang bị gỡ giữa chừng, để kiểm tra đường xử lý lỗi của model (nó nên báo tool không khả dụng một cách rõ ràng, không hallucinate ra một lệnh gọi).
Kết luận
Prompt caching đã biến “giữ system prompt và tools ổn định” thành một ràng buộc kiến trúc ngầm cho bất kỳ ai làm agent chạy dài — một ràng buộc mà hầu hết mọi người giải quyết bằng cách nạp thừa tool ngay từ đầu session, giống mình đã làm. Mid-conversation tool changes gỡ bỏ ràng buộc đó trực tiếp thay vì bắt bạn thiết kế vòng qua nó, và đó là tín hiệu thú vị hơn ở đây: Anthropic đang coi tools array như thứ nên tiến hóa cùng cuộc hội thoại, không phải một hợp đồng tĩnh cố định lúc khởi động session. Nếu bạn đang chạy agent với hơn vài giờ context tích lũy, đây là thứ đáng gắn vào ngay, kể cả với header beta — riêng khoản tiết kiệm cache nhiều khả năng đã bù lại công sức migrate ngay trong session dài đầu tiên.