AI SDK အသုံးပြု၍ Agent တည်ဆောက်ခြင်း - Tutorial A developer published a tutorial on building AI agents using TypeScript, Vercel AI SDK, and OpenRouter. The tutorial covers creating agents with tools, memory, subagents, and sequential/parallel execution. It provides step-by-step code examples for setting up a project with OpenRouter API and TypeScript. ဒီ သင်ခန်းစာမှာ TypeScript၊ Vercel AI SDK နဲ့ OpenRouter တို့ကို အသုံးပြုပြီး AI Agent တစ်ခုကို အတူတူ တည်ဆောက်ကြည့်ကြပါမယ်။ သင်ခန်းစာ ပြီးဆုံးသွားတဲ့အခါ - - Language model ခေါ်ယူခြင်း၊ - Agent Tool ဖန်တီးခြင်း၊ - Agent Tool အသုံးပြုခြင်း၊ - Agent Loop ဖန်တီးခြင်း၊ - Memory စနစ် ထည့်သွင်းခြင်း၊ - Subagent တည်ဆောက်ခြင်း၊ - Sequential Agents အကြောင်းနဲ့ - Parallel Agents အကြောင်းတို့ကို သိရှိသွားမှာပဲ ဖြစ်ပါတယ်။ အခြေခံအဆင့်တွေပဲ ဖြစ်လို့ Database တွေ၊ Vector Search တွေ၊ Web UI တွေ မပါသေးပါဘူး။ ပထမဆုံးအနေနဲ့ Agent ဆိုတာဘာလဲ၊ ဒီလို အကျဉ်းချုပ်မှတ်ပါ။ Agent ဆိုတာ ဘာလဲ?Agent ဆိုတာ AI Model တစ်ခုနဲ့အတူ ပေးထားတဲ့ Tool တွေကို ပေါင်းစပ် အသုံးပြုပြီး အဖြေတစ်ခု ထွက်လာတဲ့အထိ အဆင့်ဆင့် လုပ်ဆောင်သွားနိုင်တဲ့ ကွန်ပျူတာပရိုဂရမ်တစ်ခု ဖြစ်ပါတယ်။ အရင်ဆုံး မိမိနှစ်သက်ရာနေရာမှာ ပရောဂျက်တစ်ခု တည်ဆောက်ပါ။ package.json ဖိုင်တစ်ခုလည်း တည်ဆောက်လိုက်ပါ။ ဥပမာ - mkdir my-agent cd my-agent npm init -y ဆက်လက်ပြီး လိုအပ်တဲ့ Package တွေကို Install လုပ်ပါ - npm install ai @openrouter/ai-sdk-provider zod dotenv အဓိကနည်းပညာအဖြစ် အသုံးပြုလိုတဲ့ Vercel AI SDK နဲ့ OpenRouter Provider တို့ကို ထည့်သွင်းလိုက်တာပါ။ နောက်ထပ် လိုအပ်တဲ့ Development Dependencies တွေကိုလည်း ထပ်ပြီး Install လုပ်ပါ - npm install -D typescript tsx @types/node TypeScript ကို အသုံးပြုရေးသားမှာဖြစ်လို့ သက်ဆိုင်တာတွေ ထည့်သွင်းလိုက်တာပါ။ OpenRouter အတွက် API Key လိုအပ်ရင် ဒီလိပ်စာမှာ ရယူလို့ရပါတယ်။ ဆက်လက်ပြီး ပရောဂျက်မှာ ပါဝင်မည့်ဖိုင်တွေ အပြည့်အစုံနဲ့ အခုလို Folder Structure တစ်ခုကို တည်ဆောက်လိုက်ပါ - my-agent/ ├── src/ │ ├── 01-basic.ts │ ├── 02-tool.ts │ ├── 03-agent-loop.ts │ ├── 04-memory.ts │ ├── 05-subagent.ts │ ├── 06-sequential.ts │ └── 07-parallel.ts ├── .env ├── .gitignore ├── package.json └── tsconfig.json TypeScript နဲ့ပတ်သက်ပြီး လိုအပ်တာတွေ အသင့်ဖြစ်သွားအောင် tsconfig.json ဖိုင်ထဲမှာ အောက်ပါအတိုင်း ရေးသားပေးပါ - { "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "types": "node" , "strict": true, "esModuleInterop": true }, "include": "src" } package.json ဖိုင်ထဲမှာ scripts တွေကို အခုလို ကြိုတင်ထည့်သွင်းထားလိုက်ပါ။ ကျန်တာတွေက ပြင်စရာမလိုပါဘူး၊ အသင့်ကူးယူလို့ရအောင်သာ အစုံထည့်ပေးလိုက်တာပါ - { "name": "my-agent", "version": "1.0.0", "type": "module", "scripts": { "basic": "tsx src/01-basic.ts", "tool": "tsx src/02-tool.ts", "loop": "tsx src/03-agent-loop.ts", "memory": "tsx src/04-memory.ts", "subagent": "tsx src/05-subagent.ts", "sequential": "tsx src/06-sequential.ts", "parallel": "tsx src/07-parallel.ts", "check": "tsc --noEmit" }, "dependencies": { "@openrouter/ai-sdk-provider": "latest", "ai": "latest", "dotenv": "latest", "zod": "latest" }, "devDependencies": { "@types/node": "latest", "tsx": "latest", "typescript": "latest" } } .env ဖိုင်ထဲမှာ OpenRouter API Key နဲ့ အသုံးပြုလိုတဲ့ Model တို့ကို အောက်ပါအတိုင်း ထည့်သွင်းပါမယ် - OPENROUTER API KEY=your-openrouter-api-key OPENROUTER MODEL=xiaomi/mimo-v2.5 နမူနာမှာ xiaomi/mimo-v2.5 ကို Model အနေနဲ့ ရွေးချယ်ထားပြီး၊ အခြားနှစ်သက်ရာ Model ကို အစားထိုးရွေးချယ်နိုင်ပါတယ်။ အခမဲ့ရတဲ့ Model တွေ သုံးပြီး စမ်းလို့လည်း ရပါတယ်။ ကိုယ်ရွေးချယ်တဲ့ Model က Tool Calling ရတဲ့ Model ဖြစ်ရမယ်ဆိုတာကိုတော့ သတိပြုပါ။ .gitignore ဖိုင်ထဲမှာလည်း အခုလို ရေးသားပေးပါ၊ မဖြစ်မနေ လိုအပ်ချက်မဟုတ်ပေမဲ့ .env လိုဖိုင်မျိုးတွေ မျှဝေတဲ့အခါ ပါမသွားစေဖို့ပါ - node modules dist .env ပထမဆုံးကုဒ်အနေနဲ့ src/01-basic.ts ဖိုင်ထဲမှာ အောက်ပါအတိုင်း ရေးပါမယ် - js import "dotenv/config"; import { generateText } from "ai"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; const apiKey = process.env.OPENROUTER API KEY; const modelName = process.env.OPENROUTER MODEL; if apiKey { throw new Error "OPENROUTER API KEY is missing." ; } if modelName { throw new Error "OPENROUTER MODEL is missing." ; } const openrouter = createOpenRouter { apiKey, } ; const model = openrouter modelName ; const result = await generateText { model, prompt: "Explain what an AI agent is in two simple sentences.", } ; console.log result.text ; ရေးပြီးသွားရင် Terminal ကနေ အောက်ပါအတိုင်း Run ပြီး စမ်းကြည့်လို့ ရပါပြီ။ လိုအပ်တဲ့ NPM Script ကို စောစောက ကြိုထည့်ခဲ့ပြီးသားပါ - npm run basic ဒီကုဒ်လေးက OpenRouter provider တစ်ခုကို တည်ဆောက်လိုက်တာ ဖြစ်ပါတယ် - js const openrouter = createOpenRouter { apiKey, } ; ဒီကုဒ်ကတော့ အသုံးပြုလိုတဲ့ model ကို ရွေးချယ်လိုက်တာပါ - js const model = openrouter modelName ; Model ဆီကို request လှမ်းပို့တဲ့အခါ အခုလို ပို့ရပါတယ် - js const result = await generateText { model, prompt: "...", } ; နောက်ဆုံးမှာ Model ဆီကနေ ရလာတဲ့ ရလဒ်ကို Console မှာပဲ ပြပေးလိုက်တာ ဖြစ်ပါတယ် - console.log result.text ; generateText function ကို အဓိကအားဖြင့် စာသားတွေ ထုတ်ခိုင်းဖို့ သုံးတာ ဖြစ်ပါတယ်။ Streaming လို လုပ်ဆောင်ချက်တွေ ထည့်သုံးမထားလို့၊ ရလဒ်ကို တစ်လုံးချင်းပြန်ထုတ်ပေးတာမျိုး မဟုတ်ဘဲ အားလုံးပြီးမှ တစ်ခါတည်း ပေးထားတာ ဖြစ်ပါတယ်။ အခုအဆင့်က Agent မဟုတ်သေးပါဘူး။ Model Request တစ်ခုသာ ရှိပါသေးတယ်။ သူ့ရဲ့ Flow က အောက်ပါအတိုင်း ဖြစ်ပါတယ် - Program ↓ Prompt ↓ Model ↓ Text response Tool ဆိုတာ Model က လှမ်းခေါ်ခွင့် ပြုထားတဲ့ ရိုးရိုး function တစ်ခုသာ ဖြစ်ပါတယ်။ အဓိကအားဖြင့် အစိတ်အပိုင်း ၃ ခု ပါဝင်ပါတယ် - - Description - Input Schema - Execution Function Schema နဲ့ Model ထည့်ပေးရမဲ့ Arguments သတ်မှတ်ပါတယ်။ Model က ပြန်ပေးတဲ့ arguments တွေ မှန်/မမှန်ကိုလည်း အလုပ်မလုပ်ခင် ဒီ Schema နဲ့ပဲ စစ်ဆေးပေးပါတယ်။ နမူနာအနေနဲ့ အလွန်ရိုးရှင်းလွယ်ကူတဲ့ Calculator Tool လေးတစ်ခုလောက် လုပ်ကြပါမယ်။ src/02-tool.ts ဖိုင်မှာ အောက်ပါအတိုင်း ရေးသား လိုက်ပါ - js import "dotenv/config"; import { generateText, tool } from "ai"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { z } from "zod"; const apiKey = process.env.OPENROUTER API KEY; const modelName = process.env.OPENROUTER MODEL; if apiKey || modelName { throw new Error "OPENROUTER API KEY and OPENROUTER MODEL must be configured.", ; } const openrouter = createOpenRouter { apiKey, } ; const model = openrouter modelName ; const calculatorTool = tool { description: "Perform basic arithmetic using two numbers. Use this instead of calculating mentally.", inputSchema: z.object { operation: z.enum "add", "subtract", "multiply", "divide" , a: z.number , b: z.number , } , execute: async { operation, a, b } = { switch operation { case "add": return { result: a + b, }; case "subtract": return { result: a - b, }; case "multiply": return { result: a b, }; case "divide": if b === 0 { return { error: "Cannot divide by zero.", }; } return { result: a / b, }; } }, } ; const result = await generateText { model, prompt: "Use the calculator to multiply 37 by 14. Do not calculate it yourself.", tools: { calculator: calculatorTool, }, } ; console.log "Text:" ; console.log result.text ; console.log "\nTool calls:" ; console.dir result.toolCalls, { depth: null, } ; console.log "\nTool results:" ; console.dir result.toolResults, { depth: null, } ; ရေးပြီးသွားရင် အခုလို Run ပြီး စမ်းကြည့်လို့ ရနေပါပြီ - npm run tool Model က ခေါ်ယူအသုံးပြုလို့ရမယ့် Tool ရဲ့ အမည် အခုလို သတ်မှတ်ပေးပါတယ် - tools: { calculator: calculatorTool, } Description ကို ကြည့်ပြီး Model က ဒီ tool ကို ဘယ်အချိန်မှာ သုံးသင့်လဲဆိုတာ အလိုအလျှောက် ဆုံးဖြတ်သွားမှာပါ၊ ဒါကြောင့် ကိုယ့် tool အကြောင်းကို သေချာရှင်းပြထားရမှာ ဖြစ်ပါတယ် - description: "Perform basic arithmetic using two numbers..." Input schema ကတော့ အထက်မှာ ပြောခဲ့သလို ဘယ်လို input မျိုး လက်ခံမလဲဆိုတာ စစ်ဆေးပေးပါတယ် - inputSchema: z.object { operation: z.enum "add", "subtract", "multiply", "divide", , a: z.number , b: z.number , } Execution function ကတော့ ပုံမှန် TypeScript function code ပါပဲ - js execute: async { operation, a, b } = { // deterministic application code } Model က ဒီ function ကို သူကိုယ်တိုင် တိုက်ရိုက်ဝင် run တာတော့ မဟုတ်ပါဘူး။ လုပ်ငန်းစဉ်က အောက်ပါအတိုင်း သွားတာပါ - 1. Model က calculator ကိုခေါ်ဖို့ တောင်းဆိုတယ်။ 2. AI SDK က arguments တွေကို စစ်ဆေးတယ်။ 3. AI SDK က calculatorTool.execute ကို run ပေးတယ်။ 4. AI SDK က ရလာတဲ့ tool ရလဒ်ကို Model ဆီ ပြန်ပို့ပေးပါတယ်။ ဒီနည်းနဲ့ Model က ခေါ်ချင်တဲ့ Tool ကို ပြန်ပေးပြီး SDK က တစ်ကယ်ခေါ် အလုပ်လုပ်ပြီး ရလဒ်ကို Model ထံ ပြန်ပေးလိုက်တာ ဖြစ်ပါတယ်။ စမ်းကြည့်တဲ့အခါ Tool ရလဒ် ထွက်လာပေမယ့် အဖြေ ပြန်မရတာမျိုး ကြုံရနိုင်ပါတယ်။ Model က အလုပ်လုပ်ပုံက Tool ကို လှမ်းခေါ်ဖို့ တောင်းဆိုလိုက်တာနဲ့တင် ပြီးဆုံးသွားလို့ ဖြစ်ပါတယ်။ Model request ↓ Tool call ↓ Tool executes ↓ Generation ends Model အနေနဲ့ ရလာတဲ့ Tool ရလဒ်ကို ကြည့်ပြီး ဆက်အလုပ်လုပ်ခွင့် မရလိုက်ပါဘူး။ ဒါကြောင့် Agent Loop တစ်ခု လိုအပ်လာတာ ဖြစ်ပါတယ်။ Agent Loop တစ်ခု စမ်းသပ်တည်ဆောက်ကြည့်ဖို့အတွက် src/03-agent-loop.ts ဖိုင်ထဲမှာ အောက်ပါအတိုင်း ရေးလိုက်ပါ - js import "dotenv/config"; import { generateText, stepCountIs, tool, } from "ai"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { z } from "zod"; const apiKey = process.env.OPENROUTER API KEY; const modelName = process.env.OPENROUTER MODEL; if apiKey || modelName { throw new Error "OPENROUTER API KEY and OPENROUTER MODEL must be configured.", ; } const openrouter = createOpenRouter { apiKey, } ; const model = openrouter modelName ; const calculatorTool = tool { description: "Perform basic arithmetic accurately.", inputSchema: z.object { operation: z.enum "add", "subtract", "multiply", "divide" , a: z.number , b: z.number , } , execute: async { operation, a, b } = { console.log Executing: ${operation} ${a}, ${b} ; switch operation { case "add": return { result: a + b }; case "subtract": return { result: a - b }; case "multiply": return { result: a b }; case "divide": if b === 0 { return { error: "Division by zero is not allowed." }; } return { result: a / b }; } }, } ; const result = await generateText { model, system: You are a careful assistant. Use the calculator whenever arithmetic is needed. After using a tool, explain the result clearly. , prompt: A shop sold 18 boxes. Each box contained 24 books. Then 35 books were returned. How many books remained sold? , tools: { calculator: calculatorTool, }, stopWhen: stepCountIs 5 , } ; console.log "\nFinal answer:" ; console.log result.text ; console.log "\nNumber of steps:" ; console.log result.steps.length ; for const index, step of result.steps.entries { console.log \nStep ${index + 1} ; console.log "Text:" ; console.log step.text || " no text " ; console.log "Tool calls:" ; console.dir step.toolCalls, { depth: null, } ; console.log "Tool results:" ; console.dir step.toolResults, { depth: null, } ; } ပြီးတဲ့အခါ အခုလို Run ကြည့်လိုက်ပါ - npm run loop Model က Tool ကို အသုံးပြုပြီး နောက်ဆုံးရလဒ်ထွက်တဲ့အထိ အလုပ်လုပ်သွားတာကို တွေ့ရမှာပဲ ဖြစ်ပါတယ်။ အထက်က Agent Loop ကုဒ်မှာ ဒီပိုင်းက အဓိက ဖြစ်ပါတယ် - stopWhen: stepCountIs 5 သူက SDK ကို Tool အလုပ်လုပ်လို့ ပြီးသွားရင်လည်း ရပ်မပစ်ဘဲ သတ်မှတ်ထားတဲ့ အကြိမ်ရေအထိ ဆက်ပြီး loop ပတ်ခိုင်းလိုက်တာ ဖြစ်ပါတယ်။ လုပ်ငန်းစဉ်က အောက်ပါအတိုင်း ဖြစ်သွားပါမယ် - Step 1: Model က multiply 18, 24 ကို လှမ်းခေါ်ပါတယ်။ Step 2: Model က ရလဒ် 432 ကို လက်ခံရရှိပြီး subtract 432, 35 ကို ထပ်ခေါ်ပါတယ်။ Step 3: Model က ရလဒ် 397 ကို လက်ခံရရှိပြီး နောက်ဆုံးအဖြေကို ပြန်ပေးသွားမှာပါ။ stopWhen ကြောင့် SDK က Tool ကို run တယ်၊ ရလဒ်ကို model ဆီ ပြန်ပေးပါတယ်၊ ပြီးတော့ Model က အဖြေထုတ်ပေးနိုင်တဲ့အထိ ဆက်တိုက် အလုပ်လုပ်သွားပါတယ်။ stepCountIs 5 လို့ ကန့်သတ်ထားလိုက်တာက အဆုံးမရှိ loop ပတ် မနေအောင် ကာကွယ်ပေးတာ ဖြစ်ပါတယ်။ ဒါဟာ ကျွန်တော်တို့ရဲ့ ပထမဆုံး တကယ့် Agent တစ်ခုပဲ ဖြစ်ပါတယ် - User task ↓ Model decides action ↓ Tool executes ↓ Result returns to model ↓ Model decides next action ↓ Final answer ကျွန်တော်တို့ရဲ့ Agent မှာ အဓိကအကျဆုံး အစိတ်အပိုင်း ၄ ခု ပါဝင်တာကို နောက်တစ်ကြိမ်လောက် သတိပြုကြည့်လိုက်ပါ - 1. Model 2. Instructions 3. Tools 4. Loop Code အနေနဲ့ အောက်ပါအတိုင်း ဖြစ်ပါတယ် - generateText { model, system, prompt, tools, stopWhen, } ; ဒီနေရာမှာ Memory ဆိုတာ မှတ်တမ်းတွေကို ယာယီသိမ်းဆည်းထားခြင်းသာ ဖြစ်ပါတယ်။ ဒါကြောင့် Program ပိတ်လိုက်ရင် ပျောက်သွားမှာဖြစ်ပြီး Database တွေဘာတွေနဲ့ သိမ်းထားတာ မဟုတ်ပါဘူး။ ကျွန်တော်တို့ လုပ်မှာက User နဲ့ Model ကြားထဲက အပြန်အလှန် ဆက်သွယ် အလုပ်လုပ်ထားတဲ့ အချက်အလက်တွေကို ခပ်ရိုးရိုးပဲ Array တစ်ခုနဲ့ သိမ်းထားလိုက်မှာ ဖြစ်ပါတယ်။ နမူနာစမ်းကြည့်ဖို့အတွက် src/04-memory.ts ဖိုင်မှာ အခုလိုရေးသားပေးပါ - js import "dotenv/config"; import { createInterface } from "node:readline/promises"; import { stdin as input, stdout as output } from "node:process"; import { generateText, stepCountIs, tool, type ModelMessage, } from "ai"; import { createOpenRouter } from "@openrouter/ai-sdk-provider"; import { z } from "zod"; const apiKey = process.env.OPENROUTER API KEY; const modelName = process.env.OPENROUTER MODEL; if apiKey || modelName { throw new Error "OPENROUTER API KEY and OPENROUTER MODEL must be configured.", ; } const openrouter = createOpenRouter { apiKey, } ; const model = openrouter modelName ; const calculatorTool = tool { description: "Perform basic arithmetic accurately.", inputSchema: z.object { operation: z.enum "add", "subtract", "multiply", "divide" , a: z.number , b: z.number , } , execute: async { operation, a, b } = { switch operation { case "add": return { result: a + b }; case "subtract": return { result: a - b }; case "multiply": return { result: a b }; case "divide": if b === 0 { return { error: "Cannot divide by zero." }; } return { result: a / b }; } }, } ; const memory: ModelMessage = ; async function runAgent userText: string : Promise