DEV Community

RileyKim
RileyKim

Posted on

How I Built My First Real AI Agent with DeepSeek — A Bootcamp Grad's Guide...

So here's what happened: how I Built My First Real AI Agent with DeepSeek — A Bootcamp Grad's Guide for 2026

I had no idea what I was getting into when I first heard about AI agents. Seriously, six months ago I thought ChatGPT just... answered questions. That's it. One prompt in, one response out, done. Then someone at my bootcamp showed me a demo where an AI was booking flights, checking calendars, and sending emails — all by itself. I was shocked. My whole mental model of what LLMs could do just shattered.

So I went down a rabbit hole. I read blog posts. I watched way too many YouTube tutorials. And eventually I built my own working agent using DeepSeek's models through Global API. This is everything I learned along the way, written for people like me who are still figuring this stuff out.


Wait, What Even IS an AI Agent?

Okay, so the simplest way I can explain it: a regular chatbot is like asking a really smart friend a single question. An AI agent is like giving that friend a goal and watching them figure out how to accomplish it step by step.

Here's the comparison that finally made it click for me:

Normal Chatbot AI Agent
You ask one question, you get one answer You give a goal, it plans multiple steps to get there
Doesn't remember anything between sessions Keeps track of what it's done and what's left
Can't do anything in the real world Can call APIs, search the web, read files
One shot and you're done Thinks through the problem, checks its work, tries again

A real example that blew my mind: instead of just asking "what's the weather in Beijing right now" and getting a text reply, an agent would actually figure out it needs to hit a weather API, make the call, read the response, and then turn that data into something a human would actually want to hear.

DeepSeek's models — specifically deepseek-v4-flash and deepseek-reasoner — handle this stuff natively through something called function calling. That's the secret sauce.


Getting Set Up (The Part I Always Skip and Then Regret)

Before you can build anything cool, you need an API key. I grabbed mine from Global API — it's just a 32-character hexadecimal string, nothing fancy. If you're going to follow along with my code, you'll need one too.

For Python folks:

pip install openai httpx
Enter fullscreen mode Exit fullscreen mode

And here's the basic client setup that I use for literally everything now:

from openai import OpenAI

# Point this at Global API's proxy endpoint
client = OpenAI(
    api_key="YOUR_DEEPSEEK_API_KEY",
    base_url="https://global-apis.com/v1"
)

def chat(messages: list[dict], model: str = "deepseek-v4-flash") -> str:
    """Send a chat request to DeepSeek through Global API."""
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0.7,
        max_tokens=2048
    )
    return response.choices[0].message.content

# Quick sanity check
messages = [{"role": "user", "content": "Say hello in one sentence."}]
print(chat(messages))
Enter fullscreen mode Exit fullscreen mode

If you're more of a JavaScript person, here's the same thing in Node:

// my_first_agent/client.js
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'YOUR_DEEPSEEK_API_KEY',
  baseURL: 'https://global-apis.com/v1'
});

async function chat(messages, model = 'deepseek-v4-flash') {
  const response = await client.chat.completions.create({
    model,
    messages,
    temperature: 0.7,
    max_tokens: 2048
  });
  return response.choices[0].message.content;
}

// Quick sanity check
const messages = [{ role: 'user', content: 'Say hello in one sentence.' }];
console.log(await chat(messages));
Enter fullscreen mode Exit fullscreen mode

Honestly, this part alone saved me hours of debugging. Using Global API's base URL means I don't have to worry about regional routing or weird authentication quirks — it just works.


Function Calling: The Actual Magic Part

This is where I spent the most time staring at my screen going "wait, how does it know to do that?" Function calling is basically a way for the model to say "hey, I need you to run this specific function with these specific arguments" instead of just spitting out text.

Here's the flow in plain English:

  1. User asks something like "what's Bitcoin at right now?"
  2. The model looks at its available tools and decides "I need the get_bitcoin_price tool"
  3. It returns a structured JSON response saying exactly which tool to call and what to pass in
  4. Your code runs that tool (probably an API call)
  5. You feed the result back to the model
  6. The model turns that raw data into a human-friendly answer

When I first saw this working I actually said "whoa" out loud. Like, the model wasn't just hallucinating a price — it was asking my code to fetch a real one. That's the difference between a chatbot and an agent.


Letting the Agent Run in a Loop

Okay so here's where things get spicy. The real power of agents isn't a single function call — it's chaining them together. The model needs to be able to:

  • Look at the conversation so far
  • Decide if it needs more information
  • Pick the right tool if it does
  • Evaluate the result
  • Keep going until the original goal is solved

This is what people call the "agent loop" and honestly, writing one from scratch made me feel like a wizard. Here's the Python version I ended up with after a lot of trial and error:

# my_first_agent/agent_loop.py
from openai import OpenAI
import json

client = OpenAI(
    api_key="YOUR_DEEPSEEK_API_KEY",
    base_url="https://global-apis.com/v1"
)

# These are the tools our agent knows how to use
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"}
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Evaluate a math expression",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string", "description": "Math expression"}
                },
                "required": ["expression"]
            }
        }
    }
]

def get_weather(city: str) -> str:
    # In real life this would hit a real API
    return f"It's currently 72°F and sunny in {city}"

def calculate(expression: str) -> str:
    return str(eval(expression))

def run_agent(user_message: str, max_steps: int = 5) -> str:
    messages = [{"role": "user", "content": user_message}]

    for step in range(max_steps):
        response = client.chat.completions.create(
            model="deepseek-v4-flash",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )

        message = response.choices[0].message
        messages.append(message)

        # If the model didn't call any tools, we're done
        if not message.tool_calls:
            return message.content

        # Otherwise, run each tool the model asked for
        for tool_call in message.tool_calls:
            function_name = tool_call.function.name
            arguments = json.loads(tool_call.function.arguments)

            if function_name == "get_weather":
                result = get_weather(**arguments)
            elif function_name == "calculate":
                result = calculate(**arguments)
            else:
                result = f"Unknown function: {function_name}"

            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result
            })

    return "Agent hit max steps without finishing"

# Try it out
answer = run_agent("What's the weather in Tokyo and what's 15% of 847?")
print(answer)
Enter fullscreen mode Exit fullscreen mode

The thing that took me forever to figure out? You have to feed the tool's result back to the model as a tool role message with the matching tool_call_id. Miss that and nothing works and you get cryptic errors. I lost an entire Saturday to that.


The Cost Thing Nobody Warned Me About

Okay, real talk — I burned through way too much of my bootcamp credits before I figured out pricing. So let me save you the trouble.

Here's the deal with DeepSeek's models (and yes, these are the actual numbers from Global API):

  • deepseek-v4-flash is the cheap one. Like, really cheap. Around $0.14 per million input tokens and $0.28 per million output tokens.
  • deepseek-reasoner is the smarter one. It actually thinks before it answers, which is wild to watch. But it costs more — about $0.55 per million input tokens and $2.19 per million output tokens.

I was shocked when I ran the numbers on my first agent. A complex multi-step task that used deepseek-reasoner maybe 20 times? Cost me less than a coffee. A few cents. Compare that to GPT-4o which runs $5.00 per million input and $10.00 per million output and you'll understand why I basically stopped using anything else.

Here's the thing though — you don't always need the smart model. For simple tool calls and routing decisions, deepseek-v4-flash is plenty good and way cheaper. My pattern now is: use the cheap one for the loop logic and only escalate to the reasoner when I'm dealing with a hard problem.


Why Global API's Routing Matters (A Section I Wish Existed When I Started)

So one of the things Global API does that I didn't appreciate at first is called "GA Fusion routing." I know, sounds like marketing nonsense. But it actually saved my bacon during a hackathon.

Basically, when you send a request through Global API's endpoint, it figures out the fastest and cheapest path to actually reach DeepSeek's servers. Sometimes that means routing through different regions or using cached responses when the same query has been made recently.

In practice this means:

  • Fewer timeouts when DeepSeek's servers are having a bad day
  • Sometimes you get a response back in under 200ms when you'd otherwise wait 2 seconds
  • Lower costs because you're not always paying for full inference on identical requests

I noticed this when I was stress-testing my agent with 100 simultaneous requests. Half my friends' setups were choking. Mine was fine. That was enough for me.


A Real Example That Actually Does Something Useful

Let me show you what I built for my bootcamp final project. It's a research agent that takes a topic, searches for it, summarizes what it finds, and writes a short report. It uses two tools: a search function and a note-taking function.

# research_agent/agent.py
from openai import OpenAI
import json

client = OpenAI(
    api_key="YOUR_DEEPSEEK_API_KEY",
    base_url="https://global-apis.com/v1"
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "web_search",
            "description": "Search the web for information on a topic",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"}
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "save_note",
            "description": "Save a piece of information to the research notes",
            "parameters": {
                "type": "object",
                "properties": {
                    "fact": {"type": "string"},
                    "source": {"type": "string"}
                },
                "required": ["fact", "source"]
            }
        }
    }
]

notes = []

def web_search(query: str) -> str:
    # You'd plug in a real search API here
    fake_results = {
        "default": f"Three articles found about {query}: 'Introduction to {query}', '{query} explained', 'Why {query} matters in 2026'"
    }
    return fake_results.get("default", "No results")

def save_note(fact: str, source: str) -> str:
    notes.append({"fact": fact, "source": source})
    return "Note saved"

def research_agent(topic: str, max_steps: int = 8) -> str:
    messages = [
        {"role": "system", "content": f"You are a research assistant. Your goal is to gather 5 useful facts about: {topic}. Use web_search to find information and save_note to store each fact with its source. When you have 5 notes, write a summary."},
        {"role": "user", "content": f"Research this topic: {topic}"}
    ]

    for step in range(max_steps):
        response = client.chat.completions.create(
            model="deepseek-reasoner",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )

        message = response.choices[0].message
        messages.append(message)

        if not message.tool_calls:
            return message.content

        for tool_call in message.tool_calls:
            fn = tool_call.function.name
            args = json.loads(tool_call.function.arguments)

            if fn == "web_search":
                result = web_search(**args)
            elif fn == "save_note":
                result = save_note(**args)
            else:
                result = "Unknown tool"

            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": result
            })

    return f"Done. Collected {len(notes)} notes."

# Run it
report = research_agent("quantum computing")
print(report)
print("\nAll notes collected:")
for note in notes:
    print(f"- {note['fact']} (source: {note['source']})")
Enter fullscreen mode Exit fullscreen mode

Watching this thing run is genuinely mesmerizing. The model searches, saves a fact, searches again with a more specific query, saves another fact, and keeps going until it has enough material. It feels like watching someone actually do research.


Mistakes I Made So You Don't Have To

Since this is supposed to be the stuff I wish someone had told me, here's a quick list of things that bit me:

  1. Forgetting to append the assistant message to the conversation history. The model needs to see what it said last time or it gets confused.

  2. Using tool_choice="auto" when I actually meant "required". Auto lets the model decide if it even needs a tool. Sometimes you want to force it.

  3. Not setting a max step limit. Without one, a confused agent can loop forever and rack up charges. Always cap it.

  4. Confusing tool_call_id. Every tool call has its own ID and you need to use the right one in your response. Mismatch = silent failure.

  5. Trying to parse JSON from regular text responses instead of using the function calling API properly. Just don't. Use the structured tools.


What's Next If You Want to Go Deeper

Once you've got a basic agent loop working, the world kind of opens up. Here are things I'm exploring now:

  • Multi-agent systems where one agent delegates to others
  • Memory layers that persist across conversations
  • Streaming responses so users don't wait for the whole agent to finish
  • Safety guardrails that prevent agents from calling dangerous tools

But honestly, if you're at the same stage I was a few months ago — just start with one tool, one loop, and one goal. Get that working. Then add complexity. That's how I learned and it's how every other bootcamp grad I know learned too.


Final Thoughts

Look, I'm not going to pretend I'm an AI expert now. I'm not. But I went from "what's an LLM" to "I built an agent that does my research for me" in about six weeks. The tools are there. The pricing is absurdly good (especially if you go through Global API). The only thing standing between you and a working agent is actually sitting down and writing the code.

If you want to mess around with this yourself, Global API is what I used and I'd recommend checking it out. They have a dead-simple signup, the DeepSeek models work right out of the box, and their routing setup means you don't have to stress about reliability. That's it. That's the pitch. Go build something weird.

Top comments (0)