Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Agentic RAG and GraphRAG: When Classic RAG Is Not Enough
Classic RAG handles most questions whose answer sits in one place; on multi-hop questions an agent that uses retrieval as a tool found the right source but spent 3 calls, 11 times the tokens and 30 times the time. GraphRAG's first step produced fragmented entities with a small model, and long context with the whole corpus in the prompt tied classic RAG at 7/10.
Designing Tools for Agents: Names, Descriptions, Schemas, Error Messages and Tool Count
We compare twelve CRUD tools that mirror the API with two task-focused tools on the same requests with qwen3:4b: thirteen times the tokens, a book that can't be found and an agent that adds the wrong book and says "added". Why a schema isn't validation, human-readable output, messages that explain empty results, name collisions and side-effecting tools.
Writing an Agent Loop from Scratch: Plan, Tool Call, Observation and Stop Condition
We write an agent loop in C# without a framework: returning tool results and errors to the model, step/token/time budgets, blocking repeated calls and tracing every step. A real run shows tokens piling up turn by turn; then we do the same job with FunctionInvokingChatClient and MAF's ChatClientAgent and compare what each layer abstracts away.
Taking Tool Calling to Production: FunctionInvokingChatClient Settings, DI Services and Approvals
In production, on whose behalf a tool runs comes from the session, not from the model's arguments, and irreversible actions wait for user approval through ApprovalRequiredAIFunction. With real runs we show an OrderTools class using scoped services, FunctionInvokingChatClient settings, separating tool errors from user errors, and an approval flow over two HTTP requests.
The Evolution of LLM APIs: From Completions to Tool Calling, Structured Outputs and MCP
The evolution of LLM APIs with verified dates, from the first text-continuing API to the chat format, from function calling to JSON mode and structured outputs, from reasoning parameters to the Model Context Protocol and agents. We see which example in the series each step maps to, and at the end of the series we build a bridge to the next AI series.
LLM Tool Calling (2): Microsoft.Extensions.AI and Safe Tools
We hand the tool loop to UseFunctionInvocation and AIFunctionFactory, then get to the real question: should every call the model asks for run? Taking authorization from the session, approval for tools that change data, argument validation with Zod and arguments the model makes up, with real qwen3:4b output.
LLM Tool Calling (1): The Model Doesn't Call Functions, It Asks for Calls
With tool calling the model runs no functions; it produces a call request and running it is up to your code. We send a raw tools request to Ollama's /api/chat endpoint with qwen3:4b, send the result back with the tool role and build the loop in TypeScript and in package-free C#.