Thứ Sáu tuần trước, một agent của mình bắt đầu loop ở một tool call mà nó xử lý ổn suốt ba tuần. Phản xạ chuẩn: pin conversation về model trước đó, replay vài turn cuối, xem loop có biến mất không. Không những không biến mất mà còn tệ hơn — vì các turn được replay lại chẳng còn chút reasoning history nào. Thinking block biến mất sạch.
Lúc đó mình mới thực sự đọc migration notes của Fable 5.1 từ Anthropic, thay vì lướt qua dòng changelog. Khả năng tương thích này cố tình chỉ đi một chiều: Fable 5.1 đọc được thinking block do mọi model Claude đời trước tạo ra. Nhưng không model nào đời trước — kể cả Opus 5, kể cả Fable 5 — đọc được thinking block mà Fable 5.1 viết ra. Chuyển một conversation sang Fable 5.1, nó thừa hưởng toàn bộ reasoning history. Fallback từ Fable 5.1 về bất kỳ model cũ nào, mọi turn từng chạy trên Fable 5.1 mất sạch reasoning — âm thầm, ngay ở tầng API.
Vì sao chuyện này “dính” đúng vào team mình
Mình chạy một agent triage đọc ticket support đến, quyết định mức độ nghiêm trọng, và soạn phản hồi đầu tiên. Nó chạy trên Fable 5 nhiều tháng liền. Hai tuần trước mình chuyển sang Fable 5.1 vì cache read rẻ hơn — 0.25 USD/triệu token so với giá của Fable 5, một con số thật trên khối lượng ticket đọc lại cùng context window hàng trăm lần mỗi ngày.
Khi loop xuất hiện, playbook xử lý sự cố của team ghi rõ “rollback model, đừng động vào code.” Playbook đó được viết cho một thế giới nơi thinking block có thể mang đi được. Giờ thì không còn nữa. Rollback giữa sự cố nghĩa là mọi ticket agent đã từng “suy nghĩ” qua giờ quay lại thành một mớ tool call trần trụi, không còn chuỗi suy luận nào hiển thị — khiến việc debug thực tế khó hơn chứ không dễ hơn, vì mình mất luôn bằng chứng cho thấy model đang nghĩ gì ngay trước khi nó bắt đầu loop.
Cái bẫy thứ hai: thinking block gắn chặt vào prefix, không chỉ vào model
Có một thay đổi liên quan quan trọng ngay cả khi bạn không đụng vào version model. Thinking block trong Fable 5.1 gắn chặt vào đúng prefix của conversation — system prompt, mảng tools, và mọi turn trước đó. Sửa một turn cũ, thêm một tool, hoặc thậm chí đổi nội dung tại một URL mà prompt của bạn tham chiếu tới — mọi thinking block sau đó trong conversation ấy bị vô hiệu hóa và loại bỏ âm thầm.
Mình phát hiện ra điều này vì team làm live prompt tuning — một pattern phổ biến là chỉnh system prompt cho một phần traffic đang chạy và so sánh kết quả. Ở Fable 5, chuyện này vô hại: thinking block không quan tâm chuyện gì xảy ra trước nó. Ở Fable 5.1, mỗi nhánh A/B đụng vào system prompt sẽ reset luôn dấu vết reasoning của conversation đó từ thời điểm đó trở đi. Nếu bạn tính phí theo thinking token, hoặc log chain-of-thought để phục vụ compliance, đây là một lỗ hổng bạn cần biết trước khi kiểm toán viên tự tìm ra nó thay bạn.
# Beta header của Fable 5.1 để lộ ra các thinking block bị drop
# thay vì âm thầm loại bỏ
response = client.messages.create(
model="claude-fable-5-1",
betas=["thinking-binding-controls-2026-08-01"],
system=system_prompt,
messages=conversation_history,
tools=tool_definitions,
)
# Block bị drop xuất hiện ở đây — kiểm tra trước khi bạn
# mặc định reasoning history còn nguyên sau khi sửa prefix
dropped = response.get("input_transformations", [])
if dropped:
log.warning(f"{len(dropped)} thinking block bị vô hiệu do đổi prefix")
Header beta này không được tài liệu hóa như “bản fix cho việc mất reasoning âm thầm,” nhưng thực tế nó đóng đúng vai trò đó. Mình bật nó ngay hôm sau sự cố, và nó nên là header mặc định cho mọi thứ chạy Fable 5.1 ở production, chứ không phải một tùy chọn opt-in.
Những gì team mình đã đổi
Ba thứ, theo thứ tự triển khai nhanh nhất:
Đầu tiên, playbook rollback giờ ghi “roll forward hoặc roll sideways, đừng roll backward” cho bất kỳ agent nào chạy Fable 5.1. Nếu agent trên Fable 5.1 gặp sự cố, mình hoặc fix prompt tại chỗ, route traffic mới sang một conversation Fable 5.1 hoàn toàn mới, hoặc — trường hợp xấu nhất — chấp nhận rằng downgrade đồng nghĩa bắt đầu lại dấu vết reasoning từ số 0. Team ngừng coi rollback model là một hành động miễn phí.
Thứ hai, mọi agent production dùng thinking block giờ chạy với beta header thinking-binding-controls bật sẵn, log các lần bị vô hiệu vào cùng dashboard mình dùng để theo dõi lỗi tool-call. Header này không tính phí, nên chẳng có lý do gì để không bật ở khắp nơi.
Thứ ba — và đây mới là thứ thực sự đổi cách team làm việc hàng ngày — mình ngừng chỉnh live prompt trên những conversation dự kiến chạy dài hơn vài turn. Nếu system prompt cần đổi, mình bắt đầu một conversation ID mới thay vì patch trực tiếp cái đang chạy. Cách này tốn một ít context liên tục, nhưng liên tục mà mình nhìn thấy được vẫn tốt hơn liên tục đã âm thầm mất đi.
Bài học thật sự
Không có gì trong này là chê Fable 5.1 như một model — chất lượng reasoning thật sự tốt hơn, và giá cache là tiền thật tiết kiệm được trên các agent volume cao. Bài học hẹp hơn thế: mỗi khi nhà cung cấp model đổi cách state đi kèm theo một conversation, đó là một thay đổi kiến trúc đối với bạn, không phải một dòng ghi chú của vendor. Đọc migration guide như thể nó là một RFC cho chính hệ thống của bạn — vì với bất kỳ ai đang chạy agent ở production, đúng là như vậy.