Engineering31 min read

Agentic AI Examples: 8 Patterns and 3 Python Builds

A catalogue of eight agentic AI patterns that run in real businesses (trigger, tools, human checkpoint, where they fail), then three Python walkthroughs with LangChain, smolagents and LlamaIndex, re-verified against the September 2026 releases.

Tega Adeyemi
Tega Adeyemi
Agentic AI: Step-by-Step Examples for Business Use Cases

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. 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. 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. 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. 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. 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. 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. 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. 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:

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:

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:

Agentic AI: Step-by-Step Examples for Business Use Cases — Tega Adeyemi | Cohorte
Source: NVIDIA Blog

Step-by-Step Implementation:

  1. 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.
  2. Define tools: We will have faq_search(question) that returns a relevant FAQ answer (if any), and get_order_status(order_id) that returns a fake order status.
  3. Initialize agent: Use LangChain’s initialize_agent with these tools.
  4. 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:

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:

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:

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:

  1. Input: “Schedule meeting with John next week re: Q3 budget.”
  2. Agent uses Calendar tool for “me” and for “John”.
  3. Agent finds a matching free slot.
  4. Agent uses Email tool to draft invite.
  5. 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:

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:

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:

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:

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:

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:

  1. Check your internet connection.
  2. Restart the VPN client.
  3. 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.

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:

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

The script works. Production is a different sport.

The AI OS letter covers the part tutorials skip: verification, trust, what breaks with real users. One idea, every Saturday, from CM, Cohorte's founder, who has shipped 60+ AI systems.

Free weekly. No spam. Unsubscribe in one click.

Subscribed ✓

The next letter arrives Saturday. Go finish the build.