{"id":57698,"date":"2026-10-30T16:44:14","date_gmt":"2026-10-30T11:14:14","guid":{"rendered":"https:\/\/mobisoftinfotech.com\/resources\/?p=57698"},"modified":"2026-10-30T20:31:36","modified_gmt":"2026-10-30T15:01:36","slug":"build-ai-agent-python-openai","status":"publish","type":"post","link":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai","title":{"rendered":"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)"},"content":{"rendered":"<h2 class=\"wp-block-heading\"><strong>The Problem Every Company Website Has<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s 11:40 pm. A potential customer lands on your website while your whole team is asleep. They have a real project, a real budget, and one question: <em>&#8220;Have you built HIPAA-compliant healthcare apps before?&#8221;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Usually, one of three things happens next:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Nobody answers. They fill in a contact form, wait, and sign with a competitor who replied first.<\/li>\n\n\n\n<li>A scripted chatbot answers. It offers a menu of five buttons, none of which match the question.<\/li>\n\n\n\n<li>A generic LLM chatbot answers. It sounds confident and invents a client, a certification, or a price your sales team now has to walk back.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">What if I told you there&#8217;s a fourth option? An AI agent that answers from the company&#8217;s real knowledge, checks its own answer before sending it, and turns the conversation into a qualified lead with a sales brief on the team&#8217;s phones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I built it as a \u201cdigital twin\u201d for Mobisoft Infotech, in about 700 lines of code. This post shows how to build an AI agent in Python like this one, with the code and the design choices that make it safe to put in front of real customers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>TL;DR for busy Leaders<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The agent does four jobs a good sales assistant does, 24\/7:<\/p>\n\n\n\n<figure class=\"wp-block-table table-scroll-mobile\"><table class=\"has-fixed-layout\"><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Job<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>What The Agent Does<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>Why The Business Cares<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Answer<\/td><td class=\"has-text-align-center\" data-align=\"center\">Replies to visitor questions using only the company&#8217;s own knowledge base (a PDF)<\/td><td class=\"has-text-align-center\" data-align=\"center\">Visitors get accurate answers at any hour<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Self-check<\/td><td class=\"has-text-align-center\" data-align=\"center\">A second AI reviews every reply against the facts it retrieved, and blocks or rewrites anything unsupported<\/td><td class=\"has-text-align-center\" data-align=\"center\">No invented clients, prices or promises<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Capture<\/td><td class=\"has-text-align-center\" data-align=\"center\">Collects name, email and project needs, then saves the lead<\/td><td class=\"has-text-align-center\" data-align=\"center\">Conversations become pipeline, not just traffic<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Brief<\/td><td class=\"has-text-align-center\" data-align=\"center\">Writes a sales brief (who, what they need, best-fit services, first-call questions) and pushes it to sales reps&#8217; phones<\/td><td class=\"has-text-align-center\" data-align=\"center\">Sales walks into the first call prepared<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Tech Stack At A Glance<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Python 3.12<\/li>\n\n\n\n<li>OpenAI API (chat, structured outputs, moderation)<\/li>\n\n\n\n<li>BM25 keyword search<\/li>\n\n\n\n<li><code>pypdf<\/code><\/li>\n\n\n\n<li>Gradio for the UI<\/li>\n\n\n\n<li>Pushover for mobile alerts<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">No vector database, no agent framework: one <code>main.py<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>How It Works: One Visitor Message, End To End<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Each message passes cheap input checks, then an agent loop that can call tools, then a second model that reviews the draft before anyone sees it. Leads trigger a sales brief after the reply is sent. That final step turns a helpful assistant into an AI sales agent.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><noscript><img decoding=\"async\" width=\"855\" height=\"796\" src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/img.png\" alt=\"One Visitor Message, End To End\" class=\"wp-image-57724\"><\/noscript><img decoding=\"async\" width=\"855\" height=\"796\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20855%20796%22%3E%3C%2Fsvg%3E\" alt=\"One Visitor Message, End To End\" class=\"wp-image-57724 lazyload\" data-src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/img.png\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A rejected draft gets one rewrite with the reviewer\u2019s feedback; if that fails too, the visitor gets a safe handoff to sales instead of a risky answer. If you\u2019re evaluating <a href=\"https:\/\/www.mobisoftinfotech.com\/services\/ai-agent-development-company\">AI agent development services<\/a>, ask whether every agent includes a review step like this one before replies reach customers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 1: Turn A PDF Into A Knowledge Base The Agent Can Search<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The company&#8217;s knowledge lives in one PDF: a company overview, one chapter per service, engagement models and contact details. Stuffing all of it into every prompt is slow and expensive, so the agent gets only a summary up front and fetches the details on demand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, the PDF is split into named sections. Every service chapter starts with a line like <code>Service: Mobile App Development | Category: ...<\/code>, which makes a clean split point:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">SERVICE_LINE = re.compile(r<span class=\"hljs-string\">\"^Service: (.+?)\\s+\\|\\s+Category: (.+)$\"<\/span>)\n\ndef split_sections(pages):\n    <span class=\"hljs-string\">\"\"<\/span><span class=\"hljs-string\">\"Split the knowledge base into named sections: front matter, one per service, engagement models, contact.\"<\/span><span class=\"hljs-string\">\"\"<\/span>\n    front = <span class=\"hljs-string\">\"\\n\"<\/span>.join(pages&#091;<span class=\"hljs-number\">3<\/span>:<span class=\"hljs-number\">8<\/span>])  <span class=\"hljs-comment\"># About This Document, Company Overview, Service Catalogue<\/span>\n    lines = <span class=\"hljs-string\">\"\\n\"<\/span>.join(pages&#091;<span class=\"hljs-number\">8<\/span>:]).splitlines()\n    sections = {}\n    ...\n    <span class=\"hljs-keyword\">for<\/span> i, line in enumerate(lines):\n        match = SERVICE_LINE.match(line)\n        <span class=\"hljs-keyword\">if<\/span> match:\n            close()  <span class=\"hljs-comment\"># save the previous section<\/span>\n            current_name, current_category = match.group(<span class=\"hljs-number\">1<\/span>), match.group(<span class=\"hljs-number\">2<\/span>)\n            current = &#091;match.group(<span class=\"hljs-number\">1<\/span>), line]\n        <span class=\"hljs-keyword\">else<\/span>:\n            current.append(line)\n    close()\n    <span class=\"hljs-keyword\">return<\/span> front, sections<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The front matter (overview + service catalogue) goes straight into the system prompt. The service chapters stay outside it, behind tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Why BM25 Instead Of A Vector Database?<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For questions that span services (&#8220;Do you work with Flutter?&#8221;, &#8220;Any HIPAA experience?&#8221;), the agent needs search. I chose BM25, the classic keyword-ranking algorithm behind many search engines, in about 15 lines:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">def bm25(query_terms, terms, k1=<span class=\"hljs-number\">1.5<\/span>, b=<span class=\"hljs-number\">0.75<\/span>):\n    length = sum(terms.values())\n    score = <span class=\"hljs-number\">0.0<\/span>\n    <span class=\"hljs-keyword\">for<\/span> term in query_terms:\n        <span class=\"hljs-keyword\">if<\/span> term in terms:\n            idf = math.log(<span class=\"hljs-number\">1<\/span> + (len(chunks) - doc_freq&#091;term] + <span class=\"hljs-number\">0.5<\/span>) \/ (doc_freq&#091;term] + <span class=\"hljs-number\">0.5<\/span>))\n            tf = terms&#091;term]\n            score += idf * tf * (k1 + <span class=\"hljs-number\">1<\/span>) \/ (tf + k1 * (<span class=\"hljs-number\">1<\/span> - b + b * length \/ avg_len))\n    <span class=\"hljs-keyword\">return<\/span> score\n\ndef search_knowledge_base(query, max_results=<span class=\"hljs-number\">5<\/span>):\n    query_terms = tokenize(query)\n    scored = sorted(((bm25(query_terms, terms), i) <span class=\"hljs-keyword\">for<\/span> i, terms in enumerate(chunk_terms)), reverse=<span class=\"hljs-keyword\">True<\/span>)\n    results = &#091;{<span class=\"hljs-string\">\"section\"<\/span>: chunks&#091;i]&#091;<span class=\"hljs-string\">\"section\"<\/span>], <span class=\"hljs-string\">\"text\"<\/span>: chunks&#091;i]&#091;<span class=\"hljs-string\">\"text\"<\/span>]}\n               <span class=\"hljs-keyword\">for<\/span> score, i in scored&#091;:max_results] <span class=\"hljs-keyword\">if<\/span> score &gt; <span class=\"hljs-number\">0<\/span>]\n    <span class=\"hljs-keyword\">return<\/span> results <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">\"No matching passages found in the knowledge base.\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The reasons:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Company questions are keyword-heavy. Technology names, certifications and industries (&#8220;React Native&#8221;, &#8220;HIPAA&#8221;, &#8220;fintech&#8221;) are exactly what keyword search is good at.<\/li>\n\n\n\n<li>Zero infrastructure. No embedding model, no vector store, no extra bill. The index builds in memory at startup.<\/li>\n\n\n\n<li>Easy to debug. When a result is wrong, you can see which words matched.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The tokenizer keeps characters like <code>+<\/code>, <code>#<\/code> and <code>.<\/code> so terms such as <code>c++<\/code>, <code>c#<\/code> and <code>.net<\/code> survive. Small detail, big difference for a software company&#8217;s knowledge base.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For CTOs:<\/strong> Start with the simplest retrieval that fits your content. Move to embeddings or hybrid search when you can show keyword search is missing answers, not before.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 2: Give The Agent Tools, And Let It Decide When To Use Them<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A chatbot replies. An agent decides what to do next: look something up, save a lead, log a gap, then answer. That decision-making comes from tool calling: you describe functions to the model, and it asks you to run them. For the business side of this distinction, read our <a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-chatbot-development-guide-for-businesses\">AI chatbot development guide<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The agent has four tools:<\/p>\n\n\n\n<figure class=\"wp-block-table table-scroll-mobile\"><table class=\"has-fixed-layout\"><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Tool<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>What It Does<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><code>get_service_details<\/code><\/td><td class=\"has-text-align-center\" data-align=\"center\">Returns the full chapter for one service<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><code>search_knowledge_base<\/code><\/td><td class=\"has-text-align-center\" data-align=\"center\">BM25 search across the whole knowledge base<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><code>record_user_details<\/code><\/td><td class=\"has-text-align-center\" data-align=\"center\">Saves a lead (name, email, needs) to <code>logs\/leads.md<\/code><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\"><code>record_unknown_question<\/code><\/td><td class=\"has-text-align-center\" data-align=\"center\">Logs questions the knowledge base can&#8217;t answer<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Each tool is a plain Python function plus a JSON schema. One small trick does a lot of work: the service name is an enum of the real section names, so the model can&#8217;t ask for a service that doesn&#8217;t exist.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">get_service_details_json = {\n    <span class=\"hljs-string\">\"name\"<\/span>: <span class=\"hljs-string\">\"get_service_details\"<\/span>,\n    <span class=\"hljs-string\">\"description\"<\/span>: <span class=\"hljs-string\">\"Get the full knowledge base chapter for one Mobisoft Infotech service \"<\/span>\n                   <span class=\"hljs-string\">\"(offerings, process, technologies, differentiators, FAQs, official URL).\"<\/span>,\n    <span class=\"hljs-string\">\"parameters\"<\/span>: {\n        <span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"object\"<\/span>,\n        <span class=\"hljs-string\">\"properties\"<\/span>: {\n            <span class=\"hljs-string\">\"service_name\"<\/span>: {<span class=\"hljs-string\">\"type\"<\/span>: <span class=\"hljs-string\">\"string\"<\/span>, <span class=\"hljs-string\">\"enum\"<\/span>: <span class=\"hljs-keyword\">list<\/span>(sections)},\n        },\n        <span class=\"hljs-string\">\"required\"<\/span>: &#091;<span class=\"hljs-string\">\"service_name\"<\/span>],\n        <span class=\"hljs-string\">\"additionalProperties\"<\/span>: <span class=\"hljs-keyword\">False<\/span>,\n    },\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>The Agent Loop<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The heart of the agent is a short loop: call the model; if it asks for tools, run them, feed the results back, and call it again, until it gives a final answer.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">MAX_TOOL_ROUNDS = <span class=\"hljs-number\">6<\/span>\n\ndef run_agent(messages, knowledge, leads, activity):\n    response = complete(messages)\n    rounds = <span class=\"hljs-number\">0<\/span>\n    <span class=\"hljs-keyword\">while<\/span> response.choices&#091;<span class=\"hljs-number\">0<\/span>].finish_reason == <span class=\"hljs-string\">\"tool_calls\"<\/span> <span class=\"hljs-keyword\">and<\/span> rounds &lt; MAX_TOOL_ROUNDS:\n        message = response.choices&#091;<span class=\"hljs-number\">0<\/span>].message\n        results = handle_tool_calls(message.tool_calls)\n        messages.append(message)\n        messages.extend(results)\n        <span class=\"hljs-comment\"># Keep everything retrieved this turn: the evaluator checks the reply against it<\/span>\n        knowledge.extend(f<span class=\"hljs-string\">\"&#091;{call.function.name}] {r&#091;'content']}\"<\/span>\n                         <span class=\"hljs-keyword\">for<\/span> call, r in zip(message.tool_calls, results))\n        response = complete(messages)\n        rounds += <span class=\"hljs-number\">1<\/span>\n    <span class=\"hljs-keyword\">return<\/span> response.choices&#091;<span class=\"hljs-number\">0<\/span>].message.content <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">\"\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Three details worth stealing:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A hard cap on rounds (<code>MAX_TOOL_ROUNDS = 6<\/code>) so a confused model can&#8217;t loop forever and burn tokens.<\/li>\n\n\n\n<li>Every tool result is kept in <code>knowledge<\/code>. That list becomes the evidence the evaluator uses in Step 3.<\/li>\n\n\n\n<li>Tools validate their inputs. <code>record_user_details<\/code> refuses to save a lead without a valid email and real project notes, and tells the model what to ask for instead:<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">def record_user_details(email, name=<span class=\"hljs-string\">\"Name not provided\"<\/span>, notes=<span class=\"hljs-string\">\"not provided\"<\/span>):\n    <span class=\"hljs-keyword\">if<\/span> not re.fullmatch(r<span class=\"hljs-string\">\"&#091;^@\\s]+@&#091;^@\\s]+\\.&#091;^@\\s]+\"<\/span>, email.strip()):\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Not recorded: no valid email address yet. Ask the visitor for their email first.\"<\/span>\n    <span class=\"hljs-keyword\">if<\/span> not notes or notes.strip().lower() <span class=\"hljs-keyword\">in<\/span> (<span class=\"hljs-string\">\"not provided\"<\/span>, <span class=\"hljs-string\">\"none\"<\/span>, <span class=\"hljs-string\">\"n\/a\"<\/span>):\n        <span class=\"hljs-keyword\">return<\/span> (<span class=\"hljs-string\">\"Not recorded yet: ask the visitor which services they need and a short description \"<\/span>\n                <span class=\"hljs-string\">\"of their project (and their name, if missing).\"<\/span>)\n    log_lead_markdown(email.strip(), name or <span class=\"hljs-string\">\"Name not provided\"<\/span>, notes)\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"Lead recorded: the visitor's details were saved for the sales team to follow up.\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This is a pattern I&#8217;d recommend to any team building agents: make tool errors instructive. The tool&#8217;s reply is the model&#8217;s next prompt, so a clear &#8220;here&#8217;s what&#8217;s missing&#8221; message gets the conversation back on track.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>record_unknown_question<\/code> is the quiet hero for the business: every question the knowledge base couldn&#8217;t answer lands in a log. That&#8217;s a ready-made list of content gaps for marketing and the website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/mobisoftinfotech.com\/services\/ai-agent-development-company\"><noscript><img decoding=\"async\" width=\"855\" height=\"363\" src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/production-ready-ai-sales-agent.png\" alt=\"AI sales agent automating customer interactions and lead qualification with LLM guardrails.\" class=\"wp-image-57736\" title=\"Production-Ready AI Sales Agent Development\"><\/noscript><img decoding=\"async\" width=\"855\" height=\"363\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20855%20363%22%3E%3C%2Fsvg%3E\" alt=\"AI sales agent automating customer interactions and lead qualification with LLM guardrails.\" class=\"wp-image-57736 lazyload\" title=\"Production-Ready AI Sales Agent Development\" data-src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/production-ready-ai-sales-agent.png\"><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 3: The Agent That Checks Its Own Work<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Anyone learning how to build an AI agent for customers should spend the most time here. This is the part that makes the agent safe to put on a real company website. There are guardrails on both sides of the model.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Input Guardrails: Stop Bad Messages Before They Cost Anything<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Two cheap checks run before the main model sees a message:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Length limit:<\/strong> messages over 2,000 characters are rejected. This limits oversized prompt-injection payloads and runaway token costs.<\/li>\n\n\n\n<li><strong>Moderation:<\/strong> every message goes through OpenAI&#8217;s free moderation endpoint.<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">def is_flagged(message):\n    <span class=\"hljs-string\">\"\"<\/span><span class=\"hljs-string\">\"Input guardrail: OpenAI's moderation endpoint. Fails open so an API hiccup doesn't block real visitors.\"<\/span><span class=\"hljs-string\">\"\"<\/span>\n    <span class=\"hljs-keyword\">try<\/span>:\n        <span class=\"hljs-keyword\">return<\/span> openai.moderations.create(model=<span class=\"hljs-string\">\"omni-moderation-latest\"<\/span>, input=message).results&#091;<span class=\"hljs-number\">0<\/span>].flagged\n    except <span class=\"hljs-keyword\">Exception<\/span> <span class=\"hljs-keyword\">as<\/span> e:\n        <span class=\"hljs-keyword\">print<\/span>(f<span class=\"hljs-string\">\"Moderation check failed: {e}\"<\/span>, flush=<span class=\"hljs-keyword\">True<\/span>)\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">False<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Note the deliberate choice to <em>fail open<\/em> in these <em>LLM guardrails<\/em>: if the moderation API has a hiccup, real customers can still chat. The output evaluator below is the stronger safety net.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Output Guardrail: An Evaluator That Reviews Every Reply<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the core idea: a second LLM call acts as a strict reviewer. Before any reply reaches the visitor, the evaluator gets:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the draft reply,<\/li>\n\n\n\n<li>the visitor&#8217;s message and recent conversation,<\/li>\n\n\n\n<li>and, most importantly, the exact knowledge-base passages retrieved this turn.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">It returns a structured verdict, enforced with a Pydantic model so there&#8217;s no parsing guesswork:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">class Evaluation(BaseModel):\n    is_acceptable: bool\n    feedback: str\n\ndef evaluate(reply, message, history, knowledge):\n    \"\"\"Output guardrail: a second LLM call checks the reply against the knowledge actually retrieved this turn.\"\"\"\n    ...\n    response = openai.chat.completions.parse(\n        model=EVALUATOR_MODEL,\n        messages=&#091;{\"role\": \"system\", \"content\": EVALUATOR_PROMPT},\n                  {\"role\": \"user\", \"content\": user_prompt}],\n        response_format=Evaluation,\n    )\n    return response.choices&#091;0].message.parsed<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The evaluator&#8217;s prompt lists what makes a reply unacceptable:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>facts not supported by the overview or the retrieved extracts (invented services, clients, numbers, certifications)<\/li>\n\n\n\n<li>prices, discounts, timelines or guarantees<\/li>\n\n\n\n<li>answering off-topic requests instead of steering back<\/li>\n\n\n\n<li>abandoning its role or revealing its system prompt<\/li>\n\n\n\n<li>telling the visitor their details were saved when no tool result says <code>Lead recorded<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">That last rule catches a subtle, real failure: models love to say &#8220;I&#8217;ve passed your details to the team&#8221; even when the save failed. The evaluator checks the claim against the actual tool output.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To go deeper on testing reviewers like this one, read our post on <a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-development\/llm-evaluation-for-ai-agent-development\">LLM evaluation for AI agents<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Reject, Rewrite, or Fall Back<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If the evaluator rejects a reply, the agent gets one retry with the evaluator&#8217;s feedback. If the retry fails too, the visitor gets a safe fallback pointing to the sales team.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">for<\/span> attempt in range(<span class=\"hljs-number\">2<\/span>):\n    reply = <span class=\"hljs-keyword\">yield<\/span> from run_agent(messages, knowledge, leads, activity)\n    evaluation = evaluate(reply, message, history, <span class=\"hljs-string\">\"\\n\\n\"<\/span>.join(knowledge))\n    <span class=\"hljs-keyword\">if<\/span> evaluation.is_acceptable:\n        <span class=\"hljs-keyword\">break<\/span>\n    messages.append({<span class=\"hljs-string\">\"role\"<\/span>: <span class=\"hljs-string\">\"assistant\"<\/span>, <span class=\"hljs-string\">\"content\"<\/span>: reply})\n    messages.append({\n        <span class=\"hljs-string\">\"role\"<\/span>: <span class=\"hljs-string\">\"system\"<\/span>,\n        <span class=\"hljs-string\">\"content\"<\/span>: f<span class=\"hljs-string\">\"Your previous reply was rejected by quality control: {evaluation.feedback}\\n\"<\/span>\n                   <span class=\"hljs-string\">\"Write a corrected reply to the visitor's last message. Do not mention the review.\"<\/span>,\n    })\n<span class=\"hljs-keyword\">else<\/span>:\n    reply = FALLBACK_REPLY  <span class=\"hljs-comment\"># \"Our team can help directly at business@...\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The Python <code>for ... else<\/code> is doing real work here: the <code>else<\/code> branch only runs if the loop never hit <code>break<\/code>, meaning both attempts were rejected.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>For CEOs:<\/strong> This is the difference between &#8220;we put ChatGPT on the website&#8221; and &#8220;we put a supervised assistant on the website.&#8221; The worst case is no longer a made-up promise to a client. It&#8217;s a polite handoff to your sales team.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 4: From Chat To Sales Pipeline, Automatically<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Answering questions is nice. Turning a curious visitor into a qualified lead with a ready-to-use brief is what pays for the project. It\u2019s also what makes this an AI lead generation chatbot rather than a smarter FAQ page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Qualify Before You Capture<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The system prompt tells the agent to collect three things before recording a lead: name, email, and what they need. If something&#8217;s missing, it asks in one friendly message. The tool validation from Step 2 enforces the same rule in code, so the prompt and the code back each other up.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>A Structured Sales Brief<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once a lead is recorded, another structured-output call writes a brief for the sales team:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">class<\/span> <span class=\"hljs-selector-tag\">SalesBrief<\/span>(<span class=\"hljs-selector-tag\">BaseModel<\/span>):\n    <span class=\"hljs-selector-tag\">headline<\/span>: <span class=\"hljs-selector-tag\">str<\/span>                   # \"<span class=\"hljs-selector-tag\">Jane<\/span> (<span class=\"hljs-selector-tag\">Acme<\/span> <span class=\"hljs-selector-tag\">Health<\/span>) <span class=\"hljs-selector-tag\">wants<\/span> <span class=\"hljs-selector-tag\">a<\/span> <span class=\"hljs-selector-tag\">HIPAA-compliant<\/span> <span class=\"hljs-selector-tag\">telehealth<\/span> <span class=\"hljs-selector-tag\">app<\/span>\"\n    <span class=\"hljs-selector-tag\">needs<\/span>: <span class=\"hljs-selector-tag\">str<\/span>                      # 1<span class=\"hljs-selector-tag\">-2<\/span> <span class=\"hljs-selector-tag\">sentences<\/span> <span class=\"hljs-selector-tag\">for<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">first<\/span> <span class=\"hljs-selector-tag\">call<\/span>\n    <span class=\"hljs-selector-tag\">recommended_services<\/span>: <span class=\"hljs-selector-tag\">list<\/span><span class=\"hljs-selector-attr\">&#091;str]<\/span> # 1<span class=\"hljs-selector-tag\">-3<\/span> <span class=\"hljs-selector-tag\">best-fit<\/span> <span class=\"hljs-selector-tag\">services<\/span>, <span class=\"hljs-selector-tag\">exact<\/span> <span class=\"hljs-selector-tag\">names<\/span>\n    <span class=\"hljs-selector-tag\">discovery_questions<\/span>: <span class=\"hljs-selector-tag\">list<\/span><span class=\"hljs-selector-attr\">&#091;str]<\/span>  # 3 <span class=\"hljs-selector-tag\">questions<\/span> <span class=\"hljs-selector-tag\">to<\/span> <span class=\"hljs-selector-tag\">ask<\/span> <span class=\"hljs-selector-tag\">on<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">call<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\"><strong>The Model Picks, The Code Links<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s my favorite design decision in the whole project. The model chooses which services fit, but it never writes the links. The code drops any service name that doesn&#8217;t exist and pulls each official URL straight from the knowledge base:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">def format_brief(brief, lead):\n    <span class=\"hljs-comment\"># The model only picks services; names and URLs come from the knowledge base so links can't be made up<\/span>\n    services = &#091;name <span class=\"hljs-keyword\">for<\/span> name in brief.recommended_services <span class=\"hljs-keyword\">if<\/span> name in sections]\n    lines = &#091;\n        f<span class=\"hljs-string\">\"Contact: {lead.get('name', 'Name not provided')} &lt;{lead&#091;'email']}&gt;\"<\/span>,\n        f<span class=\"hljs-string\">\"Needs: {brief.needs}\"<\/span>,\n        <span class=\"hljs-string\">\"Services: \"<\/span> + (<span class=\"hljs-string\">\", \"<\/span>.join(services) <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-string\">\"to be decided on the call\"<\/span>),\n        *(f<span class=\"hljs-string\">\"\u2022 {name}: {service_url(name)}\"<\/span> <span class=\"hljs-keyword\">for<\/span> name in services <span class=\"hljs-keyword\">if<\/span> service_url(name)),\n        <span class=\"hljs-string\">\"Ask on the call:\"<\/span>,\n        *(f<span class=\"hljs-string\">\"\u2022 {question}\"<\/span> <span class=\"hljs-keyword\">for<\/span> question in brief.discovery_questions),\n    ]\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"\\n\"<\/span>.join(lines), services<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The lesson generalizes: let the LLM make judgment calls, and let deterministic code handle facts like URLs, prices and IDs. Hallucinated links become impossible by construction, not by hoping the model behaves.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Straight To The Sales Team&#8217;s Phones<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The brief is saved to <code>logs\/briefs.md<\/code> and pushed to the sales team&#8217;s phones with <a href=\"https:\/\/pushover.net\">Pushover<\/a>, a simple notification API:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">def push(title, message, url=None):\n    <span class=\"hljs-string\">\"\"<\/span><span class=\"hljs-string\">\"Send a Pushover notification. Returns False if Pushover isn't configured.\"<\/span><span class=\"hljs-string\">\"\"<\/span>\n    user, token = os.getenv(<span class=\"hljs-string\">\"PUSHOVER_USER\"<\/span>), os.getenv(<span class=\"hljs-string\">\"PUSHOVER_TOKEN\"<\/span>)\n    <span class=\"hljs-keyword\">if<\/span> not (user <span class=\"hljs-keyword\">and<\/span> token):\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">False<\/span>\n    payload = {<span class=\"hljs-string\">\"user\"<\/span>: user, <span class=\"hljs-string\">\"token\"<\/span>: token, <span class=\"hljs-string\">\"title\"<\/span>: title&#091;:<span class=\"hljs-number\">250<\/span>], <span class=\"hljs-string\">\"message\"<\/span>: message&#091;:PUSHOVER_MAX_CHARS]}\n    <span class=\"hljs-keyword\">if<\/span> url:\n        payload |= {<span class=\"hljs-string\">\"url\"<\/span>: url, <span class=\"hljs-string\">\"url_title\"<\/span>: <span class=\"hljs-string\">\"Service page\"<\/span>}\n    requests.post(PUSHOVER_URL, data=payload, timeout=<span class=\"hljs-number\">10<\/span>).raise_for_status()\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">True<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If Pushover isn&#8217;t configured or fails, the brief is still on disk. Nothing is lost.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The brief also runs after the visitor&#8217;s reply has been sent, so the visitor never waits on sales tooling.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For sales leaders: Your rep gets a phone notification with who the prospect is, what they want, which services fit (with links), and three questions to open the call. No more skimming a chat transcript before dialing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you\u2019re planning <a href=\"https:\/\/mobisoftinfotech.com\/services\/ai-chatbot-development\">AI chatbot development<\/a> for your own site, design this handoff first. Your sales team will use it every day.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 5: Make The Agent&#8217;s Thinking Visible<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Agents are hard to trust when they&#8217;re a black box. So next to the chat, the Gradio app shows a live Agent activity panel: every step, timestamped, as it happens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A typical turn looks like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\">0<span class=\"hljs-selector-class\">.0s<\/span>  \ud83d\udee1\ufe0f <span class=\"hljs-selector-tag\">Moderation<\/span> <span class=\"hljs-selector-tag\">check<\/span>\u2026\n0<span class=\"hljs-selector-class\">.4s<\/span>  \u2705 <span class=\"hljs-selector-tag\">Moderation<\/span> <span class=\"hljs-selector-tag\">passed<\/span>\n0<span class=\"hljs-selector-class\">.4s<\/span>  \ud83e\udde0 <span class=\"hljs-selector-tag\">Thinking<\/span>\u2026\n1<span class=\"hljs-selector-class\">.6s<\/span>  \ud83d\udd0d <span class=\"hljs-selector-tag\">Searching<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">knowledge<\/span> <span class=\"hljs-selector-tag\">base<\/span> <span class=\"hljs-selector-tag\">for<\/span> \"<span class=\"hljs-selector-tag\">HIPAA<\/span> <span class=\"hljs-selector-tag\">healthcare<\/span> <span class=\"hljs-selector-tag\">compliance<\/span>\"\n1<span class=\"hljs-selector-class\">.6s<\/span>  \u21b3 <span class=\"hljs-selector-tag\">found<\/span> 5 <span class=\"hljs-selector-tag\">passages<\/span>\n1<span class=\"hljs-selector-class\">.6s<\/span>  \ud83e\udde0 <span class=\"hljs-selector-tag\">Reading<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">results<\/span>\u2026\n4<span class=\"hljs-selector-class\">.1s<\/span>  \ud83e\uddd1\u200d\u2696\ufe0f <span class=\"hljs-selector-tag\">Evaluator<\/span> <span class=\"hljs-selector-tag\">checking<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">reply<\/span> <span class=\"hljs-selector-tag\">against<\/span> <span class=\"hljs-selector-tag\">the<\/span> <span class=\"hljs-selector-tag\">retrieved<\/span> <span class=\"hljs-selector-tag\">knowledge<\/span>\u2026\n5<span class=\"hljs-selector-class\">.3s<\/span>  \u2705 <span class=\"hljs-selector-tag\">Reply<\/span> <span class=\"hljs-selector-tag\">approved<\/span>\n5<span class=\"hljs-selector-class\">.3s<\/span>  \ud83c\udfc1 <span class=\"hljs-selector-tag\">Done<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><em>(Timings are illustrative; they depend on the model and network.)<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The trick that makes it live is Python generators. The agent loop, the chat handler and the sales brief are all generators that <code>yield<\/code> after each step. Gradio streams every yield to the browser, so the panel updates while the model is still working:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">class Activity:\n    \"\"\"The live 'agent brain' log shown next to the chat: one line per step, with the time since the turn began.\"\"\"\n\n    def __init__(self):\n        self.start = time.monotonic()\n        self.steps = &#091;]\n\n    def add(self, text):\n        self.steps.append(f\"`{time.monotonic() - self.start:4.1f}s` {text}\")\n\n\ndef respond(message, history):\n    \"\"\"Gradio handler: streams the chat and the activity panel together.\"\"\"\n    activity = Activity()\n    ...\n    for reply in chat(message, previous, activity):\n        if reply is not None:\n            history = history + &#091;{\"role\": \"assistant\", \"content\": reply}]\n        yield \"\", history, activity.markdown()<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\"><code>yield from run_agent(...)<\/code> lets the inner loop stream its steps up through <code>chat()<\/code> and still return the final reply. No threads, no queues, no websockets to manage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The panel helps three audiences at once:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Developers debug prompts and tools in real time.<\/li>\n\n\n\n<li>CTOs see exactly where latency and cost go: retrieval, generation, or evaluation.<\/li>\n\n\n\n<li>Executives and clients watching a demo see an assistant that looks things up and gets checked, not a box that makes things up.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Watch the Full Agent Demo<\/strong><\/p>\n\n\n\n<div class=\"video-container\" title=\"What is a Microinteraction? Understanding Microinteractions in UI Design\">\n    <video autoplay muted loop class=\"w-100\">\n        <source src=\"https:\/\/mobisoftinfotech.com\/assets\/images\/blog\/ai-agent-python-openai\/make-agents-thinking-visible-1.mp4\">\n        Your browser does not support the video tag.\n    <\/video>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Production Readiness: The CTO&#8217;s Checklist<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before an agent faces real customers, a CTO will ask whether it&#8217;s safe, affordable and maintainable. Here&#8217;s how the design answers each concern.<\/p>\n\n\n\n<figure class=\"wp-block-table table-scroll-mobile\"><table class=\"has-fixed-layout\"><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\"><strong>Concern<\/strong><\/td><td class=\"has-text-align-center\" data-align=\"center\"><strong>How The Design Handles It<\/strong><\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Hallucination<\/td><td class=\"has-text-align-center\" data-align=\"center\">Answers grounded in retrieved passages; an evaluator checks each reply against them<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Made-up links or data<\/td><td class=\"has-text-align-center\" data-align=\"center\">Facts like URLs come from code, never from the model<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Prompt injection<\/td><td class=\"has-text-align-center\" data-align=\"center\">Input length cap, moderation, explicit security rules in the system prompt, evaluator checks for role-breaking<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Runaway cost<\/td><td class=\"has-text-align-center\" data-align=\"center\">Caps on tool rounds (6), history (20 messages), reply length (4,000 tokens) and input (2,000 chars)<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Vendor flexibility<\/td><td class=\"has-text-align-center\" data-align=\"center\">Chat and evaluator models are environment variables (<code>MODEL_NAME<\/code>, <code>EVALUATOR_MODEL<\/code>)<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Content updates<\/td><td class=\"has-text-align-center\" data-align=\"center\">Replace the PDF and restart; no retraining, no re-embedding<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">Privacy<\/td><td class=\"has-text-align-center\" data-align=\"center\">Leads live in local log files kept out of version control; briefs pushed via Pushover include the lead&#8217;s name and email<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The honest trade-off: the evaluator adds one extra LLM call per reply (two more on a retry). For a sales-facing assistant, I think that&#8217;s cheap insurance. For high-volume support, you might run the evaluator on a smaller model or sample a share of replies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What To Measure Once It&#8217;s Live<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lead capture rate: conversations that end in a recorded lead<\/li>\n\n\n\n<li>Evaluator rejection rate, and what it rejects (a direct signal for prompt and knowledge-base fixes)<\/li>\n\n\n\n<li>Fallback rate: how often both attempts fail<\/li>\n\n\n\n<li>Unanswered questions per week, and how many you close by updating the knowledge base<\/li>\n\n\n\n<li>Time from lead to first sales contact<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Not sure which of these numbers should drive your roadmap? Our <a href=\"https:\/\/www.mobisoftinfotech.com\/services\/ai-strategy-consulting\">enterprise AI consulting<\/a> team helps set those targets before launch.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Lessons Learned<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prompts ask, code enforces. Every important rule (valid email, real project notes, real service names, real URLs) is in the prompt and checked in code.<\/li>\n\n\n\n<li>Instructive tool errors beat silent failures. A tool that says &#8220;ask for the email first&#8221; steers the model better than one that throws.<\/li>\n\n\n\n<li>Give the reviewer the evidence. An evaluator that only sees the reply can judge tone. One that sees the retrieved passages can judge truth.<\/li>\n\n\n\n<li>Separate judgment from facts. The LLM picks the services; the code supplies the links.<\/li>\n\n\n\n<li>Keep the slow work off the user&#8217;s path. The sales brief runs after the reply is delivered.<\/li>\n\n\n\n<li>Start simple. BM25 and one Python file got this to a working, demo-ready agent. Add frameworks and vector stores when the problem demands them.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What&#8217;s Next<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Hybrid search (BM25 + embeddings) if the unanswered-questions log shows keyword search missing paraphrased questions<\/li>\n\n\n\n<li>CRM integration so leads land in HubSpot or Salesforce instead of a Markdown file<\/li>\n\n\n\n<li>An evaluation suite of real visitor questions, run on every prompt change to catch regressions<\/li>\n\n\n\n<li>Analytics dashboard for the metrics above<\/li>\n\n\n\n<li>Embeddable website widget instead of the standalone Gradio app<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Which of these would your team need first? Most depend on your CRM, data and website stack. An experienced <a href=\"https:\/\/mobisoftinfotech.com\/services\/artificial-intelligence\">artificial intelligence development company<\/a> can plan these upgrades around the systems you already run.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion: The Bar For Website AI Just Went Up<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A chatbot that only talks is no longer enough. Visitors expect accurate answers, and businesses need those answers to be safe and to turn into revenue.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This agent shows you can get all three with a small, readable codebase: grounded answers from your own knowledge, a reviewer that checks every reply before it&#8217;s sent, and a lead pipeline that hands sales a ready brief.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;re a developer, take the patterns: tool validation, evidence-based evaluation, and &#8220;the model picks, the code links.&#8221; If you&#8217;re a CTO or CEO, ask one question of any AI you put in front of customers: <em>who checks its answers before the customer sees them?<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Want to try it? The full source is one <code>main.py<\/code>: swap in your own knowledge-base PDF (same section layout) and update the company-specific prompts, add an OpenAI key, and run <code>python main.py<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can download the agent code <a href=\"https:\/\/github.com\/mobisoftinfotech\/mobisoft-programming-blogs-examples\/tree\/main\/python\/mobisoft-ai-assistant\"><strong>here<\/strong><\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/mobisoftinfotech.com\/contact-us\"><noscript><img decoding=\"async\" width=\"855\" height=\"363\" src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/ai-chatbot-business-lead-generation.png\" alt=\"AI chatbot for business automating customer support and sales lead generation.\" class=\"wp-image-57740\" title=\"Custom AI Chatbot Development for Business\"><\/noscript><img decoding=\"async\" width=\"855\" height=\"363\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20855%20363%22%3E%3C%2Fsvg%3E\" alt=\"AI chatbot for business automating customer support and sales lead generation.\" class=\"wp-image-57740 lazyload\" title=\"Custom AI Chatbot Development for Business\" data-src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/ai-chatbot-business-lead-generation.png\"><\/a><\/figure>\n\n\n\n<div class=\"related-posts-section\">\n<h2>Related Posts<\/h2>\n\n<ul class=\"related-posts-list\">\n<li><a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/conversational-ai-chatbots\">Conversational AI Chatbots: How Businesses Are Redefining Customer Engagement in 2026<\/a><\/li>\n<li><a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-chatbot-for-customer-service\">How Businesses Use an AI Chatbot for Customer Service to Scale Support<\/a><\/li>\n<li><a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-agent-development-production-guide\">AI Agent Development: What CTOs Need to Get Right Before Shipping to Production\n<\/a><\/li>\n<li><a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-machine-learning\/custom-ai-agent-development-crew-ai-framework\">Custom AI Agent Development: How To Create AI Agents With Crew AI Agent Framework With Function Calling Support<\/a><\/li>\n<li><a href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/ai-machine-learning\/build-ai-agents-crewai-framework\">AI Agent Framework Tutorial: Building AI Agents using CrewAI<\/a><\/li>\n\n<\/ul>\n\n<\/div>\n<style>\n.related-posts-section {\n    background-color: #F8F9FA;\n    padding: 30px;\n    margin: 40px 0;\n    border-top: 2px solid #006AFF;\n} \n.related-posts-section .post-content ul {\n    list-style-type: none;\n}\n.related-posts-list {\n    list-style: none;\n    padding: 0;\n    margin: 0;\n    padding-left:3px;\n}\n.related-posts-section .post-content li {\n    position: relative;\n    margin: 10px 0;\n}\n.related-posts-section .post-content p, .related-posts-section .post-content li {\n    font-size: 18px;\n    font-weight: 500;\n    line-height: 2;\n    color: #1e1e1e;\n    text-align: left;\n    margin: 20px 0 30px;\n}\n.related-posts-list li {\n    margin-bottom: 12px;\n    padding-left: 20px;\n    position: relative;\n}\n.related-posts-list li a {\n    color: #495057;\n    text-decoration: none;\n    font-size: 14px;\n    line-height: 1.5;\n    transition: color 0.3s ease;\n}\n.related-posts-list li a:hover {\n    color: #006AFF;\n    text-decoration: none;\n}\n@media (max-width: 768px) {\n    .related-posts-section {\n        padding: 20px; \n    }\n    .related-posts-list related-posts-list ul {\n        padding-left: 20px !important; \n    }\n}\n<\/style>\n\n\n<div class=\"faq-section\"><h2>Frequently Asked Questions<\/h2><div class=\"faq-container\"><div class=\"faq-item\"><div class=\"faq-question-static\"><h3>What if our company knowledge lives in many documents?<\/h3><\/div><div class=\"faq-answer-static\"><p>The agent can search several sources at once. Say service details sit in Confluence and case studies in SharePoint. We\u2019d split both into named sections and tag each passage. That lets the AI chatbot for business cite where an answer came from.<\/p>\n<\/div><\/div><div class=\"faq-item\"><div class=\"faq-question-static\"><h3>Can Mobisoft Infotech connect the agent to our CRM?<\/h3><\/div><div class=\"faq-answer-static\"><p>Yes, we can swap the Markdown log for a HubSpot or Salesforce call. A valid email creates a contact with the sales brief attached. Your rep won\u2019t dig through chat logs anymore. Leads from the AI lead generation chatbot then join your existing pipeline.<\/p>\n<\/div><\/div><div class=\"faq-item\"><div class=\"faq-question-static\"><h3>How do we test the agent before customers see it?<\/h3><\/div><div class=\"faq-answer-static\"><p>Collect 50 real questions from your sales inbox with correct answers. We\u2019d rerun that set after every prompt change. Say a fix for \u201cDo you work with Flutter?\u201d breaks a HIPAA answer. You\u2019ll catch it early, and the tests prove your LLM guardrails hold up.<\/p>\n<\/div><\/div><div class=\"faq-item\"><div class=\"faq-question-static\"><h3>What affects the monthly running cost of our agent?<\/h3><\/div><div class=\"faq-answer-static\"><p>Model calls per reply matter most, since the evaluator adds one to each. Three visitor questions mean at least six calls. You\u2019ll save by moving the evaluator to a cheaper mini model. History and length caps also stop one long chat from inflating your bill.<\/p>\n<\/div><\/div><div class=\"faq-item\"><div class=\"faq-question-static\"><h3>Will Mobisoft Infotech hand over code our team can maintain?<\/h3><\/div><div class=\"faq-answer-static\"><p>Yes, you\u2019ll receive the source and a runbook. We\u2019d build an AI agent in Python with plain, readable functions. Updating content means swapping the knowledge-base PDF and restarting the app. Engineers handle only prompt edits and new tools.<\/p>\n<\/div><\/div><\/div><\/div>\n\n\n    <style>\n    .ai-disclaimer-box {\n        max-width: 1400px;\n        margin: 40px auto;\n        padding: 22px 30px;\n        background: #F8F9FA;\n        text-align: center;\n    }\n    .ai-disclaimer-box p {\n        margin: 0 !important;\n        color: #5b5b5b;\n        font-size: 13px;\n        line-height: 1.7;\n        font-weight: 500;\n    }\n    @media (max-width: 768px) {\n        .related-posts-section, .faq-section {\n            padding: 20px; \n        }\n    }\n    <\/style>\n    <div class=\"ai-disclaimer-box\">\n        <p>\n            This content is for informational purposes only and may include AI-assisted research or content generation. While we strive for accuracy, information may evolve over time. Readers are advised to independently verify critical information before making decisions.\n        <\/p>\n    <\/div>\n    \n\n\n<div class=\"modern-author-card\">\n    <div class=\"author-card-content\">\n        <div class=\"author-info-section\">\n            <div class=\"author-avatar\">\n                <noscript><img decoding=\"async\" src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2023\/08\/prashant.png\" alt=\"Prashant Telangi\"><\/noscript><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" alt=\"Prashant Telangi\" data-src=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2023\/08\/prashant.png\" class=\" lazyload\">\n            <\/div>\n            <div class=\"author-details\">\n                <h3 class=\"author-name\">Prashant Telangi<\/h3>\n                <p class=\"author-title\">Head of Technology, Mobile<\/p>\n                <a href=\"javascript:void(0);\" class=\"read-more-link read-more-btn\" onclick=\"toggleAuthorBio(this); return false;\">Read more <noscript><img decoding=\"async\" src=\"\/assets\/images\/blog\/Vector.png\" alt=\"expand\" class=\"read-more-arrow down-arrow\"><\/noscript><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" alt=\"expand\" class=\"read-more-arrow down-arrow lazyload\" data-src=\"\/assets\/images\/blog\/Vector.png\"><\/a>\n                <div class=\"author-bio-expanded\">\n                    <p>Prashant Telangi brings over 15 years of experience in Mobile Technology, He is currently serving as Head of Technology, Mobile at <a href=\"https:\/\/mobisoftinfotech.com\" target=\"_blank\">Mobisoft Infotech<\/a>. With a proven history in IT and services, he is a skilled, passionate developer specializing in Mobile Applications. His strong engineering background underscores his commitment to crafting innovative solutions in the ever-evolving tech landscape.<\/p>\n                    <div class=\"author-social-links\"><div class=\"social-icon\"><a href=\"https:\/\/www.linkedin.com\/in\/prashant-telangi-83816918\/\" target=\"_blank\" rel=\"nofollow noopener\"><i class=\"icon-sprite linkedin\"><\/i><\/a>\n                     <a href=\"https:\/\/twitter.com\/PrashantAnna\" target=\"_blank\" rel=\"nofollow noopener\"><i class=\"icon-sprite twitter\"><\/i><\/a>\n                     <a href=\"https:\/\/www.facebook.com\/prashant.telangi\/\" target=\"_blank\" rel=\"nofollow noopener\"><i class=\"icon-sprite facebook\"><\/i><\/a><\/div><\/div>\n                    <a href=\"javascript:void(0);\" class=\"read-more-link read-less-btn\" onclick=\"toggleAuthorBio(this); return false;\" style=\"display: none;\">Read less <noscript><img decoding=\"async\" src=\"\/assets\/images\/blog\/Vector.png\" alt=\"collapse\" class=\"read-more-arrow up-arrow\"><\/noscript><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" alt=\"collapse\" class=\"read-more-arrow up-arrow lazyload\" data-src=\"\/assets\/images\/blog\/Vector.png\"><\/a>\n                <\/div>\n            <\/div>\n        <\/div>\n        <div class=\"share-section\">\n            <span class=\"share-label\">Share Article<\/span>\n            <div class=\"social-share-buttons\">\n                <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fmobisoftinfotech.com%2Fresources%2Fblog%2Fbuild-ai-agent-python-openai\" target=\"_blank\" class=\"share-btn facebook-share\"><i class=\"fa fa-facebook-f\"><\/i><\/a>\n                <a href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=https%3A%2F%2Fmobisoftinfotech.com%2Fresources%2Fblog%2Fbuild-ai-agent-python-openai\" target=\"_blank\" class=\"share-btn linkedin-share\"><i class=\"fa fa-linkedin\"><\/i><\/a>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n\n<style>\n\n.wp-block-table.table-scroll-mobile td, .wp-block-table.table-scroll-mobile th\n{\nborder:1px solid black;\n}\n\n\ntable th,\ntable td {\n    border: 1px solid #000;\n    padding: 10px;\ntext-align:center;\n}\n    .post-content li:before {\n        top: 8px;\n    }\n\n    .post-details-title {\n        font-size: 42px\n    }\n\n    h6.wp-block-heading {\n        line-height: 2;\n    }\n\n    .social-icon {\n        text-align: left;\n    }\n\n    span.bullet {\n        position: relative;\n        padding-left: 20px;\n    }\n\n    .ta-l,\n    .post-content .auth-name {\n        text-align: left;\n    }\n\n    span.bullet:before {\n        content: '';\n        width: 9px;\n        height: 9px;\n        background-color: #0d265c;\n        border-radius: 50%;\n        position: absolute;\n        left: 0px;\n        top: 3px;\n    }\n\n    .post-content p {\n        margin: 20px 0 20px;\n    }\n\n    .image-container {\n        margin: 0 auto;\n        width: 50%;\n    }\n\n    h5.wp-block-heading {\n        font-size: 18px;\n        position: relative;\n\n    }\n\n    h4.wp-block-heading {\n        font-size: 20px;\n        position: relative;\n\n    }\n\n    h3.wp-block-heading {\n        font-size: 22px;\n        position: relative;\n\n    }\n\n    .para-after-small-heading {\n        margin-left: 40px !important;\n    }\n\n    h4.wp-block-heading.h4-list,\n    h5.wp-block-heading.h5-list {\n        padding-left: 20px;\n        margin-left: 20px;\n    }\n\n    h3.wp-block-heading.h3-list {\n        position: relative;\n        font-size: 20px;\n        margin-left: 20px;\n        padding-left: 20px;\n    }\n\n    h4.wp-block-heading.h3-list {\n        position: relative;\n        font-size: 20px;\n        margin-left: 20px;\n        padding-left: 20px;\n    }\n\n    table td {\n        border: 1px solid #000;\n        padding: 5px 10px;\n        font-size: 18px;\n        font-weight: 500;\n        line-height: 2;\n        color: #1e1e1e;\n    }\n\n    h3.wp-block-heading.h3-list:before,\n    h4.wp-block-heading.h4-list:before,\n    h5.wp-block-heading.h5-list:before {\n        position: absolute;\n        content: '';\n        background: #0d265c;\n        height: 9px;\n        width: 9px;\n        left: 0;\n        border-radius: 50px;\n        top: 8px;\n    }\n\n    .post-content li:before {\n        top: 12px;\n    }\n\n    @media only screen and (max-width: 991px) {\n        ul.wp-block-list.step-9-ul {\n            margin-left: 0px;\n        }\n\n        .step-9-h4 {\n            padding-left: 0px;\n        }\n\n        .post-content li {\n            padding-left: 25px;\n        }\n\n        .post-content li:before {\n            content: '';\n            width: 9px;\n            height: 9px;\n            background-color: #0d265c;\n            border-radius: 50%;\n            position: absolute;\n            left: 0px;\n            top: 8px;\n        }\n    }\n       .wp-block-table.table-scroll-mobile {\n            overflow-x: auto;\n            -webkit-overflow-scrolling: touch;\n            display: block;\n            width: 100%;\n        }\n\n        .wp-block-table.table-scroll-mobile table {\n            min-width: 340px;\n            width: 100%;\n        }\n\n        .wp-block-table.table-scroll-mobile td,\n        .wp-block-table.table-scroll-mobile th {\n            white-space: wrap;\n            padding: 10px 12px;\n        }\n    @media (max-width:767px) {\n        .image-container {\n            width: 90% !important;\n        }\n       .wp-block-table.table-scroll-mobile {\n            overflow-x: auto;\n            -webkit-overflow-scrolling: touch;\n            display: block;\n            width: 100%;\n        }\n\n        .wp-block-table.table-scroll-mobile table {\n            min-width: 340px;\n            width: 100%;\n        }\n\n        .wp-block-table.table-scroll-mobile td,\n        .wp-block-table.table-scroll-mobile th {\n            white-space: wrap;\n            padding: 10px 12px;\n        }\n    }\n\n\n\n\n\n.wp-block-table table {\n \twidth: 100%;\n \tborder-collapse: collapse;\n }\n \n.wp-block-table th,\n .wp-block-table td {\n \ttext-align: left !important;\n \tvertical-align: middle;\n \tpadding: 12px 15px;\n }\n .wp-block-table table.has-fixed-layout {\n \twidth: 100%;\n }\n \n.wp-block-table table.has-fixed-layout td,\n .wp-block-table table.has-fixed-layout th {\n \ttext-align: left !important;\n \tvertical-align: top !important;\n \tpadding: 12px 15px;\n }\n\n<\/style>\n\n\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"Article\",\n  \"headline\": \"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\",\n  \"description\": \"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.  \",\n  \"image\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png\",\n  \"author\": {\n    \"@type\": \"Person\",\n    \"name\": \"Prashant Telangi\",\n    \"description\": \"Prashant Telangi brings over 14 years of experience in Mobile Technology, He is currently serving as Head of Technology, Mobile at Mobisoft Infotech. With a proven history in IT and services, he is a skilled, passionate developer specializing in Mobile Applications. His strong engineering background underscores his commitment to crafting innovative solutions in the ever-evolving tech landscape.\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"Mobisoft Infotech\",\n    \"logo\": {\n      \"@type\": \"ImageObject\",\n      \"url\": \"https:\/\/mobisoftinfotech.com\/assets\/mobisoft-logo.png\"\n    }\n  },\n  \"datePublished\": \"2026-10-30T00:00:00Z\",\n  \"dateModified\": \"2026-10-30T00:00:00Z\",\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai \"\n  },\n  \"keywords\": \"how to build an AI agent, AI sales agent, LLM guardrails, AI lead generation chatbot, AI chatbot for business, build an AI agent in Python,\",\n  \"articleSection\": \"Startup Guides\",\n  \"wordCount\": 9400,\n  \"inLanguage\": \"en-US\",\n  \"isAccessibleForFree\": true\n}\n<\/script>\n\n\n\n<script type=\"application\/ld+json\">\n{ \"@context\":\"https:\/\/schema.org\",\"@type\":\"BreadcrumbList\",\"itemListElement\":[\n  {\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/mobisoftinfotech.com\"},\n  {\"@type\":\"ListItem\",\"position\":2,\"name\":\"Resources\",\"item\":\"https:\/\/mobisoftinfotech.com\/resources\"},\n  {\"@type\":\"ListItem\",\"position\":3,\"name\":\"Blog\",\"item\":\"https:\/\/mobisoftinfotech.com\/resources\/blog\"},\n  {\"@type\":\"ListItem\",\"position\":4,\"name\":\"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\",\n   \"item\":\"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai \"}]}<\/script>\n\n\n\n<script type=\"application\/ld+json\">\n        {\n            \"@context\": \"https:\/\/schema.org\",\n            \"@type\": \"WebPage\",\n            \"@id\": \"https:\/\/mobisoftinfotech.com\/products\/build-ai-agent-python-openai\/#webpage\",\n            \"url\": \"https:\/\/mobisoftinfotech.com\/products\/build-ai-agent-python-openai\",\n            \"name\": \"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\",\n            \"headline\": \"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\",\n            \"description\": \"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture. \",\n            \"inLanguage\": \"en-US\",\n            \"datePublished\": \"2026-10-30\",\n            \"dateModified\": \"2026-10-30\",\n            \"isPartOf\": {\n                \"@type\": \"WebSite\",\n                \"@id\": \"https:\/\/mobisoftinfotech.com\/#website\",\n                \"url\": \"https:\/\/mobisoftinfotech.com\/\",\n                \"name\": \"Mobisoft Infotech\"\n            },\n            \"publisher\": {\n                \"@type\": \"Organization\",\n                \"name\": \"Mobisoft Infotech\",\n                \"url\": \"https:\/\/mobisoftinfotech.com\/\",\n                \"logo\": {\n                    \"@type\": \"ImageObject\",\n                    \"url\": \"https:\/\/mobisoftinfotech.com\/assets\/images\/mi-logo.svg\",\n                    \"width\": 250,\n                    \"height\": 60\n                }\n            },\n            \"primaryImageOfPage\": {\n                \"@type\": \"ImageObject\",\n                    \"url\": \"https:\/\/cdn.mobisoftinfotech.com\/assets\/images\/services\/devops\/devops-banner.webp\",\n                    \"width\": 1200,\n                \"height\": 628\n            }\n        }\n    <\/script>\n\n\n\n\n<script type=\"application\/ld+json\">\n        {\n            \"@context\": \"https:\/\/schema.org\",\n            \"@graph\": [{\n                    \"@type\": \"Organization\",\n                    \"@id\": \"https:\/\/mobisoftinfotech.com\/#organization\",\n                    \"name\": \"Mobisoft Infotech\",\n                    \"url\": \"https:\/\/mobisoftinfotech.com\",\n                    \"logo\": \"https:\/\/mobisoftinfotech.com\/assets\/images\/mi-logo.svg\",\n                    \"sameAs\": [\n                        \"https:\/\/www.facebook.com\/pages\/Mobisoft-Infotech\/131035500270720\",\n                        \"https:\/\/x.com\/MobisoftInfo\",\n                        \"https:\/\/www.linkedin.com\/company\/mobisoft-infotech\",\n                        \"https:\/\/in.pinterest.com\/mobisoftinfotech\/\",\n                        \"https:\/\/www.instagram.com\/mobisoftinfotech\/\",\n                        \"https:\/\/github.com\/MobisoftInfotech\",\n                        \"https:\/\/www.behance.net\/MobisoftInfotech\"\n                    ]\n                },\n                {\n                    \"@type\": \"LocalBusiness\",\n                    \"@id\": \"https:\/\/mobisoftinfotech.com\/\",\n                    \"name\": \"Mobisoft Infotech - Houston\",\n                    \"address\": {\n                        \"@type\": \"PostalAddress\",\n                        \"streetAddress\": \"5718 Westheimer Rd Suite 1000\",\n                        \"addressLocality\": \"Houston\",\n                        \"addressRegion\": \"TX\",\n                        \"postalCode\": \"77057\",\n                        \"addressCountry\": \"USA\"\n                    },\n                    \"telephone\": \"+1-855-572-2777\",\n                    \"areaServed\": [\"USA\", \"Worldwide\"],\n                    \"parentOrganization\": {\n                        \"@id\": \"https:\/\/mobisoftinfotech.com\/\"\n                    },\n                    \"sameAs\": [\n                        \"https:\/\/share.google\/oRFDC72CfgAl26PBJ\"\n                    ]\n                },\n                {\n                    \"@type\": \"LocalBusiness\",\n                    \"@id\": \"https:\/\/mobisoftinfotech.com\/\",\n                    \"name\": \"Mobisoft Infotech - Pune\",\n                    \"address\": {\n                        \"@type\": \"PostalAddress\",\n                        \"streetAddress\": \"Unit No. 3, Second Floor, Trident Business Center, Pune Banglore Highway Pashan Exit, opposite Audi Showroom, Baner\",\n                        \"addressLocality\": \"Pune\",\n                        \"addressRegion\": \"Maharashtra\",\n                        \"postalCode\": \"411069\",\n                        \"addressCountry\": \"India\"\n                    },\n                    \"telephone\": \"+91-858-600-8627\",\n                    \"areaServed\": [\"India\", \"Worldwide\"],\n                    \"parentOrganization\": {\n                        \"@id\": \"https:\/\/mobisoftinfotech.com\/\"\n                    },\n                    \"sameAs\": [\n                        \"https:\/\/share.google\/TqfQUpZd1fCgKUqbr\"\n                    ]\n                }\n            ]\n        }\n    <\/script>\n\n\n\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [{\n    \"@type\": \"Question\",\n    \"name\": \"What if our company knowledge lives in many documents?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"The agent can search several sources at once. Say service details sit in Confluence and case studies in SharePoint. We\u2019d split both into named sections and tag each passage. That lets the AI chatbot for business cite where an answer came from.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"Can Mobisoft Infotech connect the agent to our CRM?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Yes, we can swap the Markdown log for a HubSpot or Salesforce call. A valid email creates a contact with the sales brief attached. Your rep won\u2019t dig through chat logs anymore. Leads from the AI lead generation chatbot then join your existing pipeline.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"How do we test the agent before customers see it?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Collect 50 real questions from your sales inbox with correct answers. We\u2019d rerun that set after every prompt change. Say a fix for \u201cDo you work with Flutter?\u201d breaks a HIPAA answer. You\u2019ll catch it early, and the tests prove your LLM guardrails hold up.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"What affects the monthly running cost of our agent?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Model calls per reply matter most, since the evaluator adds one to each. Three visitor questions mean at least six calls. You\u2019ll save by moving the evaluator to a cheaper mini model. History and length caps also stop one long chat from inflating your bill.\"\n    }\n  },{\n    \"@type\": \"Question\",\n    \"name\": \"Will Mobisoft Infotech hand over code our team can maintain?\",\n    \"acceptedAnswer\": {\n      \"@type\": \"Answer\",\n      \"text\": \"Yes, you\u2019ll receive the source and a runbook. We\u2019d build an AI agent in Python with plain, readable functions. Updating content means swapping the knowledge-base PDF and restarting the app. Engineers handle only prompt edits and new tools.\"\n    }\n  }]\n}\n<\/script>\n\n\n\n\n<script type=\"application\/ld+json\">\n[\n  {\n    \"@context\": \"https:\/\/schema.org\",\n    \"@type\": \"VideoObject\",\n    \"name\": \"AI Agent Demo: Customer Support and Sales Lead Capture\",\n    \"description\": \"Watch how the Mobisoft Infotech AI assistant answers website visitor questions, manages customer conversations, and supports sales lead capture with live agent activity\",\n    \"thumbnailUrl\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/thumbnail-make-agents-thinking-visible.png\",\n    \"uploadDate\": \"2026-10-30T08:00:00+08:00\",\n    \"contentUrl\": \"https:\/\/cdn.mobisoftinfotech.com\/assets\/images\/blog\/flutter-bluetooth-ble-integration-guide\/make-agents-thinking-visible.mp4\",\n    \"embedUrl\": \"https:\/\/cdn.mobisoftinfotech.com\/assets\/images\/blog\/flutter-bluetooth-ble-integration-guide\/make-agents-thinking-visible.mp4\",\n    \"duration\": \"PT1M25S\",\n    \"interactionCount\": \"234\",\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"Mobisoft Infotech\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https:\/\/mobisoftinfotech.com\/assets\/images\/mshomepage\/MI_Logo-white.svg\"\n      }\n    },\n    \"author\": {\n      \"@type\": \"Person\",\n      \"name\": \"Prashant Telangi\",\n      \"url\": \"https:\/\/www.linkedin.com\/in\/prashant-telangi-83816918\/\"\n    }\n  }\n]\n<\/script>\n\n\n\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"ImageObject\",\n      \"contentUrl\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png\",\n      \"url\": \"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai\",\n      \"name\": \"How to Build an AI Agent Using Python and OpenAI\",\n      \"caption\": \"Learn how to build an AI agent that answers customer questions, applies LLM guardrails, and captures sales leads.\",\n      \"description\": \"Explore how to build an AI agent in Python using OpenAI to answer customer queries, validate responses with LLM guardrails, and automate lead generation.\",\n      \"license\": \"https:\/\/mobisoftinfotech.com\/terms\",\n      \"acquireLicensePage\": \"https:\/\/mobisoftinfotech.com\/acquire-license\",\n      \"creditText\": \"Mobisoft Infotech\",\n      \"copyrightNotice\": \"Mobisoft Infotech\",\n      \"creator\": {\n        \"@type\": \"Organization\",\n        \"name\": \"Mobisoft Infotech\"\n      },\n      \"thumbnail\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png\"\n    },\n    {\n      \"@type\": \"ImageObject\",\n      \"contentUrl\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/production-ready-ai-sales-agent.png\",\n      \"url\": \"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai\",\n      \"name\": \"Production-Ready AI Sales Agent Development\",\n      \"caption\": \"Improve customer engagement and lead qualification with production-ready AI agents.\",\n      \"description\": \"Discover how an AI sales agent and AI lead generation chatbot can automate customer conversations, qualify prospects, and support business growth.\",\n      \"license\": \"https:\/\/mobisoftinfotech.com\/terms\",\n      \"acquireLicensePage\": \"https:\/\/mobisoftinfotech.com\/acquire-license\",\n      \"creditText\": \"Mobisoft Infotech\",\n      \"copyrightNotice\": \"Mobisoft Infotech\",\n      \"creator\": {\n        \"@type\": \"Organization\",\n        \"name\": \"Mobisoft Infotech\"\n      },\n      \"thumbnail\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/production-ready-ai-sales-agent.png\"\n    },\n    {\n      \"@type\": \"ImageObject\",\n      \"contentUrl\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/ai-chatbot-business-lead-generation.png\",\n      \"url\": \"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai\",\n      \"name\": \"Custom AI Chatbot Development for Business\",\n      \"caption\": \"Build an AI chatbot for business that improves customer support and streamlines lead generation.\",\n      \"description\": \"Explore custom AI chatbot solutions that automate customer interactions, support lead generation, and help businesses build scalable AI-powered experiences.\",\n      \"license\": \"https:\/\/mobisoftinfotech.com\/terms\",\n      \"acquireLicensePage\": \"https:\/\/mobisoftinfotech.com\/acquire-license\",\n      \"creditText\": \"Mobisoft Infotech\",\n      \"copyrightNotice\": \"Mobisoft Infotech\",\n      \"creator\": {\n        \"@type\": \"Organization\",\n        \"name\": \"Mobisoft Infotech\"\n      },\n      \"thumbnail\": \"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/ai-chatbot-business-lead-generation.png\"\n    }\n  ]\n}\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>The Problem Every Company Website Has It&#8217;s 11:40 pm. A potential customer lands on your website while your whole team is asleep. They have a real project, a real budget, and one question: &#8220;Have you built HIPAA-compliant healthcare apps before?&#8221; Usually, one of three things happens next: What if I told you there&#8217;s a fourth [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":57720,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_s2mail":"","footnotes":""},"categories":[286],"tags":[8957,11709,11553,11710,11377,11708],"class_list":["post-57698","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-ai-chatbot-for-business","tag-ai-lead-generation-chatbot","tag-ai-sales-agent","tag-build-an-ai-agent-in-python","tag-how-to-build-an-ai-agent","tag-llm-guardrails"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Build an AI Agent with Python &amp; OpenAI: Step-by-Step Guide<\/title>\n<meta name=\"description\" content=\"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build an AI Agent with Python &amp; OpenAI: Step-by-Step Guide\" \/>\n<meta property=\"og:description\" content=\"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai\" \/>\n<meta property=\"og:site_name\" content=\"Mobisoft Infotech\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-30T11:14:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-30T15:01:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/og-build-ai-agent-python-openai.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"515\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Prashant Telangi\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"How to Build an AI Agent Using Python and OpenAI\" \/>\n<meta name=\"twitter:description\" content=\"Explore how to build an AI agent in Python using OpenAI to answer customer queries, validate responses with LLM guardrails, and automate lead generation.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/og-build-ai-agent-python-openai.png\" \/>\n<meta name=\"twitter:creator\" content=\"@MobisoftInfo\" \/>\n<meta name=\"twitter:site\" content=\"@MobisoftInfo\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Prashant Telangi\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai\"},\"author\":{\"name\":\"Prashant Telangi\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/#\\\/schema\\\/person\\\/d7a32c3195dc5efe2829391045ffc070\"},\"headline\":\"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\",\"datePublished\":\"2026-10-30T11:14:14+00:00\",\"dateModified\":\"2026-10-30T15:01:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai\"},\"wordCount\":2654,\"image\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/build-ai-agent-python-openai.png\",\"keywords\":[\"AI Chatbot for Business\",\"AI lead generation chatbot\",\"AI sales agent\",\"build an AI agent in Python\",\"How to Build an AI Agent\",\"LLM guardrails\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai\",\"url\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai\",\"name\":\"Build an AI Agent with Python & OpenAI: Step-by-Step Guide\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/build-ai-agent-python-openai.png\",\"datePublished\":\"2026-10-30T11:14:14+00:00\",\"dateModified\":\"2026-10-30T15:01:36+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/#\\\/schema\\\/person\\\/d7a32c3195dc5efe2829391045ffc070\"},\"description\":\"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#primaryimage\",\"url\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/build-ai-agent-python-openai.png\",\"contentUrl\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/build-ai-agent-python-openai.png\",\"width\":1120,\"height\":515,\"caption\":\"How to build an AI agent in Python that validates answers and captures sales leads.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/blog\\\/build-ai-agent-python-openai#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/#website\",\"url\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/\",\"name\":\"Mobisoft Infotech\",\"description\":\"Discover Mobility\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mobisoftinfotech.com\\\/resources\\\/#\\\/schema\\\/person\\\/d7a32c3195dc5efe2829391045ffc070\",\"name\":\"Prashant Telangi\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g\",\"caption\":\"Prashant Telangi\"},\"sameAs\":[\"http:\\\/\\\/www.mobisoftinfotech.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build an AI Agent with Python & OpenAI: Step-by-Step Guide","description":"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.","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:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai","og_locale":"en_US","og_type":"article","og_title":"Build an AI Agent with Python & OpenAI: Step-by-Step Guide","og_description":"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.","og_url":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai","og_site_name":"Mobisoft Infotech","article_published_time":"2026-10-30T11:14:14+00:00","article_modified_time":"2026-10-30T15:01:36+00:00","og_image":[{"width":1000,"height":515,"url":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/og-build-ai-agent-python-openai.png","type":"image\/png"}],"author":"Prashant Telangi","twitter_card":"summary_large_image","twitter_title":"How to Build an AI Agent Using Python and OpenAI","twitter_description":"Explore how to build an AI agent in Python using OpenAI to answer customer queries, validate responses with LLM guardrails, and automate lead generation.","twitter_image":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/og-build-ai-agent-python-openai.png","twitter_creator":"@MobisoftInfo","twitter_site":"@MobisoftInfo","twitter_misc":{"Written by":"Prashant Telangi","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#article","isPartOf":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai"},"author":{"name":"Prashant Telangi","@id":"https:\/\/mobisoftinfotech.com\/resources\/#\/schema\/person\/d7a32c3195dc5efe2829391045ffc070"},"headline":"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)","datePublished":"2026-10-30T11:14:14+00:00","dateModified":"2026-10-30T15:01:36+00:00","mainEntityOfPage":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai"},"wordCount":2654,"image":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#primaryimage"},"thumbnailUrl":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png","keywords":["AI Chatbot for Business","AI lead generation chatbot","AI sales agent","build an AI agent in Python","How to Build an AI Agent","LLM guardrails"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai","url":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai","name":"Build an AI Agent with Python & OpenAI: Step-by-Step Guide","isPartOf":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/#website"},"primaryImageOfPage":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#primaryimage"},"image":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#primaryimage"},"thumbnailUrl":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png","datePublished":"2026-10-30T11:14:14+00:00","dateModified":"2026-10-30T15:01:36+00:00","author":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/#\/schema\/person\/d7a32c3195dc5efe2829391045ffc070"},"description":"Go beyond basic AI chatbots. Build an OpenAI-powered Python agent with answer verification, customer support workflows, and automated lead capture.","breadcrumb":{"@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#primaryimage","url":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png","contentUrl":"https:\/\/mobisoftinfotech.com\/resources\/wp-content\/uploads\/2026\/10\/build-ai-agent-python-openai.png","width":1120,"height":515,"caption":"How to build an AI agent in Python that validates answers and captures sales leads."},{"@type":"BreadcrumbList","@id":"https:\/\/mobisoftinfotech.com\/resources\/blog\/build-ai-agent-python-openai#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/mobisoftinfotech.com\/resources\/"},{"@type":"ListItem","position":2,"name":"How to Build an AI Agent That Answers Customers, Checks Its Own Answers, and Captures Sales Leads (Python + OpenAI)"}]},{"@type":"WebSite","@id":"https:\/\/mobisoftinfotech.com\/resources\/#website","url":"https:\/\/mobisoftinfotech.com\/resources\/","name":"Mobisoft Infotech","description":"Discover Mobility","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/mobisoftinfotech.com\/resources\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/mobisoftinfotech.com\/resources\/#\/schema\/person\/d7a32c3195dc5efe2829391045ffc070","name":"Prashant Telangi","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cdde432a920f6002154a0769008dfecabe1f464d11187612020b889ad41808e7?s=96&r=g","caption":"Prashant Telangi"},"sameAs":["http:\/\/www.mobisoftinfotech.com"]}]}},"_links":{"self":[{"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/posts\/57698","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/comments?post=57698"}],"version-history":[{"count":22,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/posts\/57698\/revisions"}],"predecessor-version":[{"id":57743,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/posts\/57698\/revisions\/57743"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/media\/57720"}],"wp:attachment":[{"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/media?parent=57698"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/categories?post=57698"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mobisoftinfotech.com\/resources\/wp-json\/wp\/v2\/tags?post=57698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}