{"id":23,"date":"2026-09-25T22:20:57","date_gmt":"2026-09-25T16:50:57","guid":{"rendered":"https:\/\/truepythoneer.com\/blog\/?p=23"},"modified":"2026-09-26T00:11:52","modified_gmt":"2026-09-25T18:41:52","slug":"build-ai-agent-from-scratch-ollama-langgraph","status":"publish","type":"post","link":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/","title":{"rendered":"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced."},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Every \u201cbuild an AI agent\u201d tutorial today starts the same way: <code>pip install langchain<\/code>, five lines of code, a working demo. It\u2019s fast, and it\u2019s honest about almost nothing. You get a working agent without ever seeing what \u201cagent\u201d actually means. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I wanted to understand the mechanism, not just use it. So I built one from the ground up: raw HTTP calls to a local model, hand-written tool schemas, a hand-written agent loop, hand-written memory and retrieval. No framework, until I\u2019d built enough to know exactly what a framework would be replacing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Everything runs locally, on a laptop with an NVIDIA GPU, using Ollama and Qwen3. No cloud API. No data leaves the machine. For anyone working in a regulated industry, that last point matters more than it sounds.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Build AI Agent From Scratch, Layer by Layer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"1600\" height=\"1100\" class=\"wp-image-27\" src=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram.png\" alt=\"Architecture diagram showing how to build AI agent from scratch: LLM core, tool calling, memory, RAG, web access, and session persistence\" style=\"\" srcset=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram.png 1600w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram-300x206.png 300w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram-1024x704.png 1024w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram-768x528.png 768w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-architecture-diagram-1536x1056.png 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\" \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>The six parts and how they sit around the one loop that ties them together.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Environment.<\/strong> WSL2, Ubuntu 24.04, Ollama, an 8B parameter model running on GPU. Getting GPU passthrough working correctly inside a Linux VM on Windows is its own small education in virtualization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>LLM basics.<\/strong> Sending messages, streaming tokens, understanding what a \u201cthinking\u201d model actually costs you in latency (more tokens generated, not slower generation, an important distinction most people get wrong).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Tool calling.<\/strong> The core trick behind every \u201cagentic\u201d system: the model doesn\u2019t execute anything. It asks. Your code decides whether, and how, to act. That boundary is also where safety lives in any real system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The agent loop.<\/strong> This is the actual definition of \u201cagentic AI\u201d: call the model, run what it asks for, feed the result back, repeat until it stops asking. That\u2019s it. Everything else is scaffolding on top of this one idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Memory, RAG, and live web access.<\/strong> Three different kinds of \u201cknowing something,\u201d and the agent has to pick the right one for each question: a fact I told it directly, something in a document I gave it, or something on the live web. Getting the model to reliably choose the right source, once there were four competing tool families, turned out to be harder than getting any single one to work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Actually Taught Me Something<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Anyone can show you a working demo. What\u2019s harder to fake is what happened when things broke.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The GPU that lied about its own speed.<\/strong> Early on, tool calls that should take two seconds were taking thirty. <code>nvidia-smi<\/code> showed 99% GPU utilization, everything looked fine. The actual problem: the GPU was stuck in a low-power state after a driver update, running at a fraction of its memory clock while still reporting \u201cbusy.\u201d Full utilization and full speed are not the same thing, a lesson that generalizes well beyond GPUs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The model that confidently repeated its own mistake.<\/strong> I asked for the time in \u201cHyderabad\u201d (not a valid timezone name). The model guessed wrong, got an error back, and then told me its wrong guess was \u201cthe correct timezone,\u201d rather than admitting it didn\u2019t know. That\u2019s a small, contained example of a much bigger problem in deployed AI systems: models sound confident regardless of whether they\u2019re right. The fix wasn\u2019t \u201ctrust it less,\u201d it was engineering: better error messages that tell the model exactly what to do next, and a loop that gives it the chance to actually act on that correction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The bug that only showed up at scale.<\/strong> With one tool, tool selection is trivial. With two, it\u2019s still fine. With four tool families competing, general utilities, long-term memory, document search, and live web, the model started genuinely confusing \u201ca fact about me\u201d with \u201ca question about company policy.\u201d The fix was sharpening the system prompt to explicitly disambiguate the two. Nothing about any single tool was broken; the emergent behavior across all of them was.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The hallucination that wasn\u2019t.<\/strong> I once suspected the model had invented a very specific, correct-sounding fact from nothing. I was ready to write it up as a cautionary tale about grounding. It turned out my own logging code was truncating the console output to keep it readable, the model had genuinely retrieved that fact; I just hadn\u2019t looked at the full data before jumping to a conclusion. The real lesson: don\u2019t diagnose an AI system from a summary of its output. Look at what it actually saw.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why This Matters Beyond the Exercise<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For a fintech or any data-sensitive environment, the interesting result isn\u2019t \u201cAI agents are possible\u201d, everyone knows that. It\u2019s that a genuinely capable one can run <strong>entirely inside your own infrastructure<\/strong>: no data sent to a third party, no per-query API billing, and full visibility into every decision it makes, because you wrote the decision-making loop yourself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That last part is the real point. Frameworks are valuable once you know what they\u2019re doing for you. Used before that, they\u2019re a black box you\u2019re trusting without understanding, in a domain where \u201cwhy did the agent do that\u201d needs to have a real answer.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Part Two: I Rebuilt the Same Agent in LangGraph. Here\u2019s Exactly What It Replaced.<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once the hand-built version worked end to end, I did the obvious next thing: rebuilt it in LangGraph, one of the most widely used agent frameworks, and compared the two, piece by piece.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The result surprised me a little. LangGraph didn\u2019t touch a single design decision I\u2019d made. It removed boilerplate, and only boilerplate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Mapping<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>What I hand-wrote<\/th><th>What LangGraph replaced it with<\/th><\/tr><\/thead><tbody><tr><td>A <code>while<\/code> loop calling the model, checking for tool calls, running them, and looping<\/td><td>Two nodes (\u201cagent,\u201d \u201ctools\u201d) and one line: <code>add_conditional_edges(\"agent\", tools_condition)<\/code><\/td><\/tr><tr><td>A hand-written JSON schema for every tool function<\/td><td>Inferred automatically from the function\u2019s type hints and docstring, via a single <code>@tool<\/code> decorator<\/td><\/tr><tr><td>A dispatcher dictionary mapping tool names to functions<\/td><td><code>ToolNode(ALL_TOOLS)<\/code> \u2014 built in<\/td><\/tr><tr><td>~30 lines of code to serialize conversation history to JSON and load it back on restart<\/td><td>One line: <code>SqliteSaver.from_conn_string(\"sessions.db\")<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s it. That\u2019s the whole list.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What Did NOT Change<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">My system prompt, unchanged. My tool functions, unchanged, imported directly with no modification. My conversation-trimming policy (keep the last 6 exchanges, summarize the rest), unchanged, ported over as its own graph node, because deciding <em>how<\/em> to trim a conversation is a judgment call, not plumbing, and no framework should make that decision for you.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Proving the Persistence Claim, Not Just Asserting It<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The most concrete test: I closed the process entirely, opened a <strong>brand-new<\/strong> database connection against the same file, and asked the graph to recover its own state.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It came back with the full conversation, every message, in the right order, with zero lines of save\/load code written by me. The hand-built version needed a custom serializer just to handle the fact that a model\u2019s response isn\u2019t naturally JSON-safe. The framework version needed nothing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img loading=\"lazy\" decoding=\"async\" width=\"1734\" height=\"927\" class=\"wp-image-29\" src=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution.png\" alt=\"agent execution\" srcset=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution.png 1734w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution-300x160.png 300w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution-1024x547.png 1024w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution-768x411.png 768w, https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/agent-execution-1536x821.png 1536w\" sizes=\"auto, (max-width: 1734px) 100vw, 1734px\" \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Real terminal capture: the process exits (<code>\/exit<\/code>), a fresh <code>python3 main.py<\/code> run comes back with \u201cResuming thread \u2018default\u2019 (9 messages),\u201d and correctly answers \u201cWhat is my favorite country?\u201d from the earlier session, with no memory tool called, just the checkpointer.<\/em><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>The honest takeaway.<\/strong> If I\u2019d started with LangGraph on day one, I would have had a working agent in an afternoon, and understood almost none of it. The loop, the schema-to-function mapping, the persistence, all of it would have been invisible, working, and mysterious.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Building it by hand first meant that by the time I reached for the framework, I wasn\u2019t trusting a black box. I was looking at a table of exactly what it automated, and confirming, line by line, that none of it was hiding a decision I actually needed to make myself.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s the argument for learning the fundamentals before the framework: not that frameworks are bad, they\u2019re not, but that you can\u2019t tell the difference between \u201cthis abstraction is saving me time\u201d and \u201cthis abstraction is hiding a decision I don\u2019t understand\u201d until you\u2019ve built the thing it\u2019s abstracting at least once.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The full code for both versions, hand-built and LangGraph, is on GitHub: <a href=\"https:\/\/github.com\/truepythoneer\/local-ai-agent\">github.com\/truepythoneer\/local-ai-agent<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Tags: AI Agents, LLM, Ollama, GenAI, LangGraph, On-Prem AI, Engineering Leadership<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every \u201cbuild an AI agent\u201d tutorial today starts the same way: pip install langchain, five lines of code, a working demo. It\u2019s fast, and it\u2019s honest about almost nothing. You get a working agent without ever seeing what \u201cagent\u201d actually means. I wanted to understand the mechanism, not just use it. So I built one &#8230; <a title=\"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.\" class=\"read-more\" href=\"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/\" aria-label=\"Read more about I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":31,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[7,8,6,5,11,13,9,12,10],"class_list":["post-23","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-engineering","tag-agentic-ai","tag-ai-agents","tag-langgraph","tag-local-llm","tag-ollama","tag-on-prem-ai","tag-qwen3","tag-rag","tag-tool-calling"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"Build AI agent from scratch using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show exactly what it automates.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"shashijeevan\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"truepythoneer.com -\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Build an AI Agent From Scratch: Ollama + LangGraph Guide\" \/>\n\t\t<meta property=\"og:description\" content=\"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png\" \/>\n\t\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t\t<meta property=\"og:image:height\" content=\"900\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2026-09-25T16:50:57+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-09-25T18:41:52+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Build an AI Agent From Scratch: Ollama + LangGraph Guide\" \/>\n\t\t<meta name=\"twitter:description\" content=\"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.\" \/>\n\t\t<meta name=\"twitter:image\" content=\"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#blogposting\",\"name\":\"Build AI Agent From Scratch: Ollama + LangGraph Guide\",\"headline\":\"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.\",\"author\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/author\\\/shashijeevangmail-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-blog-image.png\",\"width\":1600,\"height\":900,\"caption\":\"hero blog image\"},\"datePublished\":\"2026-09-25T22:20:57+05:30\",\"dateModified\":\"2026-09-26T00:11:52+05:30\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#webpage\"},\"articleSection\":\"AI Engineering, agentic-ai, ai-agents, langgraph, local-llm, ollama, on-prem-ai, qwen3, rag, tool-calling\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"name\":\"AI Engineering\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"position\":2,\"name\":\"AI Engineering\",\"item\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/category\\\/ai-engineering\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#listItem\",\"name\":\"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#listItem\",\"position\":3,\"name\":\"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/category\\\/ai-engineering\\\/#listItem\",\"name\":\"AI Engineering\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#organization\",\"name\":\"truepythoneer.com\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/author\\\/shashijeevangmail-com\\\/#author\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/author\\\/shashijeevangmail-com\\\/\",\"name\":\"shashijeevan\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8ac5876e60511770c50cbc08ab945cf203b5763457042026acca3373b4e6a6a7?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"shashijeevan\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#webpage\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/\",\"name\":\"Build AI Agent From Scratch: Ollama + LangGraph Guide\",\"description\":\"Build AI agent from scratch using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show exactly what it automates.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/author\\\/shashijeevangmail-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/author\\\/shashijeevangmail-com\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-blog-image.png\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#mainImage\",\"width\":1600,\"height\":900,\"caption\":\"hero blog image\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/build-ai-agent-from-scratch-ollama-langgraph\\\/#mainImage\"},\"datePublished\":\"2026-09-25T22:20:57+05:30\",\"dateModified\":\"2026-09-26T00:11:52+05:30\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/\",\"name\":\"truepythoneer.com\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/truepythoneer.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Build AI Agent From Scratch: Ollama + LangGraph Guide","description":"Build AI agent from scratch using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show exactly what it automates.","canonical_url":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#blogposting","name":"Build AI Agent From Scratch: Ollama + LangGraph Guide","headline":"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.","author":{"@id":"https:\/\/truepythoneer.com\/blog\/author\/shashijeevangmail-com\/#author"},"publisher":{"@id":"https:\/\/truepythoneer.com\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","width":1600,"height":900,"caption":"hero blog image"},"datePublished":"2026-09-25T22:20:57+05:30","dateModified":"2026-09-26T00:11:52+05:30","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#webpage"},"isPartOf":{"@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#webpage"},"articleSection":"AI Engineering, agentic-ai, ai-agents, langgraph, local-llm, ollama, on-prem-ai, qwen3, rag, tool-calling"},{"@type":"BreadcrumbList","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/truepythoneer.com\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/#listItem","name":"AI Engineering"}},{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/#listItem","position":2,"name":"AI Engineering","item":"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/","nextItem":{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#listItem","name":"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced."},"previousItem":{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#listItem","position":3,"name":"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.","previousItem":{"@type":"ListItem","@id":"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/#listItem","name":"AI Engineering"}}]},{"@type":"Organization","@id":"https:\/\/truepythoneer.com\/blog\/#organization","name":"truepythoneer.com","url":"https:\/\/truepythoneer.com\/blog\/"},{"@type":"Person","@id":"https:\/\/truepythoneer.com\/blog\/author\/shashijeevangmail-com\/#author","url":"https:\/\/truepythoneer.com\/blog\/author\/shashijeevangmail-com\/","name":"shashijeevan","image":{"@type":"ImageObject","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/8ac5876e60511770c50cbc08ab945cf203b5763457042026acca3373b4e6a6a7?s=96&d=mm&r=g","width":96,"height":96,"caption":"shashijeevan"}},{"@type":"WebPage","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#webpage","url":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/","name":"Build AI Agent From Scratch: Ollama + LangGraph Guide","description":"Build AI agent from scratch using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show exactly what it automates.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/truepythoneer.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#breadcrumblist"},"author":{"@id":"https:\/\/truepythoneer.com\/blog\/author\/shashijeevangmail-com\/#author"},"creator":{"@id":"https:\/\/truepythoneer.com\/blog\/author\/shashijeevangmail-com\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#mainImage","width":1600,"height":900,"caption":"hero blog image"},"primaryImageOfPage":{"@id":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/#mainImage"},"datePublished":"2026-09-25T22:20:57+05:30","dateModified":"2026-09-26T00:11:52+05:30"},{"@type":"WebSite","@id":"https:\/\/truepythoneer.com\/blog\/#website","url":"https:\/\/truepythoneer.com\/blog\/","name":"truepythoneer.com","inLanguage":"en-US","publisher":{"@id":"https:\/\/truepythoneer.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"truepythoneer.com -","og:type":"article","og:title":"Build an AI Agent From Scratch: Ollama + LangGraph Guide","og:description":"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.","og:url":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/","og:image":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","og:image:secure_url":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","og:image:width":"1600","og:image:height":"900","article:published_time":"2026-09-25T16:50:57+00:00","article:modified_time":"2026-09-25T18:41:52+00:00","twitter:card":"summary_large_image","twitter:title":"Build an AI Agent From Scratch: Ollama + LangGraph Guide","twitter:description":"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.","twitter:image":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png"},"aioseo_meta_data":{"post_id":"23","title":"Build AI Agent From Scratch: Ollama + LangGraph Guide","description":"Build AI agent from scratch using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show exactly what it automates.","keywords":null,"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":"Build an AI Agent From Scratch: Ollama + LangGraph Guide","og_description":"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.","og_object_type":"default","og_image_type":"featured","og_image_url":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","og_image_width":"1600","og_image_height":"900","og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"featured","twitter_image_url":"https:\/\/truepythoneer.com\/blog\/wp-content\/uploads\/2026\/09\/hero-blog-image.png","twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":"Build an AI Agent From Scratch: Ollama + LangGraph Guide","twitter_description":"A hands-on build of a local AI agent using Ollama and Qwen3, no framework first, then rebuilt in LangGraph to show what it actually automates.","schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"BlogPosting","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"schemas":[],"titles":[],"descriptions":[],"socialPosts":{"email":{"subject":"","preview":"","content":""},"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2026-09-25 16:08:00","updated":"2026-09-25 18:56:08","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/truepythoneer.com\/blog\/\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/\" title=\"AI Engineering\">AI Engineering<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">\u00bb<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tI Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here\u2019s What Broke, and What the Framework Actually Replaced.\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/truepythoneer.com\/blog\/"},{"label":"AI Engineering","link":"https:\/\/truepythoneer.com\/blog\/category\/ai-engineering\/"},{"label":"I Built an AI Agent From Scratch, Then Rebuilt It in LangGraph. Here&#8217;s What Broke, and What the Framework Actually Replaced.","link":"https:\/\/truepythoneer.com\/blog\/build-ai-agent-from-scratch-ollama-langgraph\/"}],"_links":{"self":[{"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/posts\/23","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/comments?post=23"}],"version-history":[{"count":9,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions"}],"predecessor-version":[{"id":37,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions\/37"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/media\/31"}],"wp:attachment":[{"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/media?parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/categories?post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/truepythoneer.com\/blog\/wp-json\/wp\/v2\/tags?post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}