Free lesson · GenAI Application Engineering

சிந்தனை பட்ஜெட்டுடன் Gemini 2.5 Flash streaming adapter ஒன்றை உருவாக்குங்கள்

நீங்கள் adapters/gemini_stream.py இல் google.genai.Client ஐ (புதிய ஒருங்கிணைந்த SDK; காலாவதியான google-generativeai அல்ல) wrap செய்யும் GeminiStreamAdapter class ஒன்றை உருவாக்குவீர்கள். இந்த adapter, client.aio.models.generate_content_stream() ஐ அழைக்கும் stream_chat(messages, model, temperature, thinking_enabled) -> AsyncGenerator[StreamChunk, None] ஐ வெளிப்படுத்துகிறது. thinking_enabled True ஆக இருக்கும்போது, விரிவான பகுத்தறிவுக்காக config=GenerateContentConfig(thinking_config=ThinkingConfig(thinking_budget=1024)) ஐ அனுப்புங்கள்; False ஆக இருக்கும்போது, thinking_budget=0 என அமைக்கவும். ஒவ்வொரு GenerateContentResponse chunk க்கும், chunk.candidates[0].content.parts[0].text ஐப் பிரித்தெடுத்து StreamChunk க்கு map செய்யுங்கள். candidate.finish_reason ஐ FinishReason.SAFETY உடன் ஒப்பிட்டுச் சரிபார்த்து, StreamError ஐ emit செய்வதன் மூலம் safety blocks ஐக் கையாளுங்கள். இந்த adapter, Gemini role 'model' ஐ 'assistant' ஆக இயல்பாக்குகிறது (normalize). Configuration, Settings இலிருந்து GEMINI_API_KEY ஐப் படிக்கிறது.

Course: Full-Stack GenAI Applications · Chapter 1 · Chat Completion API with Streaming

Free to read — no subscription required.

அறிமுகம்

Gemini 2.5 Flash-ஐ ஒரு ஸ்ட்ரீமிங் chat endpoint-இல் ஒருங்கிணைக்கும்போது, வெறும் stream=True flag மட்டும் போதாது: Gemini இரண்டு தனித்தனி token ஸ்ட்ரீம்களைத் திருப்பித் தருகிறது — thought tokens மற்றும் text tokens — இவை இரண்டையும் ஒரே மாதிரியாகக் கையாண்டால், ஒன்று பயனருக்குத் தெரியும் chat bubble-களுக்குள் reasoning கசிந்துவிடும், அல்லது reasoning தேவையே இல்லாத query-களில் உங்கள் token பில்லை 2–3 மடங்கு அமைதியாக உயர்த்திவிடும். பயனர்கள் குழப்பமான வெளியீட்டைப் புகாரளிக்கும்போது அல்லது billing alert-கள் எதிர்பாராமல் தூண்டப்படும்போது, deploy செய்த பிறகுதான் பொறியாளர்கள் இதைப் பெரும்பாலும் கண்டறிகிறார்கள். இந்தப் பாடத்தின் முடிவில், ஒவ்வொரு request-க்கும் ஒரு ThinkingConfig-ஐ உருவாக்கவும், part.thought flag-ஐப் பயன்படுத்தி thought மற்றும் text token-களுக்கு இடையிலான phase எல்லையைக் கண்டறியவும், வகைப்படுத்தப்பட்ட வெளியீட்டை ஒரு FastAPI SSE endpoint வழியாக browser EventSource client-க்கு ஸ்ட்ரீம் செய்யவும் உங்களால் முடியும்.

முக்கிய சொற்கள்

  • ThinkingConfig: ஒவ்வொரு request அடிப்படையிலும் Gemini 2.5 Flash-இன் விரிவான reasoning நடத்தையைக் கட்டமைக்கும் ஒரு google.genai.types dataclass; இதன் thinking_budget field, தெரியும் text-ஐ வெளியிடுவதற்கு முன் model எத்தனை token-களை reasoning-க்குச் செலவிடலாம் என்பதைக் கட்டுப்படுத்துகிறது.
  • thinking_budget: reasoning token-களை வரம்பிடும், ThinkingConfig-க்குள் அனுப்பப்படும் ஒரு integer (0–24576). 0 thinking-ஐ முழுவதுமாக முடக்குகிறது (வேகமானது, மலிவானது); அதிக மதிப்புகள் பல-படி சிக்கல்களில் துல்லியத்திற்காக latency மற்றும் செலவைப் பரிமாற்றுகின்றன.
  • SSE (Server-Sent Events): ஒரு நீண்டகால HTTP response மீது server data: <json>\n\n frame-களை வெளியிடும் W3C-தரநிலை ஒருவழி ஸ்ட்ரீமிங் protocol. media_type="text/event-stream" உடன் FastAPI-இன் StreamingResponse, Gemini-இன் இரு-phase token ஸ்ட்ரீமை browser EventSource client-க்கு வழங்குவதற்கான நிலையான வழியாகும்.

கருத்துகள்

Gemini 2.5 Flash ஸ்ட்ரீமிங் adapter-இல் ஒவ்வொரு முடிவையும் இரண்டு யோசனைகள் இயக்குகின்றன: thinking_budget மதிப்பு ஒவ்வொரு request-க்கும் latency–செலவு–துல்லியம் பரிமாற்றத்தை அமைக்கிறது, மேலும் அதன் விளைவாக வரும் response ஒரு இரு-phase ஸ்ட்ரீம் (thought tokens, பின்னர் text tokens) ஆகும், அதை SSE frame-களை வெளியிடுவதற்கு முன் உங்கள் server வகைப்படுத்த வேண்டும். கீழே உள்ள துணைப்பிரிவு ஒரு budget-ஐ எப்படித் தேர்ந்தெடுப்பது என்பதை விளக்குகிறது; பின்னர் Code Walkthrough, phase மாற்றத்தை எப்படிக் கண்டறிவது மற்றும் ஒவ்வொரு chunk-ஐயும் சரியான SSE event வகைக்கு எப்படி வழிநடத்துவது என்பதைக் காட்டுகிறது.

Thinking Budget தேர்விற்கான நடைமுறைக் கருத்தாய்வுகள்

சரியான thinking budget-ஐத் தேர்ந்தெடுப்பது latency, செலவு மற்றும் பதிலின் தரத்தை சமநிலைப்படுத்துவதை உள்ளடக்கியது. thinking_budget 0 ஆக இருக்கும்போது, Gemini 2.5 Flash அதன் non-thinking முன்னோடிக்கு இணையான latency-உடன் பதிலளிக்கிறது—குறுகிய prompt-களுக்கு பொதுவாக 150–300ms time-to-first-token. thinking_budget=1024-இல், முதல் தெரியும் token தோன்றுவதற்கு முன் model சில நூறு மில்லி விநாடிகளை reasoning-க்குச் செலவிடுகிறது, இது உணரக்கூடிய தாமதத்தைச் சேர்க்கிறது, ஆனால் பல-படி சிக்கல்களில் துல்லியத்தைக் குறிப்பிடத்தக்க அளவில் மேம்படுத்துகிறது. thinking_budget=8192 அல்லது அதற்கு மேல், text token-கள் பாயத் தொடங்குவதற்கு முன் 2–5 விநாடிகள் "thinking" மௌனத்தை நீங்கள் கவனிக்கலாம், இதனால் பயனர்களைக் குழப்பாமல் இருக்க உங்கள் frontend ஒரு "reasoning..." காட்டியைக் காட்ட வேண்டியிருக்கும்.

thinking budget, token billing-ஐயும் பாதிக்கிறது. Thought token-கள் உங்கள் output token பயன்பாட்டில் கணக்கிடப்படுகின்றன, எனவே தனது budget-ஐ முழுமையாகப் பயன்படுத்தும் thinking_budget=8192 உடன் கூடிய ஒரு request, thinking முடக்கப்பட்ட அதே request-ஐ விட தோராயமாக 2–3 மடங்கு அதிகச் செலவாகும். இதனால்தான் ஒவ்வொரு request-க்கான கட்டுப்பாடு முக்கியம்: உங்கள் application எளிய query-களை (வாழ்த்துகள், உண்மைத் தேடல்கள்) thinking_budget=0 உடன் adapter வழியாக வழிநடத்தலாம், மேலும் சிக்கலான query-களை (code debugging, பல-படி கணிதம், planning பணிகள்) அதிக budget-களுக்கு இயங்குநிலையில் உயர்த்தலாம்.

thinking இயக்கப்பட்டிருக்கும்போது, Gemini API எந்தவொரு வெளிப்படையான temperature மதிப்பையும் நிராகரிக்கிறது: ஒரு பூஜ்ஜியமற்ற thinking budget உடன் temperature=0.3-ஐ அனுப்பினால், API உங்கள் மதிப்பைப் பயன்படுத்துவதற்குப் பதிலாக ஒரு validation error-ஐத் திருப்பித் தருகிறது. இதனால்தான் thinking_budget பூஜ்ஜியத்தை விட அதிகமாக இருக்கும்போதெல்லாம் adapter temperature field-ஐத் தவிர்க்கிறது, மேலும் thinking_budget=0 ஆக இருக்கும் non-thinking பாதையில் மட்டுமே temperature=1.0-ஐ அமைக்கிறது. இவ்வாறு நிபந்தனையுடன் temperature-ஐ அமைப்பது இரண்டு code பாதைகளையும் செல்லுபடியாக வைத்திருக்கிறது மற்றும் request தோல்வியடைவதைத் தடுக்கிறது.

Code Walkthrough

thinking_budget எப்படி latency–செலவு–துல்லியம் பரிமாற்றத்தைக் கட்டுப்படுத்துகிறது என்பதை இப்போது நீங்கள் புரிந்துகொண்டதால், செயலாக்கம் இரண்டு பணிகளாகச் சுருங்குகிறது: ஒவ்வொரு chunk-இன் part.thought flag-ஐப் பரிசோதித்து அதை thought token அல்லது தெரியும் token என வகைப்படுத்தும் ஒரு adapter-ஐ உருவாக்குங்கள், பின்னர் அந்த adapter-ஐ media_type="text/event-stream" உடன் ஒரு FastAPI StreamingResponse-இல் இணையுங்கள்.

Adapter: adapters/gemini_stream.py

GeminiStreamAdapter class ஒரு google.genai.Client-ஐ உருவாக்கி ஒரு stream_chat generator-ஐ வெளிப்படுத்துகிறது. அதன் உள்ளே, கோரப்பட்ட budget-க்கு அமைக்கப்பட்ட ThinkingConfig உடன் ஒரு GenerateContentConfig உருவாக்கப்படுகிறது. ஒரு முக்கியமான கட்டுப்பாடு: thinking_budget பூஜ்ஜியத்தை விட அதிகமாக இருக்கும்போது temperature field தவிர்க்கப்பட வேண்டும் — இரண்டும் அமைக்கப்பட்டால் API ஒரு validation error-ஐத் திருப்பித் தருகிறது. thinking_budget 0 ஆக இருக்கும்போது, temperature=1.0-ஐ வெளிப்படையாக அமைப்பது response பாணியை non-thinking பாதையுடன் சீராக வைத்திருக்கிறது. iteration loop-க்குள், part.thought தான் phase எல்லையைக் குறிக்கும் flag: reasoning phase-இன் போது True, தெரியும் text தொடங்கியவுடன் False.

Code snippetpython
1from google import genai 2from google.genai import types 3 4class GeminiStreamAdapter: 5 def __init__(self, api_key: str, model: str = "gemini-2.5-flash"): 6 self.client = genai.Client(api_key=api_key) 7 self.model = model 8 9 def stream_chat(self, message: str, thinking_budget: int = 0): 10 """Yields SSE-ready dicts: type='thinking'|'token'|'done'.""" 11 config_kwargs: dict = { 12 "thinking_config": types.ThinkingConfig(thinking_budget=thinking_budget), 13 } 14 if thinking_budget == 0: 15 config_kwargs["temperature"] = 1.0 16 config = types.GenerateContentConfig(**config_kwargs) 17 for chunk in self.client.models.generate_content_stream( 18 model=self.model, contents=message, config=config 19 ): 20 for part in chunk.candidates[0].content.parts: 21 if part.thought: 22 yield {"type": "thinking", "token": part.text} 23 else: 24 yield {"type": "token", "token": part.text} 25 yield {"type": "done"}

FastAPI SSE endpoint

endpoint, stream_chat-ஐ ஒரு async generator-இல் சுற்றி அதை StreamingResponse-க்கு அனுப்புகிறது. yield செய்யப்படும் ஒவ்வொரு dict-ம் ஒரு data: …\n\n frame-ஆக serialize செய்யப்படுகிறது — இது browser EventSource client இயல்பாகவே படிக்கும் W3C SSE wire format ஆகும். thinking_budget query parameter நேரடியாக request-இலிருந்து பாய்கிறது, எனவே அழைப்பவர்கள் route-ஐ மாற்றாமல் reasoning-ஐ இயக்கவோ முடக்கவோ முடியும்.

Code snippetpython
1import json 2from fastapi import FastAPI 3from fastapi.responses import StreamingResponse 4from adapters.gemini_stream import GeminiStreamAdapter 5 6app = FastAPI() 7adapter = GeminiStreamAdapter(api_key="your-api-key") 8 9@app.post("/chat/stream") 10async def chat_stream(message: str, thinking_budget: int = 0): 11 async def event_generator(): 12 for event in adapter.stream_chat(message, thinking_budget): 13 yield f"data: {json.dumps(event)}\n\n" 14 15 return StreamingResponse(event_generator(), media_type="text/event-stream")

POST /chat/stream?message=hello&thinking_budget=0 அனுப்புவது, குறைந்தது ஒரு {"type":"token","token":"..."} event-ஐ frame-களில் உள்ளடக்கிய மற்றும் இறுதியில் ஒரு {"type":"done"} frame உடன் முடிவடையும் text/event-stream response-ஐத் திருப்பித் தருகிறது என்பதை உறுதிப்படுத்துங்கள்.

துறைசார் பயன்பாடு

செய்ய வேண்டியவை மற்றும் செய்யக்கூடாதவை

செய்ய வேண்டியவை

  1. thinking_budget > 0 ஆக இருக்கும்போதெல்லாம் GenerateContentConfig-இலிருந்து temperature-ஐத் தவிர்க்கவும் — ஒரே request-இல் ThinkingConfig மற்றும் ஒரு temperature மதிப்பு இரண்டும் இருந்தால் Gemini API ஒரு validation error-ஐத் திருப்பித் தருகிறது; non-thinking request-கள் தொடர்ந்து சீராகச் செயல்பட, வெளிப்படையான temperature=1.0 ஒதுக்கீட்டை thinking_budget == 0 பாதைக்கு மட்டுமே ஒதுக்குங்கள்.
  2. yield செய்வதற்கு முன் token-களை வகைப்படுத்த ஒவ்வொரு chunk-இன் ஒவ்வொரு part-இலும் part.thought-ஐப் பரிசோதிக்கவும் — Gemini 2.5 Flash, thought token-களையும் தெரியும் text token-களையும் ஒரே ஸ்ட்ரீமில் கலந்து அனுப்புகிறது, மேலும் அவற்றைத் தனித்தனி SSE event வகைகளுக்கு ("thinking" vs "token") வழிநடத்துவதே, பயனருக்குத் தெரியும் chat bubble-இல் மூல reasoning தோன்றுவதைத் தடுக்கும் ஒரே வழி.
  3. StreamingResponse-இல் media_type="text/event-stream"-ஐ அமைத்து, yield செய்யப்படும் ஒவ்வொரு dict-ஐயும் ஒரு data: …\n\n frame-ஆக serialize செய்யவும் — content-type அல்லது இரட்டை-newline frame பிரிப்பானைத் தவிர்ப்பது W3C SSE ஒப்பந்தத்தை உடைக்கிறது, மேலும் browser EventSource client ஒவ்வொரு token-க்கும் event-களைத் தூண்டுவதற்குப் பதிலாக காலவரையின்றி buffer செய்யக் காரணமாகிறது.

செய்யக்கூடாதவை

  1. Gemini ஸ்ட்ரீமை ஒரே வேறுபடுத்தப்படாத token வரிசையாகக் கையாளாதீர்கள் — part.thought-ஐச் சரிபார்க்காமல் chunk.candidates[0].content.parts-ஐ iterate செய்வது thought token-களையும் தெரியும் token-களையும் ஒரே ஸ்ட்ரீமாகச் சுருக்கி, பல-வாக்கிய reasoning சங்கிலிகளை UI-க்குள் அமைதியாகக் கசியவிடுகிறது, மேலும் reasoning-இயக்கப்பட்ட request-களில் பயனருக்குத் தெரியும் வெளியீட்டை 2–3 மடங்கு பெருக்குகிறது.
  2. request-களுக்கு இடையே ஒரே hardcoded GenerateContentConfig-ஐப் பகிராதீர்கள் — startup-இல் ஒருமுறை config_kwargs-ஐ உருவாக்குவது, அழைப்பவர்கள் runtime-இல் query parameter வழியாக thinking_budget-ஐ மாற்றுவதைத் தடுக்கிறது; ஒவ்வொரு request-ம் தனித்தனியாக reasoning phase-ஐ இயக்கவோ முடக்கவோ முடியும் வகையில், ThinkingConfig ஒவ்வொரு அழைப்பிற்கும் stream_chat-க்குள் உருவாக்கப்பட வேண்டும்.
  3. SSE generator-இலிருந்து இறுதி {"type": "done"} frame-ஐ நிராகரிக்காதீர்கள் — ஸ்ட்ரீம் சுத்தமாக முடிந்துவிட்டது என்பதை அறிய browser EventSource client இந்த sentinel-ஐ நம்பியிருக்கிறது; அதை விட்டுவிடுவது ஏற்கனவே மூடப்பட்ட connection-ஐ client தொடர்ந்து poll செய்யும் நிலையில் விட்டுவிடுகிறது, மேலும் error நிலைகளை மெதுவான response-இலிருந்து வேறுபடுத்த முடியாததாக்குகிறது.

3 hands-on labs come with this lesson — real code, in a cloud IDE. Create a free account to run them. No card.

Free account · no card · straight to the labs

Or get the full path — from

Listen to this lesson

Audio overviews of this lesson's labs and its chapter, from GenBodha Bytes.

More free lessons in Full-Stack GenAI Applications

All free lessons in GenAI Application Engineering →