Cara Membangun Cadangan Lokal untuk Menyelamatkan Sesi Agen Saat OpenAI Assistants API Down
TuBrief 편집팀
2026년 8월 7일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
Menjalankan layanan dengan agen AI sendirian bisa menjadi situasi yang rumit jika API vendor tiba-tiba mengalami shutdown. Tepat pada 26 Agustus 2026, ketika OpenAI menutup total endpoint beta Assistants API v1, thread obrolan dan riwayat eksekusi yang disimpan di server akan menguap begitu saja. Struktur yang menyerahkan seluruh status sesi ke server vendor tidak ada bedanya dengan bekerja sambil membawa bom waktu.
Jika tidak ingin terus bergantung pada platform, Anda harus membawa status percakapan ke sistem file komputer Anda sendiri. Jauh lebih aman untuk menggunakan LLM sebagai alat komputasi yang dapat ditukar kapan saja, sementara konteks percakapan dan aset prompt dipegang dan dikendalikan secara langsung secara lokal.
Jika Anda memercayakan sesi ke server penyedia seperti OpenAI atau Anthropic, tidak ada cara untuk mengetahui bagaimana status percakapan dikompresi dan dienkripsi di dalam sistem mereka. Saat terjadi masalah, proses audit untuk melihat ke dalam sistem menjadi tidak mungkin dilakukan. Setiap kali giliran percakapan bertambah, seluruh konteks diproses ulang dari awal, yang membuat biaya token berlipat ganda. Biaya Code Interpreter sebesar $0.03 per sesi atau biaya penyimpanan File Search sebesar $0.10 per GB per bulan juga secara diam-diam menggerogoti anggaran Anda.
| Item Evaluasi | Sesi Kelolaan Cloud (OpenAI Assistants) | Harness Independen Sistem File Lokal |
|---|---|---|
| Kepemilikan Data | Terisolasi di server vendor (tidak dapat diekspor) | Disimpan sebagai file JSON di direktori lokal |
| Kontenuitas Layanan | Thread hilang saat API shutdown pada 26 Agustus 2026 | Langsung beralih ke model lain meskipun server vendor down |
| Biaya Konteks | Pemborosan token karena pemrosesan ulang seluruh thread setiap giliran | Penghematan token dengan hanya menyuntikkan perubahan DiffMem |
| Transparansi Debugging | Tidak dapat diverifikasi karena kompresi sisi server yang tidak transparan | Memeriksa proses inferensi secara langsung melalui log middleware lokal |
Seperti yang disebutkan oleh CEO Microsoft Satya Nadella, struktur yang menyerahkan manajemen sesi ke infrastruktur penyedia model adalah hal yang berbahaya. Ini karena aset yang sebenarnya bukanlah model itu sendiri, melainkan konteks percakapan milik Anda sendiri. 'Ketergantungan perilaku' yang ditunjukkan oleh 76% pengembang dalam survei Docker juga pada akhirnya muncul karena kehilangan kendali atas sesi ini.
Dengan menggabungkan kerangka kerja LangGraph dan Custom Checkpointer, Anda dapat mengamankan status percakapan ke dalam file JSON lokal. Saat menulis data ke file, gunakan metode penulisan atomik (Atomic Write) yang memanfaatkan os.replace. Bahkan jika daya terputus atau proses dimatikan secara paksa di tengah jalan, data tidak akan rusak.
`python
import json
import os
from datetime import datetime
from typing import Any, Dict, List
from dataclasses import dataclass, asdict
@dataclass
class LocalSessionState:
session_id: str
model_provider: str
model_name: str
system_prompt: str
messages: List[Dict[str, Any]]
metadata: Dict[str, Any]
updated_at: str
class LocalFileCheckpointer:
def init(self, base_dir: str = "./agent_workspace/sessions"):
self.base_dir = base_dir
os.makedirs(self.base_dir, exist_ok=True)
def _get_file_path(self, session_id: str) -> str:
return os.path.join(self.base_dir, f"{session_id}.json")
def save_state(self, state: LocalSessionState) -> str:
file_path = self._get_file_path(state.session_id)
temp_path = f"{file_path}.tmp"
state.updated_at = datetime.utcnow().isoformat()
data = asdict(state)
with open(temp_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
os.replace(temp_path, file_path)
return file_path
`
Anda dapat mengatur lingkungan pencadangan sesi dengan cara berikut:
agent_workspace di dalam folder proyek Anda, dan letakkan direktori prompts/, sessions/, dan logs/ di dalamnya. Aturan operasional diringkas dalam AGENTS.md.LocalFileCheckpointer dari kode Python di atas dan hubungkan agar snapshot ditimpa ke file JSON setiap kali percakapan diperbarui per giliran.GitSessionVersioner di bawah ini ke pipa post-hook Git untuk secara otomatis melakukan commit perubahan ke Git setiap kali ada perubahan pada file sesi.`python
import subprocess
class GitSessionVersioner:
def init(self, repo_dir: str = "./agent_workspace"):
self.repo_dir = repo_dir
self._ensure_git_repo()
def _ensure_git_repo(self):
if not os.path.exists(os.path.join(self.repo_dir, ".git")):
subprocess.run(["git", "init"], cwd=self.repo_dir, check=True)
def commit_session(self, session_id: str, commit_message: str):
file_name = f"sessions/{session_id}.json"
subprocess.run(["git", "add", file_name], cwd=self.repo_dir, check=True)
status = subprocess.run(["git", "status", "--porcelain", file_name], cwd=self.repo_dir, capture_output=True, text=True)
if status.stdout.strip():
subprocess.run(["git", "commit", "-m", f"session({session_id}): {commit_message}"], cwd=self.repo_dir, check=True)
`
Jika struktur ini diatur, meskipun thread percakapan menjadi panjang, Anda tidak perlu lagi memaksa memasukkan seluruh riwayat ke dalam jendela konteks (context window). Karena Anda hanya mencari dan memilih perubahan DiffMem, pengeluaran token yang tidak perlu dapat dicegah dan waktu pemulihan sesi berkurang lebih dari 2 jam.
API cloud seringkali menyembunyikan sepenuhnya apa yang dipikirkan agen dan alat apa yang dipanggilnya. Untuk menghilangkan rasa frustrasi dalam debugging, Anda harus menempatkan LiteLLM Proxy atau interceptor middleware di tengah-tengah dan mencatat data yang masuk dan keluar secara langsung ke file. Jika Anda menjalankan alat pelacakan sumber terbuka seperti Langfuse atau Weights & Biases Weave di Docker lokal, Anda dapat mengumpulkan perbedaan antara type: function OpenAI atau input_schema Anthropic di satu tempat dengan rapi.
`python
import json
import logging
from typing import Dict, Any, Optional
class AgentLoggingMiddleware:
def init(self, log_file_path: str):
self.logger = logging.getLogger("AgentLogger")
self.logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(log_file_path, encoding="utf-8")
handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s'))
self.logger.addHandler(handler)
def on_pre_tool_execution(self, tool_name: str, tool_args: Dict[str, Any], tool_call_id: str):
log_entry = {"event": "PreToolUse", "tool_call_id": tool_call_id, "tool_name": tool_name, "arguments": tool_args}
self.logger.info(f"TOOL_CALL_INIT: {json.dumps(log_entry, ensure_ascii=False)}")
def on_post_tool_execution(self, tool_call_id: str, result: Any, error: Optional[str] = None):
log_entry = {"event": "PostToolUse", "tool_call_id": tool_call_id, "result": result, "error": error}
if error:
self.logger.error(f"TOOL_CALL_FAILED: {json.dumps(log_entry, ensure_ascii=False)}")
else:
self.logger.info(f"TOOL_CALL_SUCCESS: {json.dumps(log_entry, ensure_ascii=False)}")
`
Pengumpulan log eksekusi diselesaikan dalam tiga langkah:
AgentLoggingMiddleware pada titik PreToolUse dan PostToolUse dari lingkaran eksekusi agen.Hanya dengan mengumpulkan log secara benar, Anda dapat menemukan penyebab kesalahan yang terjadi pada argumen alat dalam satu kali coba. Biaya token API yang terbuang karena berputar dalam perulangan yang salah akan berkurang secara signifikan.
OpenAI API mengirim dan menerima argumen alat sebagai string JSON yang diserialisasikan serta memiliki peran tool terpisah. Di sisi lain, Anthropic Messages API menggunakan objek kamus yang diurai dan blok tool_result di dalam pesan user. Karena spesifikasinya berbeda, jika Anda mengirim data JSON yang dicadangkan secara langsung ke Anthropic, akan terjadi error HTTP 400. Harus ada adaptor di tengah yang menyesuaikan spesifikasinya.
`python
import json
from typing import List, Dict, Any, Tuple
class CrossModelSessionAdapter:
@staticmethod
def openai_to_anthropic_format(system_prompt: str, openai_messages: List[Dict[str, Any]]) -> Tuple[str, List[Dict[str, Any]]]:
anthropic_messages = []
i = 0
while i < len(openai_messages):
msg = openai_messages[i]
role = msg.get("role")
if role == "system":
system_prompt = msg.get("content", system_prompt)
i += 1
elif role == "user":
anthropic_messages.append({"role": "user", "content": msg.get("content")})
i += 1
elif role == "assistant":
content_blocks = []
if msg.get("content"):
content_blocks.append({"type": "text", "text": msg.get("content")})
if "tool_calls" in msg and msg["tool_calls"]:
for tc in msg["tool_calls"]:
args = tc["function"]["arguments"]
parsed_args = json.loads(args) if isinstance(args, str) else args
content_blocks.append({"type": "tool_use", "id": tc["id"], "name": tc["function"]["name"], "input": parsed_args})
anthropic_messages.append({"role": "assistant", "content": content_blocks})
i += 1
elif role == "tool":
tool_results = []
while i < len(openai_messages) and openai_messages[i].get("role") == "tool":
t_msg = openai_messages[i]
tool_results.append({"type": "tool_result", "tool_use_id": t_msg.get("tool_call_id"), "content": t_msg.get("content")})
i += 1
anthropic_messages.append({"role": "user", "content": tool_results})
return system_prompt, anthropic_messages
`
Proses migrasi juga sangat sederhana:
sessions/{session_id}.json.CrossModelSessionAdapter untuk mengubah format OpenAI ke spesifikasi Anthropic.`text
[System Context Injection]
Percakapan ini adalah pekerjaan berkelanjutan yang dimigrasikan dari sesi sebelumnya (ID: sess_99812).
Hasil eksekusi alat dan konteks percakapan dengan model sebelumnya disertakan dalam riwayat pesan.
Lanjutkan pekerjaan dari titik berhenti berdasarkan hasil pemanggilan alat sebelumnya (tool_result) yang disajikan.
`
Tidak masalah jika server vendor tertentu rusak atau kebijakan layanan tiba-tiba berubah. Anda cukup beralih ke LLM lain dengan beberapa baris kode konversi sambil mempertahankan alur percakapan 100%. Kelangsungan bisnis pengembang solo baru dapat terjamin ketika Anda memegang data sesi secara fisik di direktori Anda sendiri.