About

Hi there, I'm Joana. I am mainly interested in topics related to mathematics, machine learning, artificial intelligence, and computer science. I am quite passionate about the application of mathematics to various fields. I love experimenting with new technologies and learning new things. I am currently exploring Large Language Models and their applications, and working as a Generative AI Developer.

My Projects

  • LLMs Journey Collection of various experiments with Large Language Models
  • PaliGemma Image Segmentation An API service for performing image segmentation based on text prompts using Google's PaliGemma 2 mix model, built with FastAPI, JAX/Flax, and Transformers.

Recent Posts all posts

Agno + MLX + Agent Lighting: Automatic Prompt Optimization for a Job-Search Agent
posted in Machine Learning

In the previous post, we built a dev.bg job-search agent with Agno and MLX that supports Human-in-the-Loop (HITL) control flow, meaning the agent pauses when it needs missing fields, asks for structured user input, and resumes from exactly where it left off. But there’s a recurring question in any agent project: How do we know the system prompt is actually good? You write something that works in your head, you tweak it a few times, and you ship it. But you’re essentially doing manual trial-and-error on natural language. In this post, we’ll do something more principled: use Microsoft’s Agent Lightning (agentlightning) to automatically optimize the system prompt for the same job-search agent. Instead of guessing the best prompt, we will let the model learn it.

Agno + MLX: Human-in-the-Loop User Control Flow for a Job-Search Agent
posted in Machine Learning

In my earlier posts, we first built a dev.bg job-search assistant by serving a local MLX model via mlx_lm.server, then using the OpenAI Python client to do tool calling. The client code owned the whole “tool loop”: call model → execute tool → append tool result → call model again, etc: A Job Postings Tool: A Guide to MLX-LM Server and Tool Use with the OpenAI Client. Later, we connected MLX to the Agno framework using theOpenAILike model adapter, and we saw how easy it is to give an Agno agent tools: Running Local Hugging Face Models with MLX-LM and the Agno Agentic Framework. In this post, we’ll rebuild the same agent with Agno and MLX, but this time we’ll focus on Human-in-the-Loop (HITL) control flow. Concretely, the agent can pause when it needs missing info, request that info via a structured user input (schema), continue from exactly where it left off.

Edge Functions vs. Serverless Functions
posted in Computer Science

This post covers the technical and theoretical differences between Edge Functions and traditional Serverless Functions (like AWS Lambda). We are going to explore how they differ in runtime architecture, performance characteristics, and show 2 simple use cases.

Running Local Hugging Face Models with MLX-LM and the Agno Agentic Framework
posted in Machine Learning

In this blog post we are going to show how to run a Hugging Face model locally using Apple's MLX-LM framework, connect it to the Agno agentic framework, and extend the agent's capabilities with custom tools. Agno is a modern and extensible agentic framework for Python. It is designed to be model-agnostic, allowing to seamlessly switch between different LLM providers and models. Medium post can be found here.

Python's os.environ vs os.getenv
posted in Python

Environment variables are key-value pairs that exist in the operating system's environment and can be accessed by programs running on that system. They are a way to configure applications without hardcoding values directly into the source code. Python provides several ways to work with environment variables through the os module. Two common methods are os.environ and os.getenv. While they might seem similar, they have different use cases and behaviors. Let's explore the differences and when to use each method effectively.