An agentic AI example is a system where a model decides which tools to call, in what order, and when to stop, to finish a task a person used to do by hand: triaging a support ticket, scheduling a meeting, answering an IT question from the wiki. Below is a catalogue of eight such patterns we see running in businesses in 2026, each with its trigger, its tools, its human checkpoint and the way it usually fails, followed by three Python walkthroughs (LangChain, smolagents, LlamaIndex) with working code.
Updated September 2026: added the eight-pattern catalogue, checked every import against the current LangChain 1.3, smolagents 1.26 and LlamaIndex 0.14 releases, added a "what changed" note with the call that works today above each affected code block, the gpt-3.5-turbo retirement date, and an FAQ. The original walkthroughs and their code are kept unchanged.
Moving from demo to deployed agent is where most teams fail; we walk through that transition in Cohorte's Building Accountable AI Agents course (E3).
Agentic AI examples: the patterns that actually run in business (2026)
These are the shapes we keep meeting in production, stripped of vendor names. The fields matter more than the names: if you cannot write the trigger, the tool list and the human checkpoint for your own idea in one line each, it is not ready to build. There are no metrics in this list on purpose. The numbers depend on your data, your volume and your baseline, and any figure we printed would be someone else's.
- 1. Support triage and reply drafting.
Pattern: classify the incoming request, pull the answer from the knowledge base or the account, draft the reply.
Trigger: a new ticket, chat message or email in the helpdesk queue.
Tools: knowledge-base search, order or account lookup, ticket update, a "hand to a human" action.
Human checkpoint: auto-send only for the FAQ class (a policy question with a matching article); anything that touches money, credentials or an account change is drafted and a person sends it.
Where it fails: the model answers from its training data when the search returns nothing (the "do you ship internationally?" case in walkthrough 1), stale articles, and policy exceptions nobody wrote down. - 2. Order and account operations.
Pattern: perform a bounded set of account actions on request: status, address change, resend an invoice, refund under a threshold.
Trigger: a customer request that passed identity verification, or a webhook from the order system.
Tools: order API, payment API, identity check, audit log.
Human checkpoint: a threshold. Refunds, credits or cancellations above it go to a queue; every write carries an idempotency key so a retry cannot issue the same refund twice.
Where it fails: identity confusion between similar customers, retries without idempotency, and tools that return "success" for actions that did not complete. - 3. Scheduling and follow-up assistant.
Pattern: read a natural-language request, gather availability, pick a slot, produce the invite or the email (walkthrough 2).
Trigger: a message in chat or email addressed to the assistant.
Tools: calendar free/busy, contacts, email or invite creation.
Human checkpoint: an explicit "send this?" before anything leaves the company; internal-only invites can go out on their own.
Where it fails: time zones, ambiguous names ("John"), relative dates ("next week" typed on a Friday), and double-booking when two requests run at the same time. - 4. Internal knowledge assistant (IT, HR, finance helpdesk).
Pattern: retrieval over the internal wiki, an answer with its sources, and an optional ticket (walkthrough 3).
Trigger: a question in Slack, Teams or the helpdesk portal.
Tools: a vector or hybrid search index over the docs, a permission check, ticket creation.
Human checkpoint: the employee confirms before a ticket is opened; the index only returns documents the asker is allowed to read.
Where it fails: answering from an outdated version of a policy, leaking through the index a document the file system would have blocked, and confident answers to questions the wiki does not cover. - 5. Document intake and extraction.
Pattern: turn invoices, contracts, claims or forms into structured records and push them into the system of record.
Trigger: a file lands in a mailbox, a shared folder or an upload endpoint.
Tools: OCR or document parsing, validation rules (totals reconcile, dates in range, vendor exists), ERP or CRM write.
Human checkpoint: fields under a confidence threshold, and any record that fails a validation rule, go to a review queue; the write to the system of record never happens from an unreviewed low-confidence extraction.
Where it fails: layout drift when a supplier changes its template, silently swapped fields (net vs gross), and multi-page documents where page 3 contradicts page 1. - 6. CRM hygiene and enrichment.
Pattern: after each call or on a nightly schedule, update the record, propose merges, fill missing fields from approved sources.
Trigger: a call transcript, a form submission, a cron job.
Tools: CRM read and write, enrichment API, email.
Human checkpoint: the agent proposes merges and deletions and a person applies them; it may write notes and next steps on its own.
Where it fails: merging two companies with similar names, inventing a field value when the source is empty, and overwriting a human-entered value with a lower-quality one. - 7. Data questions and reporting.
Pattern: translate a question into a query against the warehouse, run it, return a table or a chart with the SQL shown.
Trigger: a question in chat, or a scheduled report.
Tools: schema and metric-definition lookup, read-only SQL execution, charting.
Human checkpoint: read-only credentials by construction; numbers are reviewed by the owner of the metric before they leave the team.
Where it fails: a wrong join that returns a plausible number, a metric defined differently in two tables, and questions that assume a column that does not exist. - 8. Engineering and operations agent.
Pattern: triage an alert or an issue, read the logs and the runbook, propose a fix as a pull request.
Trigger: an alert, a failing pipeline, a labelled issue.
Tools: log search, repository read, test runner, CI status, pull-request creation.
Human checkpoint: the pull request is reviewed and merged by a person; the agent never holds production write credentials.
Where it fails: fixing the symptom that made the test pass, a blast radius nobody bounded when write access was granted, and confident diagnoses from partial logs.
Two things hold across all eight. The trigger and the tools are the easy part; the checkpoint is the design. And the failure column is not a list of bugs to fix once, it is what your evaluation set must contain before you ship.
How to read the three walkthroughs below
The three examples that follow were written in March 2025 and map onto patterns 1, 3 and 4 above: a customer-service agent with LangChain, a scheduling agent that writes its own code with smolagents, and an IT helpdesk assistant with LlamaIndex. We kept the original code byte for byte because the reasoning in the prose still holds; what moved is the framework surface. LangChain 1.0 (October 2025) took the legacy agent constructors out of the main package, LlamaIndex had already moved everything to the llama_index.core namespace in v0.10 (February 2024, so that block was on the old import path when the post went out), and smolagents now rejects tool docstrings that do not describe their arguments. Above each affected block there is a short "What changed since this was written" note with the call that works today, verified on 3 September 2026 against LangChain 1.3.18, smolagents 1.26.0 and LlamaIndex 0.14.24. One more thing moved: all three examples used gpt-3.5-turbo. OpenAI has scheduled that alias for shutdown on 23 October 2026, so swap in a current model id when you run them.
Example 1: Customer Service Virtual Agent
Use Case: A company wants an AI agent to handle customer support queries. This agent should be able to answer frequently asked questions by retrieving information from a knowledge base, perform simple account actions (like checking order status or opening a support ticket), and escalate complex issues to a human if needed. We’ll design a Customer Service Virtual Agent that can do the following:
- Greet the user and understand their question.
- Use a knowledge base tool to find answers for informational queries (e.g., “What is your return policy?”).
- Use an order API tool for questions like “Where is my order #12345?”.
- If the query is beyond its capability, politely inform the user that a human rep will follow up (and perhaps log the query for human review).
Framework choice: We’ll use LangChain for this example because it allows easy integration of a Q&A knowledge base and custom tools. LangChain’s agent can handle the decision-making of whether to use the knowledge base or the order API. We’ll assume we have:
- A small FAQ document or vector store for general questions.
- A dummy order database or API function to get order status.
Architecture Diagram: The agent here is a single LLM-based agent with two tools: a KnowledgeBase (a retrieval QA tool that returns an answer from documentation) and an OrderStatus tool (function that looks up an order). The flow is: User query -> Agent -> (optional tool usage) -> Agent answer to user. Below is a conceptual diagram:

Step-by-Step Implementation:
- Setup knowledge base: Let’s create a simple knowledge base. In a real scenario, this could be a vector database containing embeddings of FAQ answers. For our example, we’ll simulate with a dictionary of Q&A.
- Define tools: We will have
faq_search(question)that returns a relevant FAQ answer (if any), andget_order_status(order_id)that returns a fake order status. - Initialize agent: Use LangChain’s initialize_agent with these tools.
- Run agent with example queries.
What changed since this was written: initialize_agent, AgentExecutor and langchain.llms.OpenAI no longer ship in the main langchain package. Since LangChain 1.0 (17 October 2025) the legacy constructors live in langchain-classic (from langchain_classic.agents import initialize_agent, Tool; version 1.0.8 as we write) and the OpenAI wrappers in langchain-openai. The supported way to build this agent on LangChain 1.3.18 is create_agent: it takes a model (a string such as "openai:gpt-5.5" or a chat-model instance) and a list of @tool functions, and returns a compiled graph you call with a messages dict. The block below keeps the original tool logic, adds the escalation rule the original prose only wished for, and runs the same three queries:
# pip install -U langchain langchain-openai (LangChain 1.3.18, September 2026)
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
FAQ_DB = {
"return policy": "You can return any item within 30 days of purchase with a receipt for a full refund.",
"shipping time": "Orders typically arrive within 5-7 business days via standard shipping.",
}
@tool
def search_faq(query: str) -> str:
"""Answer common questions from the FAQ or policy documents. Returns an empty string when nothing matches."""
for key, answer in FAQ_DB.items():
if key in query.lower():
return answer
return ""
@tool
def get_order_status(order_id: str) -> str:
"""Check the status of an order by order number."""
return f"Order {order_id} is currently being processed and will ship in 2 days."
agent = create_agent(
model=ChatOpenAI(model="gpt-5.5"), # any current chat model; gpt-3.5-turbo retires on 2026-10-23
tools=[search_faq, get_order_status],
system_prompt=(
"You are a customer support agent. Use search_faq for policy questions and "
"get_order_status when the user gives an order number. If neither tool returns "
"an answer, say a human representative will follow up. Never invent a policy."
),
)
queries = [
"Hi, what's your return policy?",
"Where is my order 12345? It was supposed to be here by now.",
"Do you ship internationally?",
]
for q in queries:
result = agent.invoke({"messages": [{"role": "user", "content": q}]})
print(f"User: {q}\nAgent: {result['messages'][-1].content}\n")
The original block, unchanged:
from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
# 1. Knowledge base setup (simple dict for demo)
FAQ_DB = {
"return policy": "You can return any item within 30 days of purchase with a receipt for a full refund.",
"shipping time": "Orders typically arrive within 5-7 business days via standard shipping.",
}
def search_faq(query: str) -> str:
"""Very basic FAQ search: returns an answer if query matches a known FAQ."""
for key, answer in FAQ_DB.items():
if key in query.lower():
return answer
return "" # empty string if no match found
# 2. Define the tools
def get_order_status(order_id: str) -> str:
"""Dummy order status lookup."""
# In real life, call database or API
return f"Order {order_id} is currently being processed and will ship in 2 days."
tools = [
Tool(name="KnowledgeBase", func=search_faq,
description="useful for answering common questions from FAQs or policy documents"),
Tool(name="OrderStatus", func=get_order_status,
description="useful for checking the status of an order by order number")
]
# 3. Initialize the LLM and agent
llm = OpenAI(model="gpt-3.5-turbo", temperature=0, openai_api_key="YOUR_OPENAI_API_KEY")
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)
# 4. Simulate user queries
queries = [
"Hi, what's your return policy?",
"Where is my order 12345? It was supposed to be here by now.",
"Do you ship internationally?",
]
for q in queries:
print(f"User: {q}")
response = agent.run(q)
print(f"Agent: {response}\n")
Let’s go through what happens for each query:
- Query 1: “What’s your return policy?” The agent should identify this as a FAQ-type query. The
KnowledgeBasetool likely gets triggered. The agent might think: “This sounds like a common question. Use KnowledgeBase.” It callssearch_faq, which finds “return policy” key and returns the answer. The agent then replies with that answer. The output could be: “Our return policy is: You can return any item within 30 days of purchase with a receipt for a full refund.” (Given we putverbose=True, you would see the chain of thoughts and the tool invocation in the console logs – confirming it used the KnowledgeBase tool.) - Query 2: “Where is my order 12345?” The agent will parse this, likely noticing the pattern “order [number]” and decide to use the OrderStatus tool. It calls
get_order_status("12345"), gets back the dummy status, and responds: “Your order 12345 is currently being processed and will ship in 2 days.” If this question also contained something like “... it was supposed to be here by now”, the agent might combine an apology or explanation along with the tool result. The agent’s LLM can merge tool outputs with a conversational tone. - Query 3: “Do you ship internationally?” Suppose our simple FAQ search doesn’t have a direct match for “ship internationally”.
search_faqmight return "". The agent gets no useful info from that tool (it might try it and see no answer). Now, since we didn’t explicitly code this info, the agent might either A) know from training data (GPT-3.5 might guess a generic answer), or B) say it’s not sure. Ideally, in a real system, we’d have this in our knowledge base. But let’s say it isn’t. The agent might reply, “I’m sorry, I don’t have that information. Let me connect you with a human representative for further assistance.” This would be the fallback behavior. We didn’t explicitly code escalation, but we could: one approach is to have a threshold that if no tool gives an answer and LLM isn’t confident, it says it will escalate. LangChain doesn’t do this automatically, but we can incorporate it via prompt engineering (e.g., in the system message we instruct: “If you are unsure or it’s outside knowledge, respond with a deferral to human.”). For brevity, assume the model handles it gracefully on its own.
Design Decisions: We chose LangChain because it made integrating an information retrieval step straightforward. We used a Zero-shot ReAct agent which decides on its own which tool to use for each query – this dynamic decision-making is crucial in support scenarios (the agent must distinguish informational vs account-specific queries). We kept the tools simple; in production, search_faq could be replaced by a vector search using LlamaIndex or LangChain’s vector store, for more robust semantic matching. The get_order_status tool in real life would query a database. Security-wise, we’d ensure the agent only calls OrderStatus for properly formatted order IDs, etc. The agent’s prompt (handled by LangChain internally for this agent type) includes descriptions of each tool, so it knows when to use them.
This example shows an agent that can automate tier-1 support: answering common questions and handling simple tasks. This frees up human agents to deal with more complex issues. It also shows how combining retrieval (knowledge base) with action (API calls) allows the agent to be both informative and performative.
Example 2: Task Automation Assistant (Email Scheduler Agent)
Use Case: Many professionals spend time on small repetitive tasks, such as scheduling meetings or sending follow-up emails. We’ll create a Task Automation Assistant that can understand a natural language request to schedule a meeting and then perform the steps to actually schedule it (in a simplified manner). Specifically, the agent should:
- Parse a request like “Schedule a meeting with John next week about the Q3 budget.”
- Check the calendars (we’ll simulate calendar availability).
- Propose a time, possibly by consulting both parties’ free times (we’ll simplify with dummy data).
- Draft an email invitation to John with the details.
This is a multi-step workflow: understanding the intent, retrieving data (calendars), making a decision on time, and producing an output (email). It’s a good candidate for a code-centric agent because it involves procedural logic (finding a common free slot). We will use SmolAgents for this, letting the agent write some code to handle the scheduling logic.
Framework choice: SmolAgents allows the agent to use Python tools. We’ll provide:
- A
get_free_slots(person, week)tool that returns free time slots for that person (dummy data). - A
send_email(to, subject, body)tool that doesn’t actually send an email but simulates that action (printing or storing the output). - The agent’s job is to use these to achieve the goal.
Architecture Diagram: Here, we have one agent that will likely utilize multiple tools in sequence. The architecture is simpler (it’s a single agent with tools, like before), but the internal logic is more complex (the agent essentially writes a mini program). We can depict it like: User instruction -> Agent (LLM) -> [calls Calendar Tool for Person A] + [calls Calendar Tool for Person B] -> Agent computes common time -> [calls Email Tool] -> outputs confirmation to user.
We can draw a flow diagram:
- Input: “Schedule meeting with John next week re: Q3 budget.”
- Agent uses Calendar tool for “me” and for “John”.
- Agent finds a matching free slot.
- Agent uses Email tool to draft invite.
- Agent outputs, e.g., “I have scheduled a meeting on [date time] and sent an invite to John.”
We’ll assume it’s okay for the agent to finalize without human confirmation for this demo (though in practice, one might want a confirmation step).
Now, implementing this:
What changed since this was written: the imports still resolve on smolagents 1.26.0 (29 May 2026): OpenAIServerModel is kept as an alias of the renamed OpenAIModel, with no deprecation warning. What breaks is the tool definition. smolagents now builds each tool's JSON schema from the docstring and raises DocstringParsingException ("the docstring has no description for the argument ...") when a @tool function does not describe every argument under an Args: heading, so the two tools in the original block fail before the agent runs. Two more things to know before you copy this pattern: a CodeAgent executes model-written Python, and the docs let you move that execution out of your process with executor_type="docker", "e2b" or "blaxel"; and when your tools are atomic API calls with no logic to compose, ToolCallingAgent (structured JSON calls, no code execution) is the safer default. The version that runs today:
# pip install -U 'smolagents[openai]' (smolagents 1.26.0, September 2026)
from smolagents import tool, CodeAgent, OpenAIModel
FREE_SLOTS = {
"me": ["Mon 10am", "Tue 2pm", "Wed 1pm", "Fri 4pm"],
"john": ["Tue 2pm", "Wed 1pm", "Thu 9am"],
}
@tool
def get_free_slots(person: str, week: str = "next") -> list:
"""Return the free time slots of a person for the coming week.
Args:
person: First name of the person, for example "me" or "john".
week: Which week to look at; only "next" is supported in this demo.
"""
return FREE_SLOTS.get(person.lower(), [])
@tool
def send_email(to: str, subject: str, body: str) -> str:
"""Simulate sending an email and return a confirmation string.
Args:
to: Recipient email address.
subject: Subject line of the email.
body: Plain-text body of the email.
"""
print(f"--- Email to {to} ---\nSubject: {subject}\nBody:\n{body}\n--- End Email ---")
return f"Email sent to {to}"
model = OpenAIModel(model_id="gpt-5", api_key="YOUR_OPENAI_API_KEY") # gpt-3.5-turbo retires on 2026-10-23
agent = CodeAgent(
tools=[get_free_slots, send_email],
model=model,
# executor_type="docker", # or "e2b" / "blaxel": run the model-written code outside your process
)
result = agent.run("Schedule a meeting with John next week about the Q3 budget review.")
print("Agent final response:", result)
The original block, unchanged:
from smolagents import tool, CodeAgent, OpenAIServerModel
# Dummy data: free slots for each person (just simple dict of person -> slots)
FREE_SLOTS = {
"me": ["Mon 10am", "Tue 2pm", "Wed 1pm", "Fri 4pm"],
"john": ["Tue 2pm", "Wed 1pm", "Thu 9am"]
}
@tool
def get_free_slots(person: str, week: str = "next") -> list:
"""Return a list of free time slots for the given person for the next week."""
# Ignoring 'week' in this dummy implementation
person_key = person.lower()
if person_key in FREE_SLOTS:
return FREE_SLOTS[person_key]
else:
return []
@tool
def send_email(to: str, subject: str, body: str) -> str:
"""Simulate sending an email by returning a confirmation string."""
print(f"--- Email to {to} ---\nSubject: {subject}\nBody:\n{body}\n--- End Email ---")
return f"Email sent to {to}"
# Initialize the agent's LLM model (using GPT-3.5 for cost, but GPT-4 might be better for complex tasks)
model = OpenAIServerModel(model_id="gpt-3.5-turbo", api_key="YOUR_OPENAI_API_KEY")
agent = CodeAgent(tools=[get_free_slots, send_email], model=model)
# User request to the agent
request = "Schedule a meeting with John next week about the Q3 budget review."
result = agent.run(request)
print("Agent final response:", result)
When we run agent.run(request), behind the scenes, the agent (GPT-3.5) will receive a prompt listing the tools get_free_slots and send_email with their docstrings, plus the user request. It will ideally output a plan in Python code. The code might look like:
slots_me = get_free_slots("me")
slots_john = get_free_slots("john")
# find a common slot
common = None
for slot in slots_me:
if slot in slots_john:
common = slot
break
if common is None:
print("No common free slot found next week.")
else:
subject = "Meeting invite: Q3 Budget Review"
body = f"Hi John,\n\nCan we meet on {common} next week to discuss the Q3 budget? Let me know if that works for you.\n\nThanks!"
send_email("[email protected]", subject, body)
print(f"Scheduled a meeting on {common}. An invite has been sent to John.")
This is a plausible piece of code the LLM could generate given the task. Let’s analyze it:
- It calls
get_free_slots("me")andget_free_slots("john"). Our dummy functions will return lists of free times. - It then finds the first common slot.
- If found, it prepares an email subject and body, then calls
send_emailwith John’s email, subject, and body. - It prints a confirmation message.
SmolAgents will execute this code. The get_free_slots calls return data from FREE_SLOTS. Suppose "Tue 2pm" is common (from our dummy data, both have Tue 2pm and Wed 1pm as common). It picks "Tue 2pm". Then it calls send_email, which will print the email content:
--- Email to [email protected] ---
Subject: Meeting invite: Q3 Budget Review
Body:
Hi John,
Can we meet on Tue 2pm next week to discuss the Q3 budget? Let me know if that works for you.
Thanks!
--- End Email ---
And send_email returns "Email sent to [email protected]". Finally, it prints the confirmation: "Scheduled a meeting on Tue 2pm. An invite has been sent to John." SmolAgents captures that print output as the agent’s final answer.
The final result printed would be:
Agent final response: Scheduled a meeting on Tue 2pm. An invite has been sent to John.This demonstrates the agent effectively performed the scheduling task autonomously.
Why this design: We used SmolAgents because the problem required a bit of logic (finding common time) that is easier to express in code than in pure natural language prompts. By giving the agent get_free_slots and send_email tools, we allow it to gather info and take action. The agent’s LLM filled in the logic of finding the common slot. If we tried this with a pure LangChain approach, we’d have to rely on the LLM to reason about lists of times without error, which is harder to guarantee. Here, by writing a little loop in code, the LLM can leverage the deterministic nature of Python to get it right.
Extending this: In a real system, get_free_slots would connect to actual calendar APIs, and send_email would actually send an email or create a calendar invite. You might also have more error handling (if no common time, maybe the agent suggests some alternatives or asks for a new time). You might incorporate a human approval – for instance, after the agent finds a time, it could ask “Should I send an invite for Tue 2pm?” (perhaps via a different channel), then proceed. But as a fully automated assistant, the above approach saves you from doing these repetitive checks manually.
This example shows how agentic AI can automate an end-to-end task: from intent to execution. It combined natural language understanding (parsing the request for “with John next week” etc.) with programmatic action. It’s easy to imagine many similar office assistant tasks: booking travel (search flights, pick best option, hold a reservation), preparing a report (gather data, compile into doc), etc. By using frameworks like SmolAgents, we ensure the agent’s steps are auditable and reliable.
Example 3: Internal Knowledge Base Assistant (IT Helpdesk Agent)
Use Case: Large organizations have internal knowledge bases (wikis, SharePoint, documentation) for policies, how-to guides, etc. An internal IT Helpdesk Agent could answer employees’ tech support questions by retrieving relevant info from documentation and even perform simple troubleshooting tasks. For example, an employee asks: “I can’t connect to the VPN, how do I fix it?” The agent should:
- Search the internal docs for “VPN connection issues”.
- Provide the solution steps to the user.
- Possibly open a ticket or suggest escalation if the problem persists.
We’ll build an Internal Knowledge Assistant that uses LlamaIndex to index some mock documents and answer a query. This agent will primarily demonstrate retrieval augmented Q&A, possibly with a chain-of-thought if multiple docs are involved.
Framework choice: LlamaIndex is well-suited as it can handle the indexing of documents and provide a simple agent interface to query them. We will:
- Create two small text “documents”: one with VPN troubleshooting steps, another with general IT policy.
- Index them with LlamaIndex.
- Use an agent or query interface to ask a question and get an answer citing the docs.
Architecture Diagram: This agent’s architecture has an LLM agent that uses a Retrieval Tool (the index) to get info. It’s essentially a context-augmented QA: user query -> agent -> retrieves docs -> agent composes answer. We can illustrate:
- Data: internal docs (like a vector store).
- Agent (LLM) with a retriever tool.
- The agent might not need other tools, or perhaps a ticket logging tool as well. For simplicity, we’ll focus on retrieval and answer.
Diagram: [User query] -> [Agent] -> [LlamaIndex QueryEngine] -> [Relevant doc snippet] -> [Agent answer]. It’s a single-step tool usage in this case.
Step-by-Step Implementation:
What changed since this was written: this block was already on LlamaIndex's old import path when the post went out. Since v0.10.0 (12 February 2024) the core package is llama_index.core, GPTVectorStoreIndex has been renamed VectorStoreIndex, ServiceContext is deprecated in favour of the global Settings object (or an llm= argument passed to as_query_engine), and LLMPredictor is no longer meant to be used: you pass an LLM directly. Every provider is its own package, so the OpenAI LLM comes from llama-index-llms-openai, not from LangChain. On LlamaIndex 0.14.24 (19 August 2026) the same helpdesk assistant is:
# pip install -U llama-index llama-index-llms-openai (llama-index 0.14.24, September 2026)
from llama_index.core import VectorStoreIndex, Document, Settings
from llama_index.llms.openai import OpenAI
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0) # any current model; gpt-3.5-turbo retires on 2026-10-23
doc1_text = """VPN Troubleshooting Guide:
If you cannot connect to the VPN, follow these steps:
1. Check your internet connection.
2. Restart the VPN client application.
3. Ensure your account has VPN access by contacting IT if unsure.
4. If the issue persists, create a support ticket with the IT helpdesk.
"""
doc2_text = """IT Policy - Network Access:
Company VPN is required for accessing internal resources from outside the office.
All employees must use their assigned credentials. If you forget your VPN password, you can reset it via the IT portal or contact support.
"""
docs = [("vpn_guide.txt", doc1_text), ("it_policy.txt", doc2_text)]
documents = [Document(text=t, doc_id=name) for name, t in docs]
index = VectorStoreIndex.from_documents(documents) # embeddings use OPENAI_API_KEY by default
query_engine = index.as_query_engine(similarity_top_k=2)
question = "I can't connect to the VPN. What should I do?"
response = query_engine.query(question)
print("Agent answer:", str(response))
The original block, unchanged:
from llama_index import GPTVectorStoreIndex, SimpleDirectoryReader, ServiceContext, LLMPredictor
from langchain.chat_models import ChatOpenAI
# 1. Prepare documents (simulate reading from files or sources)
doc1_text = """VPN Troubleshooting Guide:
If you cannot connect to the VPN, follow these steps:
1. Check your internet connection.
2. Restart the VPN client application.
3. Ensure your account has VPN access by contacting IT if unsure.
4. If the issue persists, create a support ticket with the IT helpdesk.
"""
doc2_text = """IT Policy - Network Access:
Company VPN is required for accessing internal resources from outside the office.
All employees must use their assigned credentials. If you forget your VPN password, you can reset it via the IT portal or contact support.
"""
# Instead of reading from files, we use in-memory text
docs = [
("vpn_guide.txt", doc1_text),
("it_policy.txt", doc2_text)
]
# In a real scenario, you might have actual text files and use SimpleDirectoryReader or similar.
# 2. Build the index
from llama_index import Document
documents = [Document(text=t, doc_id=name) for name, t in docs]
index = GPTVectorStoreIndex.from_documents(documents)
# 3. Set up LLM for answering
llm_predictor = LLMPredictor(llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0))
service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)
query_engine = index.as_query_engine(service_context=service_context, similarity_top_k=2)
# 4. Ask a question via the query engine
question = "I can't connect to the VPN. What should I do?"
response = query_engine.query(question)
answer = str(response)
print("Agent answer:", answer)
Let’s break it down:
- We created two
Documentobjects containing our text.GPTVectorStoreIndexbuilds an index (embedding-based). Under the hood, it will chunk text, create embeddings (requires an OpenAI key or default embed model). - We then turn the index into a
query_enginewhich we can query in natural language. We setsimilarity_top_k=2to retrieve possibly both docs if relevant. - We ask the question. The LLM (GPT-3.5) will get the relevant text from the VPN guide (and maybe the policy doc if it deems it relevant) and will formulate an answer.
The expected behavior: It should find the VPN Troubleshooting Guide document which directly addresses the question. Likely it will output an answer like:“According to the VPN Troubleshooting Guide, you should:
- Check your internet connection.
- Restart the VPN client.
- Make sure your account has VPN access (contact IT to verify).If the issue persists after these steps, you should open a support ticket with IT helpdesk.”
The query_engine.query already returns a response object that LlamaIndex’s default QueryEngine might format with sources. If response is a Response object, str(response) gives the answer text, and possibly it might include citations if enabled. (We didn’t explicitly enable source citation formatting, but LlamaIndex can provide source text).
We could also use LlamaIndex’s Graph or Workflow to create a tool-using agent, but here the direct query engine suffices.
Considerations: We used similarity_top_k=2 in case the policy doc had something useful (like about credentials). The agent (LLM) might combine info if relevant. For example, if the question was “I can’t connect to VPN and I forgot my password,” the agent might fetch both docs: one for troubleshooting, one for password reset info, and weave them into the answer. LlamaIndex’s Response synthesizer would handle that.
In terms of framework, this showcases a more data-centric approach: rather than a fancy multi-step plan, the agent’s power comes from having access to the right information. For an internal helpdesk, this is crucial – often answers are somewhere in the docs, and the agent’s job is to fetch and relay them, maybe performing minor actions like creating a ticket which could be another tool if we extended it.
For completeness, if we wanted the agent to also create a ticket for the user as a follow-up, we could integrate a create_ticket(issue) tool. The agent after giving the advice could decide if a ticket is needed and call that tool. In LlamaIndex, that would involve using the Tool abstraction and possibly the Workflow to allow a function call. But given the question, we stick to Q&A.
Why LlamaIndex: It simplified indexing data and retrieving it, so we didn’t have to manually manage embeddings or vector stores. It’s designed exactly for this pattern of augmenting LLMs with private data. We could have done similar with LangChain’s RetrievalQA chain, which is also fine; but LlamaIndex might handle more complex documents or retrieval better out-of-the-box (plus it has nice features like combining multiple sources or following query plans if needed).
This example demonstrates how an agent can serve as an on-demand expert by pulling from a knowledge base. Businesses can deploy such agents internally to reduce the load on IT staff or HR (answering policy questions, etc.). It’s like a smarter search engine that gives you a concise answer rather than a bunch of documents to read.
What changed in the frameworks since this was written
Everything below was checked on 3 September 2026 against the projects' own pages (PyPI, the official docs, the source at the tagged release, OpenAI's deprecations page). Where we could not verify a detail we left it out.
- LangChain. 1.0.0 was published on 17 October 2025; the current release is 1.3.18 (27 August 2026), Python 3.10 or later.
create_agentis the standard constructor (it replacedlanggraph.prebuilt.create_react_agent). Legacy chains, retrievers, the indexing API, the hub module and thelangchain-communityre-exports moved tolangchain-classic(1.0.8, 10 June 2026), which is also whereinitialize_agent,AgentExecutorandAgentTypenow import from. Human approval is a middleware:HumanInTheLoopMiddlewarewithinterrupt_onper tool, a checkpointer, andCommand(resume=...)to continue. - smolagents. Current release 1.26.0 (29 May 2026), Python 3.10 or later. The model classes were renamed (
OpenAIServerModelis nowOpenAIModel, with the old name kept as an alias; the family also includesInferenceClientModel,LiteLLMModel,AzureOpenAIModel,AmazonBedrockModel,TransformersModel,MLXModelandVLLMModel). Tool docstrings must describe every argument. Two agent types,CodeAgentandToolCallingAgent; remote code executors viaexecutor_type(Docker, E2B, Blaxel); MCP servers load as tools throughMCPClient. - LlamaIndex. Current release 0.14.24 (19 August 2026), Python 3.10 or later. Since 0.10.0 (12 February 2024): the
llama_index.corenamespace, one package per integration,ServiceContextdeprecated in favour ofSettings,LLMPredictorno longer intended for users, and the GPT-prefixed index classes renamed toVectorStoreIndex. - OpenAI model ids.
gpt-3.5-turbo(an alias ofgpt-3.5-turbo-0125) is scheduled for shutdown on 23 October 2026, withgpt-5.6-terralisted as the replacement;gpt-3.5-turbo-instructon 28 September 2026. The Assistants API was shut down on 26 August 2026 in favour of the Responses and Conversations APIs, and thegpt-5-nano-2025-08-07snapshot is scheduled for 11 December 2026. Pin a model id, and read the deprecations page before each release.
FAQ
What is an agentic AI example?
A working system where a language model chooses actions (tool calls, generated code, a hand-off to a person) in a loop until a task is done, rather than answering once. The catalogue above lists eight. The shortest test is whether you can name the trigger, the tools, the human checkpoint and the failure mode; if any of the four is missing, you have a demo, not an example.
Agentic AI vs a chatbot vs RPA: what is the difference?
A chatbot answers; it does not act. RPA acts, but only along a script someone recorded, and it breaks when the screen or the form changes. An agent chooses which action to take from a set of tools, so it absorbs variation RPA cannot, at the price of being less predictable. In practice the three coexist: RPA for the stable, high-volume steps, an agent for the routing and the exceptions, a chat surface for the conversation.
Which framework should I use for a first agent in Python?
Pick by the shape of the task, not by popularity. If the tools are atomic API calls and you want structured, validated calls, LangChain's create_agent (or smolagents' ToolCallingAgent) with a handful of @tool functions is enough. If the task needs logic the model should write (loops, comparisons, data munging), smolagents' CodeAgent, with the executor moved out of your process. If the job is mostly retrieval over your documents, LlamaIndex gives you a query engine in five lines and you add tools later. All three require Python 3.10 or later in their current releases. Whatever you pick, keep the tool functions in a plain module of your own so you can change framework without rewriting them.
How do you keep a human in the loop?
Decide per tool, not per agent. Reads run freely; reversible writes run with logging; writes that move money, send external messages or delete data pause for approval. In LangChain 1.x this is HumanInTheLoopMiddleware with interrupt_on set per tool (approve, edit, reject or respond) and a checkpointer so the run can pause and resume with Command(resume=...). In smolagents the equivalent is to have the sensitive tool return a proposal and a separate, human-triggered step execute it. A confidence threshold on retrieval, with a hand-off when nothing matches, covers the "answers from training data" failure.
How do you evaluate an agent before production?
Build the test set from the failure column, not from the happy path: each pattern above lists what goes wrong, and those are the cases to write first. Run the agent on 50 to 100 real, anonymised requests, score three things separately (did it pick the right tool, were the arguments correct, was the final answer correct and grounded in a tool result), and log every tool call so a failure can be replayed. Then rerun the same set on every model or prompt change. An agent that is not re-evaluated after a model swap is not evaluated.
What does an agent cost to run?
Tokens multiplied by steps. A single tool-calling turn is one model call; an agent loop is three to ten, and a CodeAgent that retries after an error is more. Estimate it as model calls per task, times the average prompt size (which grows with every tool result fed back), times the price of the model you pinned; then add the tools' own costs (search, OCR, API quotas) and the human review time at the checkpoints. Measure it on your evaluation set, because the step count depends on your tools and prompts, and cap the maximum number of steps so a stuck agent cannot loop on your bill.
Wrap up of the Agentic AI series: Through these examples – a customer service bot, an automation assistant, and an internal knowledge agent – we’ve seen how Agentic AI can be applied to real business needs. Each required slightly different capabilities:
- The Customer Service Agent required multi-modal action (answer vs perform lookup), so we used tools and an agent that can decide between them, showing the benefit of an LLM agent orchestrating functions.
- The Automation Assistant involved executing a procedure on behalf of a user, highlighting how an agent can offload tedious tasks and even write code to handle logic.
- The Knowledge Base Assistant emphasized information retrieval, illustrating how an agent can leverage organizational knowledge to provide immediate answers.
When designing your own agentic solutions, think about the problem in these terms: What knowledge does the agent need? What actions should it be able to take? Then choose a framework that makes it easy to provide that knowledge (documents, APIs) and implement those actions (tools, code execution). By following the patterns in these examples, you can create agents that are not just chatbots, but proactive assistants that truly act on the user’s behalf, bringing substantial efficiency and value to business operations.
Until the next one,
Tega AdeyemiMarch 25, 2025

