{"id":1592,"date":"2026-06-26T14:01:00","date_gmt":"2026-06-26T14:01:00","guid":{"rendered":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/"},"modified":"2026-06-28T08:59:27","modified_gmt":"2026-06-28T08:59:27","slug":"the-ai-agent-tech-stack-explained","status":"publish","type":"post","link":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/","title":{"rendered":"The AI Agent Tech Stack Defined"},"content":{"rendered":"<p><br \/>\n<\/p>\n<div id=\"\">\n<p>On this article, you&#8217;ll find out how the seven layers of a manufacturing AI agent stack match collectively, from the inspiration mannequin right down to deployment infrastructure.<\/p>\n<p>Matters we&#8217;ll cowl embrace:<\/p>\n<p>What every layer of the stack does, from the inspiration mannequin and orchestration framework by way of reminiscence, retrieval, instruments, observability, and deployment.<br \/>\nFind out how to implement every layer with working code, together with a stateful agent, a reminiscence system, a RAG pipeline, customized instruments, and tracing.<br \/>\nWhich mixture of applied sciences to make use of at every layer relying on whether or not you might be prototyping, scaling a startup, or working in an enterprise atmosphere.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-scaled.png\" alt=\"The AI Agent Tech Stack Explained\" width=\"800\" height=\"706\"\/><\/p>\n<h2>Introduction<\/h2>\n<p>Image this: you ask an AI agent to analysis three opponents, pull the pricing knowledge from every of their web sites, summarize the findings right into a structured report, and drop it in a Slack channel by 9am. You hit enter. Thirty seconds later, the report is there.<\/p>\n<p>What simply occurred beneath the hood will not be magic, and it isn&#8217;t one factor. It&#8217;s seven distinct layers of expertise working in sequence, every one dealing with a selected job, every one able to breaking in its personal particular manner. The mannequin on the prime will get all the eye. The six layers beneath it are what decide whether or not the agent truly works.<\/p>\n<p>In accordance with Gartner, 40% of enterprise purposes will likely be built-in with task-specific AI brokers by the tip of 2026, up from lower than 5% in 2025. That isn&#8217;t a gradual curve. That may be a near-vertical adoption line, and the engineers and technical leads chargeable for these deployments want to know the complete stack, not simply the layer they occur to personal.<\/p>\n<p>This text goes by way of every layer so as, from the inspiration mannequin right down to deployment infrastructure. By the tip, you&#8217;ll know what every bit is, why it exists, how the layers join to one another, and what to really use at every degree.<\/p>\n<h2>Layer 1: The Basis Mannequin<\/h2>\n<p>The inspiration mannequin is the cognitive core of an agent. It&#8217;s the place reasoning occurs, language is known, and choices about what to do subsequent are made. Every thing else within the stack is both feeding context into it or appearing on what it produces.<\/p>\n<p>In sensible phrases, your principal choices in 2026 are OpenAI\u2019s GPT-5.5, Anthropic\u2019s Claude Sonnet 4.6 (or Claude Opus 4.8 for tougher reasoning), Google\u2019s Gemini 3.1 Professional, and open-weight fashions like Meta\u2019s Llama 4 and Mistral Massive 3. Every has trade-offs value understanding earlier than you commit.<\/p>\n<p>GPT-5.5 is quick for on a regular basis calls and dependable at tool-calling, and it has probably the most mature ecosystem of integrations and the widest group of builders who&#8217;ve already run into and solved the sting circumstances you&#8217;ll encounter. Claude Sonnet 4.6 handles lengthy paperwork and nuanced instruction-following nicely at a lower cost level than Anthropic\u2019s Opus tier, which issues in document-heavy workflows; attain for Claude Opus 4.8 when a process wants deeper, longer-horizon reasoning. Gemini 3.1 Professional has a 1 million token context window, which is related in case your agent must course of massive codebases or prolonged data bases in a single cross. Open-weight fashions like Llama 4 offer you full management over deployment and knowledge residency, at the price of the infrastructure overhead of working them your self.<\/p>\n<p>There isn&#8217;t a longer a tough break up between \u201ccommonplace\u201d and \u201creasoning\u201d mannequin households, the best way there was in 2025; OpenAI, Anthropic, and Google have every folded reasoning right into a single mannequin that decides how lengthy to suppose. GPT-5.5 ships with adjustable reasoning effort ranges (from none as much as xhigh), and the identical applies to Claude\u2019s effort parameter and Gemini\u2019s pondering ranges. For many agent workflows, the default or low-effort setting is the precise selection: quick and low-cost. For duties that require cautious planning or mathematical reasoning, dialling the hassle degree up earns again its value in correctness.<\/p>\n<h2>Layer 2: The Orchestration Framework<\/h2>\n<p>If the inspiration mannequin is the mind, the orchestration framework is the nervous system. It handles the management stream: deciding what the agent ought to do subsequent, when it ought to name a software, the way it ought to deal with the consequence, and the way the entire reasoning loop stays coherent throughout a number of steps.<\/p>\n<p>The sample that almost all frameworks implement is known as ReAct (Reasoning and Appearing). The agent produces a thought, decides on an motion, executes the motion by way of a software, observes the consequence, after which thinks once more. This loop repeats till the agent produces a closing reply. It sounds easy. In apply, it&#8217;s the place most manufacturing failures happen: the agent calls the flawed software, will get caught in a loop, or fails to recognise when it has sufficient info to cease.<\/p>\n<p>LangChain is probably the most extensively adopted framework. It provides a big ecosystem of integrations and good documentation. The criticism that it provides an excessive amount of abstraction is truthful on the prototype stage, however much less related when you want the options that abstraction gives. LangGraph, constructed by the identical crew, is best fitted to stateful multi-agent workflows the place you want fine-grained management over the execution graph. In case your agent entails a number of specialists coordinating on a process, LangGraph is the cleaner selection.<br \/>\nCrewAI is designed particularly for multi-agent coordination. It allows you to outline brokers with roles, assign them duties, and have them collaborate inside a structured workflow. It&#8217;s higher-level than LangGraph and quicker to get working, however provides you much less management over the execution particulars. AutoGen, from Microsoft, takes a conversational method to multi-agent techniques. Brokers work together with one another by way of a message-passing interface, which makes the interplay logic very readable.<br \/>\nSemantic Kernel is Microsoft\u2019s enterprise-focused choice, with production-ready help for C#, Python, and Java. If you&#8217;re working in an enterprise atmosphere already working on the Microsoft stack, it suits naturally. LlamaIndex began as a doc ingestion and retrieval framework and has since grown right into a full agent framework, with significantly robust help for RAG-heavy workflows.<\/p>\n<p>The precise selection relies on what your agent must do. For a single-agent process runner: LangGraph or LangChain. For a coordinated crew of specialised brokers: CrewAI or AutoGen. For enterprise environments: Semantic Kernel. For document-heavy retrieval workflows: LlamaIndex.<\/p>\n<p>Here&#8217;s a minimal working agent in LangGraph that handles software use and maintains state.<\/p>\n<p>Stipulations:<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b3234c556339089\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\npip set up langgraph langchain-openai langchain-community python-dotenv<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">set up <\/span><span class=\"crayon-e\">langgraph <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">openai <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">group <\/span><span class=\"crayon-v\">python<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">dotenv<\/span><\/p>\n<\/div><\/div><\/div>\n<p>Find out how to run: Save as agent.py, add your OPENAI_API_KEY to a .env file, then run python agent.py<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b32362345264137\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\n# agent.py&#13;<br \/>\n# Minimal stateful agent with software use constructed on LangGraph&#13;<br \/>\n# Python 3.10+ | LangGraph 0.2+ | LangChain 0.3+&#13;<br \/>\n&#13;<br \/>\nimport os&#13;<br \/>\nfrom dotenv import load_dotenv&#13;<br \/>\nfrom langchain_openai import ChatOpenAI&#13;<br \/>\nfrom langchain_community.instruments import DuckDuckGoSearchRun&#13;<br \/>\nfrom langchain_core.messages import HumanMessage&#13;<br \/>\nfrom langgraph.prebuilt import create_react_agent&#13;<br \/>\n&#13;<br \/>\n# Load API key from .env file&#13;<br \/>\nload_dotenv()&#13;<br \/>\n&#13;<br \/>\n# Initialize the language mannequin&#13;<br \/>\n# temperature=0 for deterministic, targeted responses in agentic duties&#13;<br \/>\nllm = ChatOpenAI(&#13;<br \/>\n    mannequin=&#8221;gpt-5.5&#8243;,&#13;<br \/>\n    temperature=0,&#13;<br \/>\n    api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;)&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\n# Register the instruments the agent can use&#13;<br \/>\n# DuckDuckGoSearchRun requires no API key &#8212; good for improvement&#13;<br \/>\ninstruments = [DuckDuckGoSearchRun()]&#13;<br \/>\n&#13;<br \/>\n# create_react_agent from LangGraph wires collectively the LLM,&#13;<br \/>\n# instruments, and a built-in ReAct loop &#8212; no boilerplate required&#13;<br \/>\nagent = create_react_agent(llm, instruments)&#13;<br \/>\n&#13;<br \/>\n# Run the agent with a pattern question&#13;<br \/>\n# The agent will resolve whether or not to make use of a software primarily based on the query&#13;<br \/>\nconsequence = agent.invoke({&#13;<br \/>\n    &#8220;messages&#8221;: [HumanMessage(content=&#8221;What is the current market cap of Nvidia?&#8221;)]&#13;<br \/>\n})&#13;<br \/>\n&#13;<br \/>\n# The ultimate response is the final message within the messages checklist&#13;<br \/>\nprint(consequence[&#8220;messages&#8221;][-1].content material)<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"urvanov-syntax-highlighter-nums-content\" style=\"font-size: 12px !important; line-height: 15px !important;\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<\/div>\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-p\"># agent.py<\/span><\/p>\n<p><span class=\"crayon-p\"># Minimal stateful agent with software use constructed on LangGraph<\/span><\/p>\n<p><span class=\"crayon-p\"># Python 3.10+ | LangGraph 0.2+ | LangChain 0.3+<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">os<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">dotenv <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">load_dotenv<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_openai <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_community<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">instruments <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">messages <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">HumanMessage<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langgraph<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">prebuilt <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">create_react<\/span><span class=\"crayon-sy\">_<\/span>agent<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Load API key from .env file<\/span><\/p>\n<p><span class=\"crayon-e\">load_dotenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Initialize the language mannequin<\/span><\/p>\n<p><span class=\"crayon-p\"># temperature=0 for deterministic, targeted responses in agentic duties<\/span><\/p>\n<p><span class=\"crayon-v\">llm<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;gpt-5.5&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">temperature<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Register the instruments the agent can use<\/span><\/p>\n<p><span class=\"crayon-p\"># DuckDuckGoSearchRun requires no API key &#8212; good for improvement<\/span><\/p>\n<p><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># create_react_agent from LangGraph wires collectively the LLM,<\/span><\/p>\n<p><span class=\"crayon-p\"># instruments, and a built-in ReAct loop &#8212; no boilerplate required<\/span><\/p>\n<p><span class=\"crayon-v\">agent<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">create_react_agent<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Run the agent with a pattern question<\/span><\/p>\n<p><span class=\"crayon-p\"># The agent will resolve whether or not to make use of a software primarily based on the query<\/span><\/p>\n<p><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">agent<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">{<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;messages&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-e\">HumanMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;What is the current market cap of Nvidia?&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># The ultimate response is the final message within the messages checklist<\/span><\/p>\n<p><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;messages&#8221;<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">content material<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div><\/div><\/div>\n<p>What this does: create_react_agent handles the complete ReAct loop routinely. The agent receives the query, decides it wants present knowledge, calls the DuckDuckGo search software, reads the consequence, and synthesizes a closing reply. The messages checklist within the output accommodates the complete hint of that reasoning course of.<\/p>\n<h2>Layer 3: Reminiscence Methods<\/h2>\n<p>Statelessness is the default habits of any LLM. Each name begins from scratch, with no data of what got here earlier than except you explicitly cross that context in. For a one-shot query, that&#8217;s superb. For an agent that should observe a dialog, keep in mind a person\u2019s preferences, or construct on work it did yesterday, it&#8217;s a basic drawback.<\/p>\n<p>In accordance with Atlan\u2019s analysis on AI agent reminiscence, 95% of enterprise generative AI pilots delivered zero measurable ROI in 2025, with failure attributed to context readiness fairly than mannequin high quality. Brokers are failing not as a result of the mannequin is flawed, however as a result of the reminiscence layer will not be there.<\/p>\n<p>There are 4 varieties of reminiscence in a manufacturing agent, and every one handles a unique job:<\/p>\n<p>Working reminiscence (in-context) is the energetic context window. It holds the present dialog, any paperwork you&#8217;ve handed in, and the outcomes of current software calls. It&#8217;s quick and requires no infrastructure, however it&#8217;s session-bound. When the session ends, it&#8217;s gone.<br \/>\nEpisodic reminiscence is a log of prior interactions. As described within the analysis on reminiscence varieties, episodic reminiscence shops what occurred: timestamp, process, actions taken, final result. That is what permits an agent to reply \u201cWhat did we work on final Tuesday?\u201d or \u201cWhat did the person say about this undertaking three periods in the past?\u201c<br \/>\nSemantic reminiscence is factual data saved externally, together with definitions, entity relationships, and domain-specific information that the mannequin was not skilled on. That is the place your RAG pipeline feeds in (extra on that within the subsequent layer).<br \/>\nProcedural reminiscence encodes workflows and tool-use patterns, repeatable behaviors the agent ought to all the time comply with. This lives within the system immediate or a version-controlled instruction file, and it shapes each response the agent produces.<\/p>\n<p>Right here is  implement working and episodic reminiscence collectively utilizing LangChain\u2019s really helpful sample for LangChain 0.3+:<\/p>\n<p>Stipulations:<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b32368841938687\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\npip set up langchain langchain-openai python-dotenv<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">set up <\/span><span class=\"crayon-e\">langchain <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">openai <\/span><span class=\"crayon-v\">python<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">dotenv<\/span><\/p>\n<\/div><\/div><\/div>\n<p>Find out how to run: Save as reminiscence.py, guarantee your .env has OPENAI_API_KEY, then run python reminiscence.py<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b32370980490001\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\n# reminiscence.py&#13;<br \/>\n# Working reminiscence + episodic reminiscence for persistent agent context&#13;<br \/>\n# Makes use of the present LangChain 0.3+ sample (legacy ConversationBufferMemory is deprecated)&#13;<br \/>\n&#13;<br \/>\nimport os&#13;<br \/>\nimport json&#13;<br \/>\nfrom datetime import datetime&#13;<br \/>\nfrom dotenv import load_dotenv&#13;<br \/>\nfrom langchain_openai import ChatOpenAI&#13;<br \/>\nfrom langchain_core.messages import HumanMessage, AIMessage, SystemMessage, trim_messages&#13;<br \/>\n&#13;<br \/>\nload_dotenv()&#13;<br \/>\n&#13;<br \/>\nllm = ChatOpenAI(&#13;<br \/>\n    mannequin=&#8221;gpt-5.5&#8243;,&#13;<br \/>\n    temperature=0.2,&#13;<br \/>\n    api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;)&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 EPISODIC MEMORY STORE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# In manufacturing, exchange this checklist with a database (SQLite, Postgres, Redis).&#13;<br \/>\n# The construction right here: every episode is a dict with timestamp, person enter, and agent response.&#13;<br \/>\nepisodic_store: checklist[dict] = []&#13;<br \/>\n&#13;<br \/>\ndef save_episode(user_input: str, agent_response: str) -&gt; None:&#13;<br \/>\n    &#8220;&#8221;&#8221;Save a dialog flip to the episodic retailer.&#8221;&#8221;&#8221;&#13;<br \/>\n    episodic_store.append({&#13;<br \/>\n        &#8220;timestamp&#8221;: datetime.now().isoformat(),&#13;<br \/>\n        &#8220;person&#8221;: user_input,&#13;<br \/>\n        &#8220;agent&#8221;: agent_response&#13;<br \/>\n    })&#13;<br \/>\n&#13;<br \/>\ndef load_recent_episodes(n: int = 5) -&gt; str:&#13;<br \/>\n    &#8220;&#8221;&#8221;Retrieve the final N episodes as a formatted string for injection into context.&#8221;&#8221;&#8221;&#13;<br \/>\n    if not episodic_store:&#13;<br \/>\n        return &#8220;No prior dialog historical past.&#8221;&#13;<br \/>\n    current = episodic_store[-n:]&#13;<br \/>\n    return &#8220;n&#8221;.be part of(&#13;<br \/>\n        f&#8221;[{ep[&#8216;timestamp&#8217;]}] Person: {ep[&#8216;user&#8217;]} | Agent: {ep[&#8216;agent&#8217;]}&#8221;&#13;<br \/>\n        for ep in current&#13;<br \/>\n    )&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 WORKING MEMORY (IN-CONTEXT) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# We handle the message checklist ourselves and cross it by way of trim_messages&#13;<br \/>\n# earlier than every LLM name to remain throughout the mannequin&#8217;s context restrict.&#13;<br \/>\n# max_tokens=4000 leaves headroom for the mannequin&#8217;s response.&#13;<br \/>\nworking_memory: checklist = []&#13;<br \/>\n&#13;<br \/>\ndef chat(user_input: str) -&gt; str:&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    Ship a message to the agent.&#13;<br \/>\n    Episodic historical past is injected into the system immediate.&#13;<br \/>\n    Working reminiscence is trimmed earlier than every name to forestall context overflow.&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    # Inject episodic reminiscence into the system immediate so the mannequin has long-term context&#13;<br \/>\n    system = SystemMessage(content material=(&#13;<br \/>\n        &#8220;You&#8217;re a useful, context-aware assistant.nn&#8221;&#13;<br \/>\n        &#8220;Latest dialog historical past:n&#8221;&#13;<br \/>\n        f&#8221;{load_recent_episodes()}&#8221;&#13;<br \/>\n    ))&#13;<br \/>\n&#13;<br \/>\n    # Add the brand new person message to working reminiscence&#13;<br \/>\n    working_memory.append(HumanMessage(content material=user_input))&#13;<br \/>\n&#13;<br \/>\n    # Trim working reminiscence to remain throughout the context window&#13;<br \/>\n    # This compresses older messages fairly than dropping them totally&#13;<br \/>\n    trimmed = trim_messages(&#13;<br \/>\n        working_memory,&#13;<br \/>\n        max_tokens=4000,&#13;<br \/>\n        technique=&#8221;final&#8221;,              # Hold the latest messages&#13;<br \/>\n        token_counter=llm,            # Use the mannequin&#8217;s tokenizer for correct counts&#13;<br \/>\n        include_system=True,&#13;<br \/>\n        allow_partial=False&#13;<br \/>\n    )&#13;<br \/>\n&#13;<br \/>\n    # Name the mannequin with system context + trimmed working reminiscence&#13;<br \/>\n    response = llm.invoke([system] + trimmed)&#13;<br \/>\n    reply = response.content material&#13;<br \/>\n&#13;<br \/>\n    # Save the trade to episodic reminiscence and add the reply to working reminiscence&#13;<br \/>\n    save_episode(user_input, reply)&#13;<br \/>\n    working_memory.append(AIMessage(content material=reply))&#13;<br \/>\n&#13;<br \/>\n    return reply&#13;<br \/>\n&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\nif __name__ == &#8220;__main__&#8221;:&#13;<br \/>\n    print(chat(&#8220;My identify is Alex and I am constructing a RAG pipeline for authorized paperwork.&#8221;))&#13;<br \/>\n    print(chat(&#8220;What&#8217;s one of the best vector database for my use case?&#8221;))&#13;<br \/>\n    print(chat(&#8220;What did I let you know I used to be constructing?&#8221;))  # Assessments episodic recall<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"urvanov-syntax-highlighter-nums-content\" style=\"font-size: 12px !important; line-height: 15px !important;\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<p>51<\/p>\n<p>52<\/p>\n<p>53<\/p>\n<p>54<\/p>\n<p>55<\/p>\n<p>56<\/p>\n<p>57<\/p>\n<p>58<\/p>\n<p>59<\/p>\n<p>60<\/p>\n<p>61<\/p>\n<p>62<\/p>\n<p>63<\/p>\n<p>64<\/p>\n<p>65<\/p>\n<p>66<\/p>\n<p>67<\/p>\n<p>68<\/p>\n<p>69<\/p>\n<p>70<\/p>\n<p>71<\/p>\n<p>72<\/p>\n<p>73<\/p>\n<p>74<\/p>\n<p>75<\/p>\n<p>76<\/p>\n<p>77<\/p>\n<p>78<\/p>\n<p>79<\/p>\n<p>80<\/p>\n<p>81<\/p>\n<p>82<\/p>\n<p>83<\/p>\n<p>84<\/p>\n<p>85<\/p>\n<p>86<\/p>\n<p>87<\/p>\n<p>88<\/p>\n<p>89<\/p>\n<p>90<\/p>\n<p>91<\/p>\n<\/div>\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-p\"># reminiscence.py<\/span><\/p>\n<p><span class=\"crayon-p\"># Working reminiscence + episodic reminiscence for persistent agent context<\/span><\/p>\n<p><span class=\"crayon-p\"># Makes use of the present LangChain 0.3+ sample (legacy ConversationBufferMemory is deprecated)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">os<\/span><\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">json<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">datetime <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">datetime<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">dotenv <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">load_dotenv<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_openai <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">messages <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">HumanMessage<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">AIMessage<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">SystemMessage<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">trim_messages<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">load_dotenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-v\">llm<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;gpt-5.5&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">temperature<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0.2<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 EPISODIC MEMORY STORE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># In manufacturing, exchange this checklist with a database (SQLite, Postgres, Redis).<\/span><\/p>\n<p><span class=\"crayon-p\"># The construction right here: every episode is a dict with timestamp, person enter, and agent response.<\/span><\/p>\n<p><span class=\"crayon-v\">episodic_store<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">checklist<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">dict<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">save_episode<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">user_input<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">agent_response<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">None<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;Save a dialog flip to the episodic retailer.&#8221;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">episodic_store<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">append<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">{<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;timestamp&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">datetime<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">now<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">isoformat<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;person&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">user_input<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;agent&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">agent<\/span><span class=\"crayon-sy\">_<\/span>response<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">load_recent_episodes<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">n<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-t\">int<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;Retrieve the final N episodes as a formatted string for injection into context.&#8221;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-st\">not<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">episodic_store<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;No prior dialog historical past.&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">current<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">episodic_store<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">n<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;n&#8221;<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">be part of<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;[{ep[&#8216;timestamp&#8217;]}] Person: {ep[&#8216;user&#8217;]} | Agent: {ep[&#8216;agent&#8217;]}&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">for<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ep <\/span><span class=\"crayon-st\">in<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">current<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 WORKING MEMORY (IN-CONTEXT) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># We handle the message checklist ourselves and cross it by way of trim_messages<\/span><\/p>\n<p><span class=\"crayon-p\"># earlier than every LLM name to remain throughout the mannequin&#8217;s context restrict.<\/span><\/p>\n<p><span class=\"crayon-p\"># max_tokens=4000 leaves headroom for the mannequin&#8217;s response.<\/span><\/p>\n<p><span class=\"crayon-v\">working_memory<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">checklist<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">chat<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">user_input<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Ship a message to the agent.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Episodic historical past is injected into the system immediate.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Working reminiscence is trimmed earlier than every name to forestall context overflow.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0&#8220;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Inject episodic reminiscence into the system immediate so the mannequin has long-term context<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">system<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">SystemMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content material<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;You&#8217;re a useful, context-aware assistant.nn&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;Latest dialog historical past:n&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;{load_recent_episodes()}&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Add the brand new person message to working reminiscence<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">working_memory<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">append<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">HumanMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content material<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">user_input<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Trim working reminiscence to remain throughout the context window<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># This compresses older messages fairly than dropping them totally<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">trimmed<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">trim_messages<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">working_memory<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">max_tokens<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">4000<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">technique<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;final&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Hold the latest messages<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">token_counter<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Use the mannequin&#8217;s tokenizer for correct counts<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">include_system<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-t\">True<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">allow_partial<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-t\">False<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Name the mannequin with system context + trimmed working reminiscence<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">response<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">system<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">+<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">trimmed<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">reply<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">response<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-i\">content material<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Save the trade to episodic reminiscence and add the reply to working reminiscence<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">save_episode<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">user_input<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">reply<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">working_memory<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">append<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">AIMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content material<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">reply<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">reply<\/span><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">__name__<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">==<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;__main__&#8221;<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">chat<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;My identify is Alex and I am constructing a RAG pipeline for authorized paperwork.&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">chat<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;What&#8217;s one of the best vector database for my use case?&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-e\">chat<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;What did I let you know I used to be constructing?&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\">\u00a0\u00a0<\/span><span class=\"crayon-p\"># Assessments episodic recall<\/span><\/p>\n<\/div><\/div><\/div>\n<p>What this does: The episodic_store acts as a light-weight persistent log that will get summarized into the system immediate on each name. The working_memory checklist holds the in-session message historical past and will get trimmed by trim_messages earlier than every LLM name to forestall token overflow. The ultimate take a look at query, \u201cWhat did I let you know I used to be constructing?\u201d verifies that episodic recall is working appropriately even after the context window has moved on.<\/p>\n<h2>Layer 4: Vector Databases and Retrieval (RAG)<\/h2>\n<p>Basis fashions know loads, however they have no idea your paperwork. They weren&#8217;t skilled in your inner data base, your buyer help historical past, your proprietary analysis, or something that has occurred since their coaching cutoff. Retrieval-Augmented Technology (RAG) is the way you repair that.<\/p>\n<p>The idea is easy: as an alternative of attempting to suit a complete data base into the context window, you change your paperwork into numerical representations (embeddings), retailer them in a vector database, and retrieve solely probably the most related chunks at question time. The agent will get a context window filled with exactly the precise info fairly than every little thing you&#8217;ve ever written.<\/p>\n<p>The worldwide vector database market reached $3.2 billion in 2025 and is rising at 24% yearly, which displays how central retrieval has develop into to manufacturing AI techniques.<\/p>\n<p>The main choices every serve a unique use case:<\/p>\n<p>Pinecone is totally managed with zero infrastructure overhead. You pay for it, push vectors to it, and question it. At 100 million vectors, it maintains recall with out tuning. The precise selection once you need to ship and never take into consideration infrastructure.<br \/>\nWeaviate is open-source with a managed cloud choice, and it leads the sector on hybrid search combining vector similarity, key phrase matching (BM25), and metadata filtering in a single question. In case your retrieval wants require greater than pure semantic search, Weaviate handles it natively.<br \/>\nChroma is developer-first and runs regionally with no infrastructure. The 2025 Rust rewrite made it considerably quicker. It&#8217;s the proper selection for prototyping and small-to-medium manufacturing workloads the place developer expertise issues greater than scale.<br \/>\npgvector is a PostgreSQL extension that provides vector search to a database you might already be working. In case your crew already runs Postgres, pgvector is the lowest-friction path to manufacturing RAG. It handles hundreds of thousands of vectors with HNSW indexing and stays inside single-node PostgreSQL limits for many manufacturing workloads.<\/p>\n<div style=\"width: 810px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-A-horizontal-three-step-flow-diagram-showing-the-RAG-pipeline-1-scaled.png\" alt=\"A horizontal three-step flow diagram showing the RAG pipeline: Documents \u2192 Embeddings Model \u2192 Vector Database.\" width=\"800\" height=\"706\"\/><\/p>\n<p class=\"wp-caption-text\">A horizontal three-step stream diagram displaying the RAG pipeline: Paperwork \u2192 Embeddings Mannequin \u2192 Vector Database (click on to enlarge)<\/p>\n<\/div>\n<p>Here&#8217;s a working RAG pipeline utilizing Chroma and OpenAI embeddings.<\/p>\n<p>Stipulations:<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b32376519438789\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\npip set up langchain langchain-openai langchain-chroma langchain-text-splitters chromadb python-dotenv<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">set up <\/span><span class=\"crayon-e\">langchain <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">openai <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">chroma <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">textual content<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">splitters <\/span><span class=\"crayon-e\">chromadb <\/span><span class=\"crayon-v\">python<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">dotenv<\/span><\/p>\n<\/div><\/div><\/div>\n<p>Find out how to run: Save as rag_pipeline.py, add OPENAI_API_KEY to your .env, then run python rag_pipeline.py.<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b323ab261817079\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\n# rag_pipeline.py&#13;<br \/>\n# Minimal RAG pipeline: ingest paperwork \u2192 embed \u2192 retailer in Chroma \u2192 retrieve and reply&#13;<br \/>\n# Python 3.10+ | ChromaDB 0.5+ | LangChain 0.3+&#13;<br \/>\n&#13;<br \/>\nimport os&#13;<br \/>\nfrom dotenv import load_dotenv&#13;<br \/>\nfrom langchain_openai import ChatOpenAI, OpenAIEmbeddings&#13;<br \/>\nfrom langchain_chroma import Chroma&#13;<br \/>\nfrom langchain_text_splitters import RecursiveCharacterTextSplitter&#13;<br \/>\nfrom langchain_core.paperwork import Doc&#13;<br \/>\nfrom langchain_core.prompts import ChatPromptTemplate&#13;<br \/>\n&#13;<br \/>\nload_dotenv()&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 STEP 1: SAMPLE DOCUMENTS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# Change this checklist with actual paperwork out of your data base.&#13;<br \/>\n# In manufacturing, load from PDFs, databases, APIs, or file techniques.&#13;<br \/>\npaperwork = [&#13;<br \/>\n    Document(page_content=&#8221;Pinecone is a managed vector database optimized for fast, &#8220;&#13;<br \/>\n             &#8220;low-latency similarity search at scale. It handles infrastructure automatically &#8220;&#13;<br \/>\n             &#8220;and is best for production RAG when you don&#8217;t want to manage servers.&#8221;,&#13;<br \/>\n             metadata={&#8220;source&#8221;: &#8220;vector_db_guide&#8221;, &#8220;topic&#8221;: &#8220;pinecone&#8221;}),&#13;<br \/>\n&#13;<br \/>\n    Document(page_content=&#8221;Weaviate is an open-source vector database with native hybrid search &#8220;&#13;<br \/>\n             &#8220;support, combining BM25 keyword search with dense vector search in a single query. &#8220;&#13;<br \/>\n             &#8220;It can be self-hosted or used via Weaviate Cloud.&#8221;,&#13;<br \/>\n             metadata={&#8220;source&#8221;: &#8220;vector_db_guide&#8221;, &#8220;topic&#8221;: &#8220;weaviate&#8221;}),&#13;<br \/>\n&#13;<br \/>\n    Document(page_content=&#8221;Chroma is a developer-friendly, local-first vector database ideal for &#8220;&#13;<br \/>\n             &#8220;prototyping. The 2025 Rust rewrite significantly improved performance. &#8220;&#13;<br \/>\n             &#8220;Best for small-to-medium production workloads and local development.&#8221;,&#13;<br \/>\n             metadata={&#8220;source&#8221;: &#8220;vector_db_guide&#8221;, &#8220;topic&#8221;: &#8220;chroma&#8221;}),&#13;<br \/>\n&#13;<br \/>\n    Document(page_content=&#8221;pgvector is a PostgreSQL extension that adds vector similarity search &#8220;&#13;<br \/>\n             &#8220;to an existing Postgres database. With HNSW indexing, it handles millions of vectors &#8220;&#13;<br \/>\n             &#8220;at low latency. Best choice if your team already runs PostgreSQL in production.&#8221;,&#13;<br \/>\n             metadata={&#8220;source&#8221;: &#8220;vector_db_guide&#8221;, &#8220;topic&#8221;: &#8220;pgvector&#8221;}),&#13;<br \/>\n]&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 STEP 2: CHUNK THE DOCUMENTS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# Massive paperwork are break up into smaller chunks earlier than embedding.&#13;<br \/>\n# chunk_size=500 characters; chunk_overlap=50 preserves context throughout chunk boundaries.&#13;<br \/>\nsplitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)&#13;<br \/>\nchunks = splitter.split_documents(paperwork)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 STEP 3: EMBED AND STORE IN CHROMA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# OpenAIEmbeddings converts every chunk right into a high-dimensional vector.&#13;<br \/>\n# Chroma shops these vectors regionally within the .\/chroma_db listing.&#13;<br \/>\n# On subsequent runs, the prevailing retailer is loaded fairly than rebuilt.&#13;<br \/>\nembeddings = OpenAIEmbeddings(&#13;<br \/>\n    mannequin=&#8221;text-embedding-3-small&#8221;,   # Quick and cost-effective for many RAG duties&#13;<br \/>\n    api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;)&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\nvectorstore = Chroma.from_documents(&#13;<br \/>\n    paperwork=chunks,&#13;<br \/>\n    embedding=embeddings,&#13;<br \/>\n    persist_directory=&#8221;.\/chroma_db&#8221;   # Persist to disk so you do not re-embed on each run&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 STEP 4: RETRIEVAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# Converts the question into an embedding and finds probably the most comparable chunks.&#13;<br \/>\n# okay=3 returns the highest 3 most related chunks.&#13;<br \/>\nretriever = vectorstore.as_retriever(search_kwargs={&#8220;okay&#8221;: 3})&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 STEP 5: GENERATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\nllm = ChatOpenAI(&#13;<br \/>\n    mannequin=&#8221;gpt-5.5&#8243;,&#13;<br \/>\n    temperature=0,&#13;<br \/>\n    api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;)&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\n# The immediate tells the mannequin to make use of solely the retrieved context.&#13;<br \/>\n# This prevents the mannequin from hallucinating information not in your data base.&#13;<br \/>\nrag_prompt = ChatPromptTemplate.from_messages([&#13;<br \/>\n    (&#8220;system&#8221;,&#13;<br \/>\n     &#8220;Answer the question using only the provided context. &#8220;&#13;<br \/>\n     &#8220;If the answer isn&#8217;t in the context, say so clearly.nn&#8221;&#13;<br \/>\n     &#8220;Context:n{context}&#8221;),&#13;<br \/>\n    (&#8220;human&#8221;, &#8220;{question}&#8221;)&#13;<br \/>\n])&#13;<br \/>\n&#13;<br \/>\ndef reply(query: str) -&gt; str:&#13;<br \/>\n    &#8220;&#8221;&#8221;Retrieve related chunks and generate a grounded reply.&#8221;&#8221;&#8221;&#13;<br \/>\n    # Retrieve probably the most related doc chunks for this query&#13;<br \/>\n    retrieved_docs = retriever.invoke(query)&#13;<br \/>\n&#13;<br \/>\n    # Mix the retrieved chunks right into a single context block&#13;<br \/>\n    context = &#8220;nn&#8221;.be part of(doc.page_content for doc in retrieved_docs)&#13;<br \/>\n&#13;<br \/>\n    # Construct and invoke the immediate with the query and retrieved context&#13;<br \/>\n    immediate = rag_prompt.invoke({&#8220;context&#8221;: context, &#8220;query&#8221;: query})&#13;<br \/>\n    response = llm.invoke(immediate)&#13;<br \/>\n    return response.content material&#13;<br \/>\n&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\nif __name__ == &#8220;__main__&#8221;:&#13;<br \/>\n    q = &#8220;Which vector database ought to I exploit if I already run PostgreSQL?&#8221;&#13;<br \/>\n    print(f&#8221;Q: {q}nA: {reply(q)}&#8221;)<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"urvanov-syntax-highlighter-nums-content\" style=\"font-size: 12px !important; line-height: 15px !important;\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<p>51<\/p>\n<p>52<\/p>\n<p>53<\/p>\n<p>54<\/p>\n<p>55<\/p>\n<p>56<\/p>\n<p>57<\/p>\n<p>58<\/p>\n<p>59<\/p>\n<p>60<\/p>\n<p>61<\/p>\n<p>62<\/p>\n<p>63<\/p>\n<p>64<\/p>\n<p>65<\/p>\n<p>66<\/p>\n<p>67<\/p>\n<p>68<\/p>\n<p>69<\/p>\n<p>70<\/p>\n<p>71<\/p>\n<p>72<\/p>\n<p>73<\/p>\n<p>74<\/p>\n<p>75<\/p>\n<p>76<\/p>\n<p>77<\/p>\n<p>78<\/p>\n<p>79<\/p>\n<p>80<\/p>\n<p>81<\/p>\n<p>82<\/p>\n<p>83<\/p>\n<p>84<\/p>\n<p>85<\/p>\n<p>86<\/p>\n<p>87<\/p>\n<p>88<\/p>\n<p>89<\/p>\n<p>90<\/p>\n<p>91<\/p>\n<p>92<\/p>\n<p>93<\/p>\n<p>94<\/p>\n<p>95<\/p>\n<p>96<\/p>\n<p>97<\/p>\n<p>98<\/p>\n<p>99<\/p>\n<p>100<\/p>\n<\/div>\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-p\"># rag_pipeline.py<\/span><\/p>\n<p><span class=\"crayon-p\"># Minimal RAG pipeline: ingest paperwork \u2192 embed \u2192 retailer in Chroma \u2192 retrieve and reply<\/span><\/p>\n<p><span class=\"crayon-p\"># Python 3.10+ | ChromaDB 0.5+ | LangChain 0.3+<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">os<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">dotenv <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">load_dotenv<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_openai <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">ChatOpenAI<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">OpenAIEmbeddings<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_chroma <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">Chroma<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_text_splitters <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">RecursiveCharacterTextSplitter<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">paperwork <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">Doc<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">prompts <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">ChatPromptTemplate<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">load_dotenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 STEP 1: SAMPLE DOCUMENTS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># Change this checklist with actual paperwork out of your data base.<\/span><\/p>\n<p><span class=\"crayon-p\"># In manufacturing, load from PDFs, databases, APIs, or file techniques.<\/span><\/p>\n<p><span class=\"crayon-v\">paperwork<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">Document<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">page_content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;Pinecone is a managed vector database optimized for fast, &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;low-latency similarity search at scale. It handles infrastructure automatically &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;and is best for production RAG when you don&#8217;t want to manage servers.&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-v\">metadata<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;source&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;vector_db_guide&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;topic&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;pinecone&#8221;<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">Document<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">page_content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;Weaviate is an open-source vector database with native hybrid search &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;support, combining BM25 keyword search with dense vector search in a single query. &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;It can be self-hosted or used via Weaviate Cloud.&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-v\">metadata<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;source&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;vector_db_guide&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;topic&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;weaviate&#8221;<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">Document<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">page_content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;Chroma is a developer-friendly, local-first vector database ideal for &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;prototyping. The 2025 Rust rewrite significantly improved performance. &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;Best for small-to-medium production workloads and local development.&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-v\">metadata<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;source&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;vector_db_guide&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;topic&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;chroma&#8221;<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">Document<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">page_content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;pgvector is a PostgreSQL extension that adds vector similarity search &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;to an existing Postgres database. With HNSW indexing, it handles millions of vectors &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;at low latency. Best choice if your team already runs PostgreSQL in production.&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-v\">metadata<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;source&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;vector_db_guide&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;topic&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;pgvector&#8221;<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 STEP 2: CHUNK THE DOCUMENTS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># Massive paperwork are break up into smaller chunks earlier than embedding.<\/span><\/p>\n<p><span class=\"crayon-p\"># chunk_size=500 characters; chunk_overlap=50 preserves context throughout chunk boundaries.<\/span><\/p>\n<p><span class=\"crayon-v\">splitter<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">RecursiveCharacterTextSplitter<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">chunk_size<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">500<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">chunk_overlap<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">50<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-v\">chunks<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">splitter<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">split_documents<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">paperwork<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 STEP 3: EMBED AND STORE IN CHROMA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># OpenAIEmbeddings converts every chunk right into a high-dimensional vector.<\/span><\/p>\n<p><span class=\"crayon-p\"># Chroma shops these vectors regionally within the .\/chroma_db listing.<\/span><\/p>\n<p><span class=\"crayon-p\"># On subsequent runs, the prevailing retailer is loaded fairly than rebuilt.<\/span><\/p>\n<p><span class=\"crayon-v\">embeddings<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">OpenAIEmbeddings<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;text-embedding-3-small&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\">\u00a0\u00a0 <\/span><span class=\"crayon-p\"># Quick and cost-effective for many RAG duties<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-v\">vectorstore<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">Chroma<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">from_documents<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">paperwork<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">chunks<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">embedding<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">embeddings<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">persist_directory<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;.\/chroma_db&#8221;<\/span><span class=\"crayon-h\">\u00a0\u00a0 <\/span><span class=\"crayon-p\"># Persist to disk so you do not re-embed on each run<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 STEP 4: RETRIEVAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># Converts the question into an embedding and finds probably the most comparable chunks.<\/span><\/p>\n<p><span class=\"crayon-p\"># okay=3 returns the highest 3 most related chunks.<\/span><\/p>\n<p><span class=\"crayon-v\">retriever<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">vectorstore<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">as_retriever<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">search_kwargs<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;okay&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-cn\">3<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 STEP 5: GENERATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-v\">llm<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;gpt-5.5&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">temperature<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># The immediate tells the mannequin to make use of solely the retrieved context.<\/span><\/p>\n<p><span class=\"crayon-p\"># This prevents the mannequin from hallucinating information not in your data base.<\/span><\/p>\n<p><span class=\"crayon-v\">rag_prompt<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">ChatPromptTemplate<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">from_messages<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">[<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;system&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;Answer the question using only the provided context. &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;If the answer isn&#8217;t in the context, say so clearly.nn&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0 <\/span><span class=\"crayon-s\">&#8220;Context:n{context}&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;human&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;{question}&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">reply<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">query<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;Retrieve related chunks and generate a grounded reply.&#8221;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Retrieve probably the most related doc chunks for this query<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">retrieved_docs<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">retriever<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">query<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Mix the retrieved chunks right into a single context block<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">context<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;nn&#8221;<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">be part of<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">doc<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">page_content <\/span><span class=\"crayon-st\">for<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">doc <\/span><span class=\"crayon-st\">in<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">retrieved_docs<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Construct and invoke the immediate with the query and retrieved context<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">immediate<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">rag_prompt<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;context&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">context<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;query&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">query<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">response<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">immediate<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">response<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-i\">content material<\/span><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">__name__<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">==<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;__main__&#8221;<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">q<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;Which vector database ought to I exploit if I already run PostgreSQL?&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Q: {q}nA: {reply(q)}&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div><\/div><\/div>\n<p>What this does: The pipeline has two phases. Throughout indexing, paperwork are chunked, transformed to embeddings by way of OpenAI\u2019s text-embedding-3-small mannequin, and saved in an area Chroma database. Throughout retrieval, the question is embedded utilizing the identical mannequin, the three most comparable chunks are pulled from Chroma, and the LLM makes use of these chunks and solely these chunks to reply. The persist_directory parameter means Chroma saves the vectors to disk, so you don&#8217;t pay to re-embed your paperwork on each run.<\/p>\n<h2>Layer 5: Instruments and Exterior Integrations<\/h2>\n<p>An agent with out instruments is a really costly textual content predictor. Instruments are what give brokers the power to behave on the world fairly than simply speak about it.<\/p>\n<p>In technical phrases, a software is a operate that the mannequin can select to name. You describe what the operate does in pure language, outline its enter parameters with a schema, and the mannequin decides when calling that operate would assist it reply the query. The mannequin doesn&#8217;t execute the operate; your code does. The mannequin simply decides when and with what arguments.<\/p>\n<p>The classes of instruments that matter most in manufacturing brokers are: net search (for present info), code execution (for calculation and knowledge processing), file I\/O (for studying and writing paperwork), API calls (for connecting to exterior providers), and browser use (for interacting with net interfaces that wouldn&#8217;t have APIs).<\/p>\n<p>One improvement value understanding is the Mannequin Context Protocol (MCP), launched by Anthropic in late 2024. MCP is a standardized manner for fashions to speak with exterior instruments and knowledge sources. Quite than each crew writing customized integration code for each software, MCP gives a shared protocol. Amazon Bedrock Brokers added native MCP help in 2025, and adoption throughout the ecosystem is rising quick.<\/p>\n<p>The one most vital factor about software design is the schema. The mannequin decides whether or not to make use of a software primarily based on its description and decides what arguments to cross primarily based on the parameter schema. A obscure description produces flawed software calls. A well-typed schema with clear parameter descriptions produces dependable ones.<\/p>\n<p>Stipulations:<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b323b0301161239\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\npip set up langchain langchain-openai langchain-community python-dotenv<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">set up <\/span><span class=\"crayon-e\">langchain <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">openai <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">group <\/span><span class=\"crayon-v\">python<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">dotenv<\/span><\/p>\n<\/div><\/div><\/div>\n<p>Find out how to run: Save as instruments.py, add OPENAI_API_KEY to your .env, then run python instruments.py<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b323bc207605153\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\n# instruments.py&#13;<br \/>\n# Defining, registering, and utilizing instruments with a LangChain agent&#13;<br \/>\n# Python 3.10+ | LangChain 0.3+&#13;<br \/>\n&#13;<br \/>\nimport os&#13;<br \/>\nimport json&#13;<br \/>\nimport requests&#13;<br \/>\nfrom dotenv import load_dotenv&#13;<br \/>\nfrom langchain_openai import ChatOpenAI&#13;<br \/>\nfrom langchain.instruments import software&#13;<br \/>\nfrom langchain_community.instruments import DuckDuckGoSearchRun&#13;<br \/>\nfrom langchain_core.messages import HumanMessage&#13;<br \/>\nfrom langgraph.prebuilt import create_react_agent&#13;<br \/>\n&#13;<br \/>\nload_dotenv()&#13;<br \/>\n&#13;<br \/>\nllm = ChatOpenAI(mannequin=&#8221;gpt-5.5&#8243;, temperature=0, api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;))&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 TOOL 1: WEB SEARCH \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# Constructed-in DuckDuckGo software &#8212; no API key wanted.&#13;<br \/>\nsearch = DuckDuckGoSearchRun()&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 TOOL 2: WEATHER LOOKUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# The @software decorator does three issues:&#13;<br \/>\n# 1. Registers the operate as a callable software&#13;<br \/>\n# 2. Makes use of the operate identify because the software identify&#13;<br \/>\n# 3. Makes use of the docstring because the software description (that is what the mannequin reads)&#13;<br \/>\n# The outline is important &#8212; obscure descriptions trigger flawed software calls.&#13;<br \/>\n@software&#13;<br \/>\ndef get_weather(metropolis: str) -&gt; str:&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    Fetch the present climate for a given metropolis.&#13;<br \/>\n    Use this when the person asks about climate situations, temperature, or forecasts.&#13;<br \/>\n    Enter: metropolis identify as a string (e.g., &#8216;London&#8217;, &#8216;Tokyo&#8217;, &#8216;New York&#8217;).&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    attempt:&#13;<br \/>\n        # Utilizing open-meteo (free, no API key) for geocoding and climate&#13;<br \/>\n        geo_url = f&#8221;https:\/\/geocoding-api.open-meteo.com\/v1\/search?identify={metropolis}&amp;rely=1&#8243;&#13;<br \/>\n        geo = requests.get(geo_url, timeout=5).json()&#13;<br \/>\n&#13;<br \/>\n        if not geo.get(&#8220;outcomes&#8221;):&#13;<br \/>\n            return f&#8221;Couldn&#8217;t discover location knowledge for &#8216;{metropolis}&#8217;.&#8221;&#13;<br \/>\n&#13;<br \/>\n        lat = geo[&#8220;results&#8221;][0][&#8220;latitude&#8221;]&#13;<br \/>\n        lon = geo[&#8220;results&#8221;][0][&#8220;longitude&#8221;]&#13;<br \/>\n&#13;<br \/>\n        weather_url = (&#13;<br \/>\n            f&#8221;https:\/\/api.open-meteo.com\/v1\/forecast&#8221;&#13;<br \/>\n            f&#8221;?latitude={lat}&amp;longitude={lon}&#8221;&#13;<br \/>\n            f&#8221;&amp;current_weather=true&#8221;&#13;<br \/>\n        )&#13;<br \/>\n        climate = requests.get(weather_url, timeout=5).json()&#13;<br \/>\n        present = climate.get(&#8220;current_weather&#8221;, {})&#13;<br \/>\n&#13;<br \/>\n        return (&#13;<br \/>\n            f&#8221;Climate in {metropolis}: &#8220;&#13;<br \/>\n            f&#8221;{present.get(&#8216;temperature&#8217;, &#8216;N\/A&#8217;)}\u00b0C, &#8220;&#13;<br \/>\n            f&#8221;wind pace {present.get(&#8216;windspeed&#8217;, &#8216;N\/A&#8217;)} km\/h.&#8221;&#13;<br \/>\n        )&#13;<br \/>\n    besides Exception as e:&#13;<br \/>\n        # At all times return a string from instruments, even on failure.&#13;<br \/>\n        # Elevating exceptions from instruments can crash the agent loop.&#13;<br \/>\n        return f&#8221;Climate lookup failed for &#8216;{metropolis}&#8217;: {str(e)}&#8221;&#13;<br \/>\n&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 TOOL 3: JSON CALCULATOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n@software&#13;<br \/>\ndef calculate(expression: str) -&gt; str:&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    Consider a mathematical expression and return the consequence.&#13;<br \/>\n    Use this for arithmetic, proportion calculations, or any numerical computation.&#13;<br \/>\n    Enter: a sound Python mathematical expression as a string (e.g., &#8216;(150 * 1.08) \/ 12&#8217;).&#13;<br \/>\n    Do NOT use for advanced code execution &#8212; solely simple arithmetic expressions.&#13;<br \/>\n    &#8220;&#8221;&#8221;&#13;<br \/>\n    attempt:&#13;<br \/>\n        # eval is scoped to solely permit math &#8212; no builtins, no imports&#13;<br \/>\n        consequence = eval(expression, {&#8220;__builtins__&#8221;: {}}, {})&#13;<br \/>\n        return f&#8221;Consequence: {consequence}&#8221;&#13;<br \/>\n    besides Exception as e:&#13;<br \/>\n        return f&#8221;Calculation error: {str(e)}&#8221;&#13;<br \/>\n&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 REGISTER TOOLS AND BUILD AGENT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\ninstruments = [search, get_weather, calculate]&#13;<br \/>\nagent = create_react_agent(llm, instruments)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\nif __name__ == &#8220;__main__&#8221;:&#13;<br \/>\n    queries = [&#13;<br \/>\n        &#8220;What is the weather in Lagos right now?&#8221;,&#13;<br \/>\n        &#8220;If I earn $85,000 a year, what is my monthly gross salary?&#8221;,&#13;<br \/>\n        &#8220;Who won the most recent FIFA World Cup?&#8221;&#13;<br \/>\n    ]&#13;<br \/>\n&#13;<br \/>\n    for question in queries:&#13;<br \/>\n        print(f&#8221;nQuery: {question}&#8221;)&#13;<br \/>\n        consequence = agent.invoke({&#8220;messages&#8221;: [HumanMessage(content=query)]})&#13;<br \/>\n        print(f&#8221;Reply: {consequence[&#8216;messages&#8217;][-1].content material}&#8221;)<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"urvanov-syntax-highlighter-nums-content\" style=\"font-size: 12px !important; line-height: 15px !important;\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<p>51<\/p>\n<p>52<\/p>\n<p>53<\/p>\n<p>54<\/p>\n<p>55<\/p>\n<p>56<\/p>\n<p>57<\/p>\n<p>58<\/p>\n<p>59<\/p>\n<p>60<\/p>\n<p>61<\/p>\n<p>62<\/p>\n<p>63<\/p>\n<p>64<\/p>\n<p>65<\/p>\n<p>66<\/p>\n<p>67<\/p>\n<p>68<\/p>\n<p>69<\/p>\n<p>70<\/p>\n<p>71<\/p>\n<p>72<\/p>\n<p>73<\/p>\n<p>74<\/p>\n<p>75<\/p>\n<p>76<\/p>\n<p>77<\/p>\n<p>78<\/p>\n<p>79<\/p>\n<p>80<\/p>\n<p>81<\/p>\n<p>82<\/p>\n<p>83<\/p>\n<p>84<\/p>\n<p>85<\/p>\n<p>86<\/p>\n<p>87<\/p>\n<p>88<\/p>\n<p>89<\/p>\n<p>90<\/p>\n<p>91<\/p>\n<p>92<\/p>\n<p>93<\/p>\n<p>94<\/p>\n<p>95<\/p>\n<p>96<\/p>\n<p>97<\/p>\n<p>98<\/p>\n<\/div>\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-p\"># instruments.py<\/span><\/p>\n<p><span class=\"crayon-p\"># Defining, registering, and utilizing instruments with a LangChain agent<\/span><\/p>\n<p><span class=\"crayon-p\"># Python 3.10+ | LangChain 0.3+<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">os<\/span><\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">json<\/span><\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">requests<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">dotenv <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">load_dotenv<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_openai <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">instruments <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">software<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_community<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">instruments <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">messages <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">HumanMessage<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langgraph<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">prebuilt <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">create_react_agent<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">load_dotenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-v\">llm<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;gpt-5.5&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">temperature<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 TOOL 1: WEB SEARCH \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># Constructed-in DuckDuckGo software &#8212; no API key wanted.<\/span><\/p>\n<p><span class=\"crayon-v\">search<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 TOOL 2: WEATHER LOOKUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># The @software decorator does three issues:<\/span><\/p>\n<p><span class=\"crayon-p\"># 1. Registers the operate as a callable software<\/span><\/p>\n<p><span class=\"crayon-p\"># 2. Makes use of the operate identify because the software identify<\/span><\/p>\n<p><span class=\"crayon-p\"># 3. Makes use of the docstring because the software description (that is what the mannequin reads)<\/span><\/p>\n<p><span class=\"crayon-p\"># The outline is important &#8212; obscure descriptions trigger flawed software calls.<\/span><\/p>\n<p><span class=\"crayon-sy\">@<\/span><span class=\"crayon-e\">software<\/span><\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">get_weather<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">metropolis<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Fetch the present climate for a given metropolis.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Use this when the person asks about climate situations, temperature, or forecasts.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Enter: metropolis identify as a string (e.g., &#8216;London&#8217;, &#8216;Tokyo&#8217;, &#8216;New York&#8217;).<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0&#8220;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">attempt<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Utilizing open-meteo (free, no API key) for geocoding and climate<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">geo_url<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;https:\/\/geocoding-api.open-meteo.com\/v1\/search?identify={metropolis}&amp;rely=1&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">geo<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">requests<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">get<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">geo_url<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">timeout<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">json<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-st\">not<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">geo<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">get<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;outcomes&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Couldn&#8217;t discover location knowledge for &#8216;{metropolis}&#8217;.&#8221;<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">lat<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">geo<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;results&#8221;<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;latitude&#8221;<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">lon<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">geo<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;results&#8221;<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;longitude&#8221;<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">weather_url<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;https:\/\/api.open-meteo.com\/v1\/forecast&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;?latitude={lat}&amp;longitude={lon}&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;&amp;current_weather=true&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">climate<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">requests<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">get<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">weather_url<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">timeout<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">5<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">json<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">present<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">climate<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">get<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;current_weather&#8221;<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Climate in {metropolis}: &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;{present.get(&#8216;temperature&#8217;, &#8216;N\/A&#8217;)}\u00b0C, &#8220;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;wind pace {present.get(&#8216;windspeed&#8217;, &#8216;N\/A&#8217;)} km\/h.&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">besides <\/span><span class=\"crayon-e\">Exception <\/span><span class=\"crayon-st\">as<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">e<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># At all times return a string from instruments, even on failure.<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># Elevating exceptions from instruments can crash the agent loop.<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Climate lookup failed for &#8216;{metropolis}&#8217;: {str(e)}&#8221;<\/span><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 TOOL 3: JSON CALCULATOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-sy\">@<\/span><span class=\"crayon-e\">software<\/span><\/p>\n<p><span class=\"crayon-e\">def <\/span><span class=\"crayon-e\">calculate<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">expression<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">-&gt;<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">str<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><span class=\"crayon-s\">&#8220;<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Consider a mathematical expression and return the consequence.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Use this for arithmetic, proportion calculations, or any numerical computation.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Enter: a sound Python mathematical expression as a string (e.g., &#8216;(150 * 1.08) \/ 12&#8217;).<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0Do NOT use for advanced code execution &#8212; solely simple arithmetic expressions.<\/span><\/p>\n<p><span class=\"crayon-s\">\u00a0\u00a0\u00a0\u00a0&#8220;<\/span><span class=\"crayon-s\">&#8220;&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">attempt<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-p\"># eval is scoped to solely permit math &#8212; no builtins, no imports<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">eval<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">expression<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;__builtins__&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Consequence: {consequence}&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">besides <\/span><span class=\"crayon-e\">Exception <\/span><span class=\"crayon-st\">as<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">e<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">return<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Calculation error: {str(e)}&#8221;<\/span><\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 REGISTER TOOLS AND BUILD AGENT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">search<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">get_weather<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">calculate<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-v\">agent<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">create_react_agent<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 DEMO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-st\">if<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">__name__<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">==<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-s\">&#8220;__main__&#8221;<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">queries<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;What is the weather in Lagos right now?&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;If I earn $85,000 a year, what is my monthly gross salary?&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-s\">&#8220;Who won the most recent FIFA World Cup?&#8221;<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-st\">for<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">question <\/span><span class=\"crayon-st\">in<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">queries<\/span><span class=\"crayon-o\">:<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;nQuery: {question}&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">agent<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;messages&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-e\">HumanMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">query<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-i\">f<\/span><span class=\"crayon-s\">&#8220;Reply: {consequence[&#8216;messages&#8217;][-1].content material}&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div><\/div><\/div>\n<p>What this does: Three instruments are registered: an online search software for present occasions, a climate software that calls a free API with no key required, and a calculator that safely evaluates mathematical expressions. The agent receives every question, causes about which software to make use of, calls it, and synthesizes a solution from the consequence. The important thing design element to note is within the docstrings; every software description is exact about what the software does, when to make use of it, and what format the enter ought to take.<\/p>\n<h2>Layer 6: Observability and Analysis<\/h2>\n<p>Here&#8217;s a manufacturing reality that doesn&#8217;t get stated sufficient: LLMs fail silently. Because the crew at Kanerika put it, a hallucinated reply nonetheless returns HTTP 200. A regular infrastructure monitoring software sees a profitable request. You see nothing uncommon. In the meantime, your agent has been confidently giving flawed solutions for 3 days.<\/p>\n<p>Conventional monitoring was constructed for a world the place \u201cappropriate\u201d is binary: the operate returned the precise sort, the API returned 200, the question accomplished in beneath 100ms. LLM correctness is semantic. The response may be structurally legitimate, grammatically fluent, and utterly flawed. That requires a unique observability layer totally.<\/p>\n<p>There are three issues a very good LLM observability setup tracks. Tracing follows each step of the agent\u2019s execution: the LLM calls, the software invocations, the retrieval queries, the intermediate reasoning steps, and the way lengthy every one took. Analysis scores the output in opposition to metrics that matter: faithfulness (did it keep grounded within the retrieved context?), relevance (did it reply the query requested?), and hallucination price. Monitoring tracks behavioral drift over time, whether or not the agent\u2019s efficiency on a given class of inputs is getting higher or worse because the mannequin and prompts evolve.<\/p>\n<p>The main platforms every have a unique power. LangSmith gives the deepest integration with LangChain and LangGraph. If you&#8217;re already in that ecosystem, it&#8217;s the quickest path to working traces. Langfuse is open-source with over 19,000 GitHub stars and an MIT license, self-hostable, and works with any framework. Arize Phoenix brings ML-grade analysis rigor and ships with over 50 research-backed metrics overlaying faithfulness, relevance, security, and hallucination detection.<\/p>\n<p>In accordance with MLflow\u2019s evaluation of observability platforms, the precise selection typically comes right down to your framework: LangChain groups get probably the most from LangSmith, whereas groups on LlamaIndex or uncooked API calls are higher served by Phoenix or Langfuse.<\/p>\n<p>Right here is  add Langfuse tracing to an current agent with minimal modifications.<\/p>\n<p>Stipulations:<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b323c2181306880\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\npip set up langfuse langchain langchain-openai python-dotenv<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-e\">pip <\/span><span class=\"crayon-e\">set up <\/span><span class=\"crayon-e\">langfuse <\/span><span class=\"crayon-e\">langchain <\/span><span class=\"crayon-v\">langchain<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-e\">openai <\/span><span class=\"crayon-v\">python<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-v\">dotenv<\/span><\/p>\n<\/div><\/div><\/div>\n<p>Join at langfuse.com for a free account and add LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY to your .env. Self-hosting can be accessible in the event you desire to maintain knowledge by yourself infrastructure.<\/p>\n<p>Find out how to run: Save as observability.py and run python observability.py. Open your Langfuse dashboard to see the hint.<\/p>\n<div id=\"urvanov-syntax-highlighter-6a3ff96b323cd200120190\" class=\"urvanov-syntax-highlighter-syntax crayon-theme-classic urvanov-syntax-highlighter-font-monaco urvanov-syntax-highlighter-os-pc print-yes notranslate\" data-settings=\" touchscreen minimize scroll-mouseover disable-anim\" style=\" margin-top: 12px; margin-bottom: 12px; font-size: 12px !important; line-height: 15px !important;\">\n<p>\n# observability.py&#13;<br \/>\n# Including Langfuse tracing to a LangChain agent&#13;<br \/>\n# Langfuse captures each LLM name, software invocation, and token rely routinely.&#13;<br \/>\n&#13;<br \/>\nimport os&#13;<br \/>\nfrom dotenv import load_dotenv&#13;<br \/>\nfrom langchain_openai import ChatOpenAI&#13;<br \/>\nfrom langchain_community.instruments import DuckDuckGoSearchRun&#13;<br \/>\nfrom langchain_core.messages import HumanMessage&#13;<br \/>\nfrom langgraph.prebuilt import create_react_agent&#13;<br \/>\n&#13;<br \/>\n# Langfuse integrates by way of the CallbackHandler sample.&#13;<br \/>\n# It intercepts each LangChain occasion and sends it to your Langfuse dashboard.&#13;<br \/>\nfrom langfuse.langchain import CallbackHandler&#13;<br \/>\n&#13;<br \/>\nload_dotenv()&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 LANGFUSE SETUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# CallbackHandler reads LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY from the atmosphere.&#13;<br \/>\n# session_id teams all associated traces into one session &#8212; helpful for debugging conversations.&#13;<br \/>\n# user_id ties traces to a selected person for per-user efficiency evaluation.&#13;<br \/>\nlangfuse_handler = CallbackHandler(&#13;<br \/>\n    session_id=&#8221;demo_session_001&#8243;,&#13;<br \/>\n    user_id=&#8221;demo_user&#8221;&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 AGENT SETUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\nllm = ChatOpenAI(&#13;<br \/>\n    mannequin=&#8221;gpt-5.5&#8243;,&#13;<br \/>\n    temperature=0,&#13;<br \/>\n    api_key=os.getenv(&#8220;OPENAI_API_KEY&#8221;),&#13;<br \/>\n    callbacks=[langfuse_handler]   # Connect the handler right here &#8212; that is the one change&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\ninstruments = [DuckDuckGoSearchRun()]&#13;<br \/>\nagent = create_react_agent(llm, instruments)&#13;<br \/>\n&#13;<br \/>\n# \u2500\u2500 RUN WITH TRACING \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500&#13;<br \/>\n# Move the handler in config so it traces software calls in addition to LLM calls.&#13;<br \/>\n# With out this, solely the LLM calls are traced &#8212; software invocations are invisible.&#13;<br \/>\nconsequence = agent.invoke(&#13;<br \/>\n    {&#8220;messages&#8221;: [HumanMessage(content=&#8221;What is the latest version of Python?&#8221;)]},&#13;<br \/>\n    config={&#8220;callbacks&#8221;: [langfuse_handler]}&#13;<br \/>\n)&#13;<br \/>\n&#13;<br \/>\nprint(consequence[&#8220;messages&#8221;][-1].content material)&#13;<br \/>\n&#13;<br \/>\n# Flush ensures all traces are despatched to Langfuse earlier than the script exits.&#13;<br \/>\n# In a long-running server, that is dealt with routinely.&#13;<br \/>\nlangfuse_handler.flush()&#13;<br \/>\n&#13;<br \/>\nprint(&#8220;nTrace despatched to Langfuse. Verify your dashboard at https:\/\/cloud.langfuse.com&#8221;)<\/p>\n<div class=\"urvanov-syntax-highlighter-main\" style=\"\">\n<div class=\"urvanov-syntax-highlighter-nums-content\" style=\"font-size: 12px !important; line-height: 15px !important;\">\n<p>1<\/p>\n<p>2<\/p>\n<p>3<\/p>\n<p>4<\/p>\n<p>5<\/p>\n<p>6<\/p>\n<p>7<\/p>\n<p>8<\/p>\n<p>9<\/p>\n<p>10<\/p>\n<p>11<\/p>\n<p>12<\/p>\n<p>13<\/p>\n<p>14<\/p>\n<p>15<\/p>\n<p>16<\/p>\n<p>17<\/p>\n<p>18<\/p>\n<p>19<\/p>\n<p>20<\/p>\n<p>21<\/p>\n<p>22<\/p>\n<p>23<\/p>\n<p>24<\/p>\n<p>25<\/p>\n<p>26<\/p>\n<p>27<\/p>\n<p>28<\/p>\n<p>29<\/p>\n<p>30<\/p>\n<p>31<\/p>\n<p>32<\/p>\n<p>33<\/p>\n<p>34<\/p>\n<p>35<\/p>\n<p>36<\/p>\n<p>37<\/p>\n<p>38<\/p>\n<p>39<\/p>\n<p>40<\/p>\n<p>41<\/p>\n<p>42<\/p>\n<p>43<\/p>\n<p>44<\/p>\n<p>45<\/p>\n<p>46<\/p>\n<p>47<\/p>\n<p>48<\/p>\n<p>49<\/p>\n<p>50<\/p>\n<p>51<\/p>\n<p>52<\/p>\n<\/div>\n<div class=\"crayon-pre\" style=\"font-size: 12px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;\">\n<p><span class=\"crayon-p\"># observability.py<\/span><\/p>\n<p><span class=\"crayon-p\"># Including Langfuse tracing to a LangChain agent<\/span><\/p>\n<p><span class=\"crayon-p\"># Langfuse captures each LLM name, software invocation, and token rely routinely.<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">os<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">dotenv <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">load_dotenv<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-e\">langchain_openai <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_community<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">instruments <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langchain_core<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">messages <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">HumanMessage<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langgraph<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">prebuilt <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-v\">create_react<\/span><span class=\"crayon-sy\">_<\/span>agent<\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Langfuse integrates by way of the CallbackHandler sample.<\/span><\/p>\n<p><span class=\"crayon-p\"># It intercepts each LangChain occasion and sends it to your Langfuse dashboard.<\/span><\/p>\n<p><span class=\"crayon-e\">from <\/span><span class=\"crayon-v\">langfuse<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">langchain <\/span><span class=\"crayon-e\">import <\/span><span class=\"crayon-e\">CallbackHandler<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">load_dotenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 LANGFUSE SETUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># CallbackHandler reads LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY from the atmosphere.<\/span><\/p>\n<p><span class=\"crayon-p\"># session_id teams all associated traces into one session &#8212; helpful for debugging conversations.<\/span><\/p>\n<p><span class=\"crayon-p\"># user_id ties traces to a selected person for per-user efficiency evaluation.<\/span><\/p>\n<p><span class=\"crayon-v\">langfuse_handler<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">CallbackHandler<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">session_id<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;demo_session_001&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">user_id<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;demo_user&#8221;<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 AGENT SETUP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-v\">llm<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">ChatOpenAI<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">mannequin<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;gpt-5.5&#8221;<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">temperature<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-cn\">0<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">api_key<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-v\">os<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">getenv<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;OPENAI_API_KEY&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">callbacks<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">langfuse_handler<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-h\">\u00a0\u00a0 <\/span><span class=\"crayon-p\"># Connect the handler right here &#8212; that is the one change<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-e\">DuckDuckGoSearchRun<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><\/p>\n<p><span class=\"crayon-v\">agent<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-e\">create_react_agent<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">llm<\/span><span class=\"crayon-sy\">,<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">instruments<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># \u2500\u2500 RUN WITH TRACING \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<\/span><\/p>\n<p><span class=\"crayon-p\"># Move the handler in config so it traces software calls in addition to LLM calls.<\/span><\/p>\n<p><span class=\"crayon-p\"># With out this, solely the LLM calls are traced &#8212; software invocations are invisible.<\/span><\/p>\n<p><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-v\">agent<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">invoke<\/span><span class=\"crayon-sy\">(<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;messages&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-e\">HumanMessage<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">content<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-s\">&#8220;What is the latest version of Python?&#8221;<\/span><span class=\"crayon-sy\">)<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">}<\/span><span class=\"crayon-sy\">,<\/span><\/p>\n<p><span class=\"crayon-h\">\u00a0\u00a0\u00a0\u00a0<\/span><span class=\"crayon-v\">config<\/span><span class=\"crayon-o\">=<\/span><span class=\"crayon-sy\">{<\/span><span class=\"crayon-s\">&#8220;callbacks&#8221;<\/span><span class=\"crayon-o\">:<\/span><span class=\"crayon-h\"> <\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-v\">langfuse_handler<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">}<\/span><\/p>\n<p><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-v\">consequence<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-s\">&#8220;messages&#8221;<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">[<\/span><span class=\"crayon-o\">&#8211;<\/span><span class=\"crayon-cn\">1<\/span><span class=\"crayon-sy\">]<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-v\">content material<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-p\"># Flush ensures all traces are despatched to Langfuse earlier than the script exits.<\/span><\/p>\n<p><span class=\"crayon-p\"># In a long-running server, that is dealt with routinely.<\/span><\/p>\n<p><span class=\"crayon-v\">langfuse_handler<\/span><span class=\"crayon-sy\">.<\/span><span class=\"crayon-e\">flush<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<p>\u00a0<\/p>\n<p><span class=\"crayon-e\">print<\/span><span class=\"crayon-sy\">(<\/span><span class=\"crayon-s\">&#8220;nTrace despatched to Langfuse. Verify your dashboard at https:\/\/cloud.langfuse.com&#8221;<\/span><span class=\"crayon-sy\">)<\/span><\/p>\n<\/div><\/div><\/div>\n<p>What this does: Two modifications from a typical agent setup: the CallbackHandler is initialized with a session and person ID, and it&#8217;s connected to each the LLM and the agent.invoke config. That&#8217;s sufficient for Langfuse to seize the complete hint of each LLM name, each software invocation, token counts, latency, and the entire enter\/output at every step. Every thing you must debug a manufacturing failure or observe high quality drift over time.<\/p>\n<h2>Layer 7: Deployment Infrastructure<\/h2>\n<p>You possibly can have a flawless agent in improvement that turns right into a upkeep drawback in manufacturing. The infrastructure layer is the place that hole lives.<\/p>\n<p>At a minimal, your agent must be containerized with Docker. Containers offer you constant habits throughout environments, simple dependency administration, and a clear path to any cloud deployment goal. The choice \u2014 transport Python scripts with a necessities.txt and hoping the atmosphere matches \u2014 creates a category of bugs that wastes engineering time disproportionate to the hassle containerization would have taken.<\/p>\n<p>For many manufacturing brokers, you&#8217;ve two architectural choices for the serving layer: a synchronous API or an async queue. A synchronous API (Flask or FastAPI) works when your agent completes in beneath a number of seconds, and you may afford to carry the HTTP connection open. <\/p>\n<p>When your agent entails a number of software calls, lengthy retrieval pipelines, or doc processing that may take 30 to 60 seconds, an async queue (Celery, AWS SQS, or Google Pub\/Sub) is the higher selection. The consumer submits a job, will get a process ID again instantly, and polls for the consequence.<\/p>\n<p>On the cloud aspect, all three main platforms now have managed agent infrastructure. Amazon\u2019s AgentCore, which grew to become usually accessible in October 2025, gives devoted agentic infrastructure on AWS for reminiscence administration, software execution, and session dealing with with out provisioning servers. Google Vertex AI Agent Builder is the pure selection for groups already within the GCP ecosystem, with native Gemini integration and built-in observability. Azure OpenAI Service with Semantic Kernel is the enterprise default for Microsoft retailers.<\/p>\n<p>For value administration, three practices make the most important distinction: caching (returning saved responses for repeated equivalent queries fairly than calling the mannequin once more), request batching (grouping non-urgent duties to cut back per-call overhead), and setting max_iterations in your agent executor to forestall runaway loops from consuming tokens with out certain.<\/p>\n<div style=\"width: 810px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-A-vertical-stack-diagram-showing-all-7-layers-labeled-top-to-bottom.png\" alt=\"A vertical stack diagram showing all 7 layers labeled top to bottom: Foundation Model, Orchestration Framework, Memory Systems, Vector Database and RAG, Tools and Integrations, Observability and Evaluation, Deployment Infrastructure\" width=\"800\" height=\"706\"\/><\/p>\n<p class=\"wp-caption-text\">A vertical stack diagram displaying all 7 layers labeled prime to backside: Basis Mannequin, Orchestration Framework, Reminiscence Methods, Vector Database and RAG, Instruments and Integrations, Observability and Analysis, Deployment Infrastructure (click on to enlarge)<\/p>\n<\/div>\n<h2>Placing It All Collectively<\/h2>\n<p>The precise selections at every layer rely on the place you might be within the undertaking lifecycle. Here&#8217;s a sensible reference that displays the analysis and trade-offs mentioned above.<\/p>\n<p>Prototype (transfer quick, minimal infrastructure):<\/p>\n<p>Layer<br \/>\nSelection<br \/>\nMotive<\/p>\n<p>Basis Mannequin<br \/>\nGPT-5.5<br \/>\nDependable tool-calling, mature ecosystem<\/p>\n<p>Orchestration<br \/>\nLangGraph<br \/>\nQuick setup, good documentation<\/p>\n<p>Reminiscence<br \/>\nIn-context solely<br \/>\nNo infrastructure wanted<\/p>\n<p>Vector DB<br \/>\nChroma<br \/>\nNative, no ops, good developer expertise<\/p>\n<p>Instruments<br \/>\nDuckDuckGo + customized @software features<br \/>\nZero API keys required<\/p>\n<p>Observability<br \/>\nLangfuse (cloud free tier)<br \/>\nOne-line setup<\/p>\n<p>Deployment<br \/>\nNative \/ Docker<br \/>\nShip quick<\/p>\n<p>Manufacturing Startup (scale with management):<\/p>\n<p>Layer<br \/>\nSelection<br \/>\nMotive<\/p>\n<p>Basis Mannequin<br \/>\nGPT-5.5 + Claude Sonnet 4.6 fallback<br \/>\nReliability with redundancy<\/p>\n<p>Orchestration<br \/>\nLangGraph or CrewAI<br \/>\nState administration and multi-agent help<\/p>\n<p>Reminiscence<br \/>\nEpisodic (Postgres) + Semantic (RAG)<br \/>\nFull persistent context<\/p>\n<p>Vector DB<br \/>\nWeaviate or Pinecone<br \/>\nScale and hybrid search<\/p>\n<p>Instruments<br \/>\nFull software suite with MCP<br \/>\nStandardized integrations<\/p>\n<p>Observability<br \/>\nLangfuse self-hosted or Arize Phoenix<br \/>\nInformation management + ML-grade evals<\/p>\n<p>Deployment<br \/>\nDocker + Kubernetes + async queue<br \/>\nManufacturing-grade, cost-controlled<\/p>\n<p>Enterprise:<\/p>\n<p>Layer<br \/>\nSelection<br \/>\nMotive<\/p>\n<p>Basis Mannequin<br \/>\nAzure OpenAI or AWS Bedrock<br \/>\nCompliance, knowledge residency, SLA<\/p>\n<p>Orchestration<br \/>\nSemantic Kernel or LangGraph<br \/>\nEnterprise language help, governance<\/p>\n<p>Reminiscence<br \/>\nManaged reminiscence with audit path<br \/>\nRegulatory necessities<\/p>\n<p>Vector DB<br \/>\nWeaviate or pgvector<br \/>\nSelf-hostable, compliance-ready<\/p>\n<p>Instruments<br \/>\nMCP-based, internally permitted<br \/>\nSafety evaluate and entry management<\/p>\n<p>Observability<br \/>\nLangfuse self-hosted or Datadog LLM module<br \/>\nPresent infrastructure integration<\/p>\n<p>Deployment<br \/>\nAWS AgentCore \/ Vertex AI Agent Builder<br \/>\nAbsolutely managed, ruled, auditable<\/p>\n<h2>Conclusion<\/h2>\n<p>The inspiration mannequin is the a part of this stack that will get written about. The opposite six layers are the components that decide whether or not what you constructed truly works in manufacturing.<\/p>\n<p>An agent fails on the orchestration layer when the ReAct loop will get caught. It fails on the reminiscence layer when it forgets the context it wants. It fails on the retrieval layer when the flawed chunks are returned, and the mannequin hallucinates a grounded-sounding reply. It fails on the instruments layer when a schema is simply too obscure, and the mannequin calls the flawed operate. It fails on the observability layer when you don&#8217;t have any solution to know that any of that is taking place. And it fails on the deployment layer when the infrastructure can not deal with the latency or value necessities of actual site visitors.<\/p>\n<p>Gartner estimates that over 40% of agentic AI initiatives are prone to cancellation by 2027 attributable to unclear worth, rising prices, and weak governance. Most of these failures will hint again to not a foul mannequin selection however to a stack that was constructed layer by layer with no clear image of how the layers join.<\/p>\n<p>Understanding the complete stack doesn&#8217;t imply it&#8217;s a must to construct all of it. It means  what choices you make and what you might be buying and selling off once you make them. That&#8217;s the distinction between an agent that works in a demo and one which ships.<\/p>\n<\/p><\/div>\n<p><br \/>\n<br \/><a href=\"https:\/\/machinelearningmastery.com\/the-ai-agent-tech-stack-explained\/\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>On this article, you&#8217;ll find out how the seven layers of a manufacturing AI agent stack match collectively, from the inspiration mannequin right down to deployment infrastructure. Matters we&#8217;ll cowl embrace: What every layer of the stack does, from the inspiration mannequin and orchestration framework by way of reminiscence, retrieval, instruments, observability, and deployment. Find [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1594,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","fifu_image_alt":"","jnews-multi-image_gallery":[],"jnews_single_post":[],"jnews_primary_category":[],"jnews_override_bookmark_settings":[],"jnews_social_meta":[],"jnews_override_counter":[],"footnotes":""},"categories":[7],"tags":[457,998,1556,595],"class_list":["post-1592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-science-mlops","tag-agent","tag-explained","tag-stack","tag-tech"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The AI Agent Tech Stack Defined - Future News 24<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The AI Agent Tech Stack Defined - Future News 24\" \/>\n<meta property=\"og:description\" content=\"On this article, you&#8217;ll find out how the seven layers of a manufacturing AI agent stack match collectively, from the inspiration mannequin right down to deployment infrastructure. Matters we&#8217;ll cowl embrace: What every layer of the stack does, from the inspiration mannequin and orchestration framework by way of reminiscence, retrieval, instruments, observability, and deployment. Find [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/\" \/>\n<meta property=\"og:site_name\" content=\"Future News 24\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-26T14:01:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-28T08:59:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\" \/><meta property=\"og:image\" content=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\" \/>\n<meta name=\"author\" content=\"Future News 24\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Future News 24\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"38 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/\"},\"author\":{\"name\":\"Future News 24\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#\\\/schema\\\/person\\\/cecad1bde21cfc357cf70128144d6c83\"},\"headline\":\"The AI Agent Tech Stack Defined\",\"datePublished\":\"2026-06-26T14:01:00+00:00\",\"dateModified\":\"2026-06-28T08:59:27+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/\"},\"wordCount\":7679,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/machinelearningmastery.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\",\"keywords\":[\"Agent\",\"Explained\",\"Stack\",\"Tech\"],\"articleSection\":[\"Data Science &amp; MLOps\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/\",\"url\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/\",\"name\":\"The AI Agent Tech Stack Defined - Future News 24\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/machinelearningmastery.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\",\"datePublished\":\"2026-06-26T14:01:00+00:00\",\"dateModified\":\"2026-06-28T08:59:27+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#primaryimage\",\"url\":\"https:\\\/\\\/machinelearningmastery.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\",\"contentUrl\":\"https:\\\/\\\/machinelearningmastery.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/2026\\\/06\\\/26\\\/the-ai-agent-tech-stack-explained\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/futurenews24.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The AI Agent Tech Stack Defined\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#website\",\"url\":\"https:\\\/\\\/futurenews24.com\\\/\",\"name\":\"Future News 24\",\"description\":\"The Smart Hub for AI and Next-Gen Innovation\",\"publisher\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/futurenews24.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#organization\",\"name\":\"Future News 24\",\"url\":\"https:\\\/\\\/futurenews24.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/futurenews24.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/fn24-favicon.png\",\"contentUrl\":\"https:\\\/\\\/futurenews24.com\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/fn24-favicon.png\",\"width\":250,\"height\":250,\"caption\":\"Future News 24\"},\"image\":{\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/futurenews24.com\\\/#\\\/schema\\\/person\\\/cecad1bde21cfc357cf70128144d6c83\",\"name\":\"Future News 24\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g\",\"caption\":\"Future News 24\"},\"sameAs\":[\"https:\\\/\\\/futurenews24.com\"],\"url\":\"https:\\\/\\\/futurenews24.com\\\/index.php\\\/author\\\/mridulpahuja20\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The AI Agent Tech Stack Defined - Future News 24","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/","og_locale":"en_US","og_type":"article","og_title":"The AI Agent Tech Stack Defined - Future News 24","og_description":"On this article, you&#8217;ll find out how the seven layers of a manufacturing AI agent stack match collectively, from the inspiration mannequin right down to deployment infrastructure. Matters we&#8217;ll cowl embrace: What every layer of the stack does, from the inspiration mannequin and orchestration framework by way of reminiscence, retrieval, instruments, observability, and deployment. Find [&hellip;]","og_url":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/","og_site_name":"Future News 24","article_published_time":"2026-06-26T14:01:00+00:00","article_modified_time":"2026-06-28T08:59:27+00:00","og_image":[{"url":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","type":"","width":"","height":""},{"url":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","type":"","width":"","height":""}],"author":"Future News 24","twitter_card":"summary_large_image","twitter_image":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","twitter_misc":{"Written by":"Future News 24","Est. reading time":"38 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#article","isPartOf":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/"},"author":{"name":"Future News 24","@id":"https:\/\/futurenews24.com\/#\/schema\/person\/cecad1bde21cfc357cf70128144d6c83"},"headline":"The AI Agent Tech Stack Defined","datePublished":"2026-06-26T14:01:00+00:00","dateModified":"2026-06-28T08:59:27+00:00","mainEntityOfPage":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/"},"wordCount":7679,"commentCount":0,"publisher":{"@id":"https:\/\/futurenews24.com\/#organization"},"image":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#primaryimage"},"thumbnailUrl":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","keywords":["Agent","Explained","Stack","Tech"],"articleSection":["Data Science &amp; MLOps"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/","url":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/","name":"The AI Agent Tech Stack Defined - Future News 24","isPartOf":{"@id":"https:\/\/futurenews24.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#primaryimage"},"image":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#primaryimage"},"thumbnailUrl":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","datePublished":"2026-06-26T14:01:00+00:00","dateModified":"2026-06-28T08:59:27+00:00","breadcrumb":{"@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#primaryimage","url":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png","contentUrl":"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2026\/06\/MLM-Shittu-The-AI-Agent-Tech-Stack-1024x573.png"},{"@type":"BreadcrumbList","@id":"https:\/\/futurenews24.com\/index.php\/2026\/06\/26\/the-ai-agent-tech-stack-explained\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/futurenews24.com\/"},{"@type":"ListItem","position":2,"name":"The AI Agent Tech Stack Defined"}]},{"@type":"WebSite","@id":"https:\/\/futurenews24.com\/#website","url":"https:\/\/futurenews24.com\/","name":"Future News 24","description":"The Smart Hub for AI and Next-Gen Innovation","publisher":{"@id":"https:\/\/futurenews24.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/futurenews24.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/futurenews24.com\/#organization","name":"Future News 24","url":"https:\/\/futurenews24.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/futurenews24.com\/#\/schema\/logo\/image\/","url":"https:\/\/futurenews24.com\/wp-content\/uploads\/2026\/06\/fn24-favicon.png","contentUrl":"https:\/\/futurenews24.com\/wp-content\/uploads\/2026\/06\/fn24-favicon.png","width":250,"height":250,"caption":"Future News 24"},"image":{"@id":"https:\/\/futurenews24.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/futurenews24.com\/#\/schema\/person\/cecad1bde21cfc357cf70128144d6c83","name":"Future News 24","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d57f07142d73cb5503ab2446ea7bc9ef3d0a5ba378d64a6157692311e42bf097?s=96&d=mm&r=g","caption":"Future News 24"},"sameAs":["https:\/\/futurenews24.com"],"url":"https:\/\/futurenews24.com\/index.php\/author\/mridulpahuja20\/"}]}},"_links":{"self":[{"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/posts\/1592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/comments?post=1592"}],"version-history":[{"count":1,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/posts\/1592\/revisions"}],"predecessor-version":[{"id":1593,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/posts\/1592\/revisions\/1593"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/media\/1594"}],"wp:attachment":[{"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/media?parent=1592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/categories?post=1592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/futurenews24.com\/index.php\/wp-json\/wp\/v2\/tags?post=1592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}