Thuta Learning
Local AI / Local LLM
IntermediateAIbeginner

Local AI App တစ်ခု တည်ဆောက်ခြင်း (JavaScript/TypeScript)

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Local AI App တစ်ခု တည်ဆောက်ခြင်း (JavaScript/TypeScript) concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram ကို ဖတ်ပြီး architecture ထဲမှာ data/request ဘယ်လိုစီးဆင်းသလဲ ခြေရာခံနိုင်ရန်
  • ကိုယ့် hardware/use case အတွက် ဘယ်လို ရွေးချယ်သင့်သလဲ ဆုံးဖြတ်နိုင်ရန်

နားလည်ထားရမယ့် အချက်

local model က HTTP API ကို ဖော်ပြထားတယ်ဆိုတာ သိထားခြင်းက real application တစ်ခုမှာ ဒီ call ဘယ်နေရာ ရှိသင့်လဲ သိမှသာ အသုံးဝင်ပါတယ်, ရိုးသားစွာ ပြောရရင် — browser ထဲမှာ တိုက်ရိုက် လုပ်တာက ဘယ်တော့မှ နီးပါးမလုပ်သင့်ပါဘူး။ typical local-AI app ငယ်တစ်ခုမှာ layer သုံးခု ရှိပါတယ်။

  • Frontend — user မြင်ရပြီး click နှိပ်ရတဲ့ အပိုင်းဖြစ်ပြီး plain HTML/JS (သို့) React လို framework နဲ့ တည်ဆောက်ထားပြီး user ရဲ့ browser ထဲမှာ run ပါတယ်။
  • Backend — သင်ထိန်းချုပ်တဲ့ server ငယ်တစ်ခုဖြစ်ပြီး Node.js/Express လိုမျိုးနဲ့ ရေးထားပြီး frontend ကနေ request တွေကို လက်ခံပြီး ဘာလုပ်မလဲ ဆုံးဖြတ်ပေးပါတယ်။
  • Local model API — Ollama (သို့) ဆင်တူ runtime တစ်ခုက serve လုပ်ထားတာဖြစ်ပြီး text ကို တကယ် generate လုပ်ပေးတဲ့ အပိုင်းပါ။

မှန်ကန်တဲ့ flow ကတော့ frontend က backend ကို ခေါ်, backend က local model API ကို ခေါ်, frontend က local model API ကို တိုက်ရိုက် ဘယ်တော့မှ မခေါ်ပါဘူး။ ဒါက ထပ်ခါထပ်ခါ တွေ့ရမယ့် concrete use case သုံးခုအတွက် အရေးကြီးပါတယ်။

  • Chat feature — backend က user message တစ်ခုစီကို model ဆီ forward လုပ်ပြီး reply ကို stream ပြန်ပို့ပါတယ်။
  • Summarizer — backend က document ရှည်ရှည်တစ်ခုကို frontend ကနေ ရရှိပြီး summarization prompt နဲ့ ပတ်ရစ်ကာ version တိုတိုတစ်ခု ပြန်ပေးပါတယ်။
  • Translator — backend က frontend ပို့လိုက်တဲ့ text နဲ့ target language ပတ်ပတ်လည် translation-specific system prompt ကို တည်ဆောက်ပါတယ်။

ရာအားလုံးကို သင့်ကိုယ်ပိုင် backend ကနေတဆင့် route ချထားခြင်းက input validate, request rate-limit, usage log, model ကို မရောက်ခင် authentication ထည့်ဖို့ နေရာတစ်ခု ပေးပါတယ်။ backend ကို ကျော်ပြီး local API ကို client-side JavaScript ကနေ တိုက်ရိုက် ခေါ်တာက သင့် laptop တစ်ခုတည်းပေါ်မှာ development လုပ်နေချိန်မှာတော့ ကောင်းကောင်း အလုပ်လုပ်ပါတယ်, ဒါပေမယ့် browser နဲ့ model server ဟာ trusted machine တစ်ခုတည်းဆိုတဲ့ assumption ကို တိတ်တဆိတ် ယူဆထားလို့ deploy လုပ်လိုက်တာနဲ့ ချက်ချင်း ပျက်သွားတတ်ပါတယ်။

text
SAFE VS INSECURE LOCAL AI ARCHITECTURE
--------------------------------------
------------------------------------------------------------
  SAFE PATTERN
  --------------------------------------------
  BROWSER  -->  YOUR BACKEND  -->  LOCAL MODEL API  -->  MODEL
  (frontend)    (validates,        (Ollama /api/chat)
                 rate-limits,
                 logs, auths)

  INSECURE ANTI-PATTERN -- do not do this
  --------------------------------------------
  BROWSER  ------------------------------->  LOCAL MODEL API
  (frontend)   calls the model API directly,   (exposed, open,
               no backend in between            unauthenticated)

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

internal translator tool ငယ်တစ်ခု တည်ဆောက်တယ်လို့ ယူဆကြည့်ပါ — coworker တစ်ယောက်က English text ကို web page ထဲ paste လုပ်, target language ရွေး, translation ပြန်ရတယ်။

Frontend က backend ကို ခေါ်ခြင်း

Frontend ဆိုတာ form ရိုးရိုးလေးတစ်ခုဖြစ်ပြီး submit လုပ်ရင် model ကို တိုက်ရိုက်မဟုတ်ဘဲ သင်ထိန်းချုပ်တဲ့ Node.js/Express server ပေါ်မှာ run နေတဲ့ သင့်ကိုယ်ပိုင် backend route, `/api/translate` လိုမျိုးဆီ `fetch()` POST request ပို့ပါတယ်။

Backend က translation prompt တည်ဆောက်ခြင်း

ဒီ backend route က text နဲ့ target language ကို လက်ခံပြီး translation-focused system prompt ကို ဖန်တီးပါတယ်။

Backend က local model API ကို ခေါ်ခြင်း

ပြီးမှသာ local model ရဲ့ `http://localhost:11434/api/chat` API ကို ခေါ်, JSON response ကို စောင့်, translated text ကို ထုတ်ယူပါတယ်။

Backend က frontend ဆီ response ပြန်ပို့ခြင်း

translated text ကို frontend ဆီ backend ရဲ့ ကိုယ်စား response အနေနဲ့ ပြန်ပို့ပါတယ်။

frontend က model ရဲ့ address, port, Ollama ပါဝင်ကြောင်းတောင် ဘယ်တော့မှ မသိပါဘူး; backend နဲ့ ဘယ်လို စကားပြောမလဲဆိုတာသာ သိပါတယ်။ ဒီ indirection ကပဲ user တစ်ယောက်စီအတွက် request limit ထည့်, translation ဘယ်တွေ တောင်းခဲ့လဲ log ချ, နောက်မှာ Ollama ကို local runtime တခြားနဲ့ ပြောင်း — ဒါအကုန်လုံးကို frontend code ကို လုံးဝ မထိပဲ လုပ်နိုင်ခွင့် ပေးပါတယ်။

Authentication မပါတဲ့ Local AI Server ကို ဘယ်တော့မှ Public ထုတ်မပေးပါနဲ့

public domain, reverse proxy, (သို့) port-forward တစ်ခုကို Ollama (သို့) llama.cpp ရဲ့ raw API ဆီ တိုက်ရိုက် ညွှန်းပြီး ပြီးပြီလို့ မယူဆပါနဲ့။ local server တွေမှာ default အနေနဲ့ built-in authentication လုံးဝ မပါပါဘူး — address ဆီ ရောက်နိုင်တဲ့ လူတိုင်းက request ပို့နိုင်, model generate ထုတ်တာကို ဘာပဲဖြစ်ဖြစ် ဖတ်နိုင်, သင့်စက်ပေါ်က compute cost (သို့) abuse ကို တိုးလာစေနိုင်ပါတယ်။ local AI feature တစ်ခုကို သင့်ကိုယ်ပိုင် machine အပြင်ဘက်ကနေ ရောက်နိုင်ဖို့ လိုအပ်ရင် သင့်ကိုယ်ပိုင် backend ကို ရှေ့ဆုံးမှာ ထားပြီး local model API ကို မခေါ်ခင် authentication, rate limiting, input validation ကို ဒီ backend ကနေ handle လုပ်ခိုင်းပါ — ဆန့်ကျင်ဘက် ဘယ်တော့မှ မလုပ်ပါနဲ့။

အတူတူ စမ်းရေးကြည့်မယ်

typescript
// backend route handler, e.g. Express: app.post("/api/translate", translateHandler)

interface TranslateRequestBody {
  text: string;
  targetLanguage: string;
}

interface OllamaChatResponse {
  message: { role: string; content: string };
}

const OLLAMA_CHAT_URL = "http://localhost:11434/api/chat";

async function translateHandler(
  req: { body: TranslateRequestBody },
  res: { status: (code: number) => { json: (body: unknown) => void } }
): Promise<void> {
  const { text, targetLanguage } = req.body;

  const systemPrompt =
    `You are a translation engine. Translate the user's text into ` +
    `${targetLanguage}. Reply with only the translated text.`;

  const payload = {
    model: "llama3.2",
    messages: [
      { role: "system", content: systemPrompt },
      { role: "user", content: text },
    ],
    stream: false,
  };

  try {
    const response = await fetch(OLLAMA_CHAT_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });

    if (!response.ok) {
      res.status(502).json({ error: "Local model server returned an error." });
      return;
    }

    const data = (await response.json()) as OllamaChatResponse;
    res.status(200).json({ translated: data.message.content });
  } catch (error) {
    res.status(503).json({ error: "Local model server is unreachable." });
  }
}

Run လုပ်လို့မရနိုင်ပါ

ဒီ code ဟာ ကိုယ်ပိုင် local AI server (ဥပမာ Ollama) ကို ခေါ်သုံးပါတယ် — ဒီ site ရဲ့ browser playground ကနေ visitor ရဲ့ စက်ပေါ်က local server ကို လှမ်းမခေါ်နိုင်ပါ (network access ကန့်သတ်ထားလို့ပါ)။ ကိုယ်တိုင် server run ထားတဲ့ terminal (သို့) file ထဲမှာ ဒီ code ကို run ပြီး စမ်းကြည့်ပါ။

You should see
ဒီ code ကို ဒီနေရာမှာ run မထားပါဘူး, local Ollama server run နေခြင်း နဲ့ HTTP framework ရဲ့ request/response object တွေ လိုအပ်ပြီး ဒီ environment ထဲမှာ နှစ်ခုစလုံး မရှိလို့ပါ။ တကယ့် deployment မှာဆိုရင် အောင်မြင်တဲ့ call တစ်ခုက `{ translated: '<translated text>' }` လိုမျိုး JSON body နဲ့ HTTP 200 ကို return ပြန်ပါတယ်, translated string အစစ်က model ကနေ လာတာဖြစ်လို့ hardcode (သို့) predict လုပ်သင့်တာ မဟုတ်ပါဘူး။ Ollama ဆီ မရောက်နိုင်ရင် handler က server process ကို crash မဖြစ်စေဘဲ HTTP 503 နဲ့ error message ကို response ပြန်ပါတယ်; Ollama က HTTP error status နဲ့ response ပြန်ရင် handler က HTTP 502 နဲ့ response ပြန်ပါတယ်။

၅ မိနစ် စမ်းကြည့်

`TranslateRequestBody` ထဲကို `sourceLanguage` field (optional, မပါရင် 'auto-detect' default ယူ) ထပ်ထည့်ပါ, `targetLanguage` နဲ့ အတူ system prompt ထဲ interpolate လုပ်ပါ, ပြီးရင် run မလုပ်ဘဲ 'good morning' ကို English ကနေ Burmese သို့ translate လုပ်တဲ့ `payload.messages` array က ဘယ်လို ကြည့်ရမလဲ ရေးကြည့်ပါ။

သတိလေးတစ်ချက်

development လုပ်နေတုန်း ‘ကိုယ့်စက်ပေါ်မှာ အလုပ်လုပ်တယ်’ လို့ ထင်ပြီး frontend JavaScript ကနေ local model API ကို တိုက်ရိုက် ခေါ်ပြီး code အတူတူကို production ဆီ deploy လုပ်ပစ်ခြင်း။

reverse proxy (သို့) port-forward နဲ့ local model ရဲ့ raw API ကို authentication, rate limiting ကိုယ်ပိုင် ရှေ့မှာ မထားဘဲ expose ပြုလုပ်ခြင်း။

MDN: Using the Fetch APILocal AI / Local LLM

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • development လုပ်နေတုန်း ‘ကိုယ့်စက်ပေါ်မှာ အလုပ်လုပ်တယ်’ လို့ ထင်ပြီး frontend JavaScript ကနေ local model API ကို တိုက်ရိုက် ခေါ်ပြီး code အတူတူကို production ဆီ deploy လုပ်ပစ်ခြင်း။
  • reverse proxy (သို့) port-forward နဲ့ local model ရဲ့ raw API ကို authentication, rate limiting ကိုယ်ပိုင် ရှေ့မှာ မထားဘဲ expose ပြုလုပ်ခြင်း။
  • Model (သို့) tool အသစ်တစ်ခုကို production/daily-use workflow ထဲ တိုက်ရိုက်မထည့်ခင် သေးငယ်တဲ့ scale နဲ့ အရင်စမ်းကြည့်ပါ။

လေ့ကျင့်ခန်း

`TranslateRequestBody` ထဲကို `sourceLanguage` field (optional, မပါရင် 'auto-detect' default ယူ) ထပ်ထည့်ပါ, `targetLanguage` နဲ့ အတူ system prompt ထဲ interpolate လုပ်ပါ, ပြီးရင် run မလုပ်ဘဲ 'good morning' ကို English ကနေ Burmese သို့ translate လုပ်တဲ့ `payload.messages` array က ဘယ်လို ကြည့်ရမလဲ ရေးကြည့်ပါ။

You'll know it worked when: ဒီ code ကို ဒီနေရာမှာ run မထားပါဘူး, local Ollama server run နေခြင်း နဲ့ HTTP framework ရဲ့ request/response object တွေ လိုအပ်ပြီး ဒီ environment ထဲမှာ နှစ်ခုစလုံး မရှိလို့ပါ။ တကယ့် deployment မှာဆိုရင် အောင်မြင်တဲ့ call တစ်ခုက `{ translated: '<translated text>' }` လိုမျိုး JSON body နဲ့ HTTP 200 ကို return ပြန်ပါတယ်, translated string အစစ်က model ကနေ လာတာဖြစ်လို့ hardcode (သို့) predict လုပ်သင့်တာ မဟုတ်ပါဘူး။ Ollama ဆီ မရောက်နိုင်ရင် handler က server process ကို crash မဖြစ်စေဘဲ HTTP 503 နဲ့ error message ကို response ပြန်ပါတယ်; Ollama က HTTP error status နဲ့ response ပြန်ရင် handler က HTTP 502 နဲ့ response ပြန်ပါတယ်။

Local AI App တစ်ခု တည်ဆောက်ခြင်း (JavaScript/TypeScript) | Thuta Learning