TanStack AI: چت هوش مصنوعی با استریم و ذخیرهٔ گفتگو
خلاصهٔ کاملتر
TanStack AI جدیدترین عضو خانوادهٔ TanStack هست؛ یه مجموعه کتابخونه برای اضافه کردن قابلیتهای هوش مصنوعی به اپها، با تایپهای خیلی دقیق مثل بقیهٔ ابزارهای TanStack. نویسنده تو قسمت اول این مجموعهٔ دوقسمتی چهار چیز پایه رو نشون میده: فرستادن درخواست به مدل، استریم جواب، ذخیرهٔ گفتگو (persistence) و ادامه دادن جواب نیمهکاره بعد از رفرش (resumability). قسمت دوم قراره سراغ structured output بره.
نویسنده همهٔ درخواستها رو از Vercel AI Gateway (یعنی یه درگاه واحد که به مدلهای شرکتهای مختلف وصل میشه) رد میکنه، برای همین کنار @tanstack/ai و @tanstack/ai-react آداپتور @tanstack/ai-vercel-gateway رو هم نصب میکنه. سمت سرور یه Server Route تو TanStack Start هست که پیامها رو با تابع chat به مدل میفرسته. سمت فرانت هم هوک useChat آرایهٔ messages، تابع sendMessage و isLoading رو میده. چون هر بار کل تاریخچه فرستاده میشه، گفتگو خودش ادامه پیدا میکنه.
برای استریم کردن جواب، یعنی اینکه متن همزمان با تولیدش کمکم نشون داده بشه، تغییرات خیلی کمه. سمت سرور stream: false حذف میشه و به جای toJsonResponse از toServerSentEventsResponse استفاده میشه که یه استریم SSE (یعنی Server-Sent Events، یه کانال یکطرفه از سرور به کلاینت) میسازه. سمت فرانت هم فقط connection عوض میشه:
const { messages, sendMessage, isLoading } = useChat({
connection: fetchServerSentEvents("/api/ai/chat-streaming"),
});برای ذخیرهٔ گفتگو پکیج @tanstack/ai-persistence لازمه. TanStack AI دیتابیس خاصی رو تحمیل نمیکنه و فقط یه قرارداد (contract) میده که با هر دیتابیسی پیادهش کنی. کدش رو هم یه AI Skill برات تولید میکنه که Drizzle رو هم میشناسه. نویسنده این روش رو شبیه ShadCN میدونه، فقط به جای CLI یه AI skill کد رو تو ریپو میذاره. البته امیدواره بعداً یه CLI درستوحسابی جاش بیاد.
بعد این store با withPersistence بهعنوان middleware به chat اضافه میشه و فرانت threadId و runId رو میفرسته. برای اینکه گفتگوی ذخیرهشده بعد از رفرش دوباره نشون داده بشه، یه هندلر GET روی همون مسیر لازمه که با reconstructChat اون thread رو برمیگردونه. نویسنده تأکید میکنه callback authorize حتماً باید منطق واقعی داشته باشه، وگرنه هر کی یه thread id رو حدس بزنه کل گفتگو رو میبینه.
اگه وسط تولید جواب صفحه رفرش بشه، اتصال SSE قطع میشه و جواب از دست میره. راهحل اینه که خروجی تو یه memoryStream روی سرور بافر بشه و هندلر GET اول چک کنه چیزی برای ادامه هست یا نه؛ اگه بود، با resumeServerSentEventsResponse از همونجا ادامه میده. به گفتهٔ نویسنده این روش برای لوکال خوبه، ولی تو پروداکشن یه بکاند durable لازمه تا بین چند سرور و بعد از ریاستارت هم کار کنه.
نکات کلیدی:
- پکیجهای اصلی: @tanstack/ai، @tanstack/ai-react، @tanstack/ai-vercel-gateway و @tanstack/ai-persistence
- استریم با toServerSentEventsResponse سمت سرور و fetchServerSentEvents سمت فرانت فعال میشه
- persistence فقط یه قراردادِ store هست و کدش رو یه AI Skill با پشتیبانی از Drizzle میسازه
- اگه callback authorize تو reconstructChat خالی بمونه، هر thread با حدس زدن id قابل خوندنه
- memoryStream برای لوکال کافیه؛ تو پروداکشن برای resumability یه durable stream لازمه
- isHydrating تو useChat برای نشون دادن لودینگ موقع بارگذاری thread ذخیرهشدهست




