AI Agents

How to Build Your First AI Agent with JavaScript/TypeScript

A step-by-step tutorial for building an autonomous AI agent using TypeScript, the OpenAI API, and tool calling. By the end, you'll have a working agent that can browse the web and execute tasks.

A
AI Agents Hubยท2025-03-09ยท4 min readยท646 words

Builder of AI agents, crypto trading bots, and open-source automation tools. Sharing practical guides on how to build, deploy, and profit from AI and DeFi technology.

What We're Building

By the end of this tutorial, you'll have a working AI agent that can:

  • Accept natural language tasks
  • Use tools (web search, data analysis, API calls)
  • Reason through multi-step problems
  • Return structured results

Prerequisites

  • Node.js 18+
  • An OpenAI API key
  • Basic TypeScript knowledge

Step 1: Setup

mkdir my-ai-agent && cd my-ai-agent
npm init -y
npm install openai typescript ts-node @types/node
npx tsc --init

Step 2: Define Your Tools

Tools are functions the AI can call. Let's define a web search tool and a calculator:

// src/tools.ts
export const tools = [
  {
    type: "function" as const,
    function: {
      name: "web_search",
      description: "Search the web for current information",
      parameters: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description: "The search query"
          }
        },
        required: ["query"]
      }
    }
  },
  {
    type: "function" as const,
    function: {
      name: "calculate",
      description: "Perform mathematical calculations",
      parameters: {
        type: "object",
        properties: {
          expression: {
            type: "string",
            description: "Mathematical expression to evaluate"
          }
        },
        required: ["expression"]
      }
    }
  }
]

Step 3: Implement Tool Execution

// src/executor.ts
export async function executeTool(name: string, args: Record<string, string>): Promise<string> {
  switch (name) {
    case 'web_search':
      // In production, use a real search API like Serper or Tavily
      return `Search results for "${args.query}": [simulated results]`
    
    case 'calculate':
      try {
        const result = eval(args.expression) // Use mathjs in production
        return String(result)
      } catch (e) {
        return `Error: ${e}`
      }
    
    default:
      return `Unknown tool: ${name}`
  }
}

Step 4: The Agent Loop

This is the core of the agent โ€” the loop that keeps running until the task is complete:

// src/agent.ts
import OpenAI from 'openai'
import { tools } from './tools'
import { executeTool } from './executor'

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

interface Message {
  role: 'system' | 'user' | 'assistant' | 'tool'
  content: string
  tool_call_id?: string
  tool_calls?: OpenAI.Chat.ChatCompletionMessageToolCall[]
}

export async function runAgent(task: string): Promise<string> {
  const messages: Message[] = [
    {
      role: 'system',
      content: `You are a helpful AI agent. Use the available tools to complete tasks.
                Think step by step. When you have all the information needed, provide a final answer.`
    },
    {
      role: 'user',
      content: task
    }
  ]

  let iterations = 0
  const MAX_ITERATIONS = 10

  while (iterations < MAX_ITERATIONS) {
    iterations++
    console.log(`\n--- Iteration ${iterations} ---`)

    const response = await client.chat.completions.create({
      model: 'gpt-4o',
      messages: messages as OpenAI.Chat.ChatCompletionMessageParam[],
      tools,
      tool_choice: 'auto'
    })

    const choice = response.choices[0]
    const message = choice.message

    messages.push({
      role: 'assistant',
      content: message.content || '',
      tool_calls: message.tool_calls
    })

    // No tool calls = agent is done
    if (!message.tool_calls || message.tool_calls.length === 0) {
      return message.content || 'Task completed.'
    }

    // Execute each tool call
    for (const toolCall of message.tool_calls) {
      console.log(`Calling tool: ${toolCall.function.name}`)
      const args = JSON.parse(toolCall.function.arguments)
      const result = await executeTool(toolCall.function.name, args)
      console.log(`Result: ${result}`)

      messages.push({
        role: 'tool',
        tool_call_id: toolCall.id,
        content: result
      })
    }
  }

  return 'Max iterations reached. Task may be incomplete.'
}

Step 5: Run Your Agent

// src/index.ts
import { runAgent } from './agent'

async function main() {
  const task = process.argv[2] || "What is 15% of 2,450 and what is today's top crypto news?"
  
  console.log(`Task: ${task}\n`)
  const result = await runAgent(task)
  console.log(`\nFinal Answer:\n${result}`)
}

main().catch(console.error)

Run it:

OPENAI_API_KEY=sk-... npx ts-node src/index.ts "Research the top 3 crypto arbitrage strategies"

Making It More Powerful

Once you have the basics working, extend your agent with:

  • Memory โ€” Store conversation history in a vector DB (Pinecone, Qdrant)
  • More tools โ€” Add exchange APIs, database queries, code execution
  • Persistence โ€” Save and resume agent state
  • Multi-agent โ€” Spawn sub-agents for parallel tasks

Download the Full Template

Don't want to build from scratch? Download our production-ready AI agent template from the Tools page. It includes error handling, logging, rate limiting, and 10+ pre-built tools.

Related Articles