# Capstone: a real end-to-end ChatGPT workflow
Let's build one realistic system end to end: a customer-support assistant for a small SaaS company that answers from a knowledge base, pulls live order and account data, escalates hard tickets to a human, and emails a weekly health report to the founder every Monday. You already know the pieces individually. This lesson is about wiring them together and, more importantly, choosing *which* piece to use where.
"SupportBot" must do four things:
1. Answer product questions from internal docs.
2. Look up a customer's live subscription and recent tickets.
3. Hand off to a human when confidence is low or the customer is angry.
4. Produce a weekly report on ticket volume, resolution time, and top issues.
Three constraints drive every decision: the team is two people, the docs change weekly, and customer data lives in a Postgres database and Zendesk. Keep these in mind, because they push us toward different surfaces for different jobs.
This is the central architecture fork, so resolve it first.
A Custom GPT (configured at chatgpt.com, distributed via the GPT Store or a private link) is the right home for the *internal-facing* assistant. Your two support agents open it inside ChatGPT, paste a customer email, and get a drafted reply grounded in your docs. Zero hosting, zero auth code, and it inherits Connectors and Actions natively.
The APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → (the Responses API) is the right home for anything *customer-facing* or *automated*: the widget on your website, the nightly report job. You need programmatic control, your own auth, logging, and the ability to run without a human in the loop.
So the answer is both, split by audience:
Don't try to force one surface to do everything. The Custom GPT is your fast path; the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → is your durable path.
The docs change weekly, so grounding strategy matters.
For the Custom GPT, use Connectors to link the live Google Drive folder where the team keeps docs. The GPT searches that source at query time, so a Monday edit is reflected Monday. This beats uploading static files to the GPT's knowledge, which would go stale and require re-uploading. See help.openai.com for the current Connectors catalog and admin controls.
For the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →-backed widget, you own retrieval. Either run your own vector search and pass results into the prompt, or use file search as a hosted tool on the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →. For a two-person team, hosted file search is the pragmatic choice: less infrastructure to babysit. A weekly cron job re-syncs the docs into the file store.
The assistant needs getCustomer(email) and getRecentTickets(customerId). Same capability, two implementations depending on surface.
In the Custom GPT, you expose these as GPT Actions: an OpenAPI spec pointing at your internal APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →, with auth configured in the GPT builder. The model decides when to call them.
In the API widget, the same operations become function calling with structured outputs, so the arguments arrive as schemaschemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.Voir la définition complète →-valid JSON every time. Here is the tool definition for the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →:
from openai import OpenAI
client = OpenAI()
tools = [{
"type": "function",
"name": "get_customer",
"description": "Look up a customer's subscription and account status by email.",
"parameters": {
"type": "object",
"properties": {
"email": {"type": "string", "description": "Customer email address"}
},
"required": ["email"],
"additionalProperties": False
},
"strict": True
}]
response = client.responses.create(
model="gpt-4.1",
input="What plan is taylor@acme.com on, and is their account in good standing?",
tools=tools
)
print(response.output)strict: True is the part worth internalizing: it guarantees the model's arguments conform to your schemaschemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.Voir la définition complète →, which means your backend code never has to defensively parse a malformed email field. Read the function calling guide for the full loop, including how you send the tool result back for the model's final answer.
The key insight: the *same OpenAPI operations* back both your GPT Actions and your function-calling tools. Write the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → once, expose it twice.
Never let a support bot guarantee a refund or close a ticket on its own. Build an explicit escalation tool, escalate_to_human(reason, urgency), and instruct the model to call it when the customer is upset, asks for money, or the docs don't cover the question.
Make escalation a *first-class tool*, not a vibe. When called, your code drops the conversation into a Zendesk queue and tells the customer a human is on it. This turns "the bot got it wrong" into "the bot knew its limits," which is the difference between a useful assistant and a liability.
When you have several tools and multi-step logic (look up customer → check tickets → decide to answer or escalate), you have a choice:
If you're prototyping interactively, the ChatGPT agent (the browsing, clicking, multi-step agent inside ChatGPT) is great for one-off investigations ("go find every open ticket mentioning the new billing bug"), but it's not where you run production traffic. Keep that distinction sharp: ChatGPT agent for exploration, Agents SDK for the deployed system.
This is where Advanced Data Analysis (Code Interpreter) shines. The report needs real computation: median resolution time, week-over-week ticket deltas, a chart of top issue categories.
You have two clean options:
Option A: Scheduled task inside ChatGPT. ChatGPT supports scheduled tasks that run a prompt on a recurring basis. Create a task in your Custom GPT: "Every Monday at 8am, pull last week's tickets via the Zendesk connector, compute resolution stats, and produce a summary with a chart." Lowest effort, no code to host.
Option B: API job on your own cron. A small script queries Postgres, hands the rows to the model with the Code Interpreter tool to crunch numbers and render a chart, then emails the result. More control, version-controlled, testable. Choose this when the report feeds something downstream or the founder needs it in a specific format every time.
For a two-person team, start with Option A. Graduate to Option B when the report becomes load-bearing.
Vérification des acquis
1. According to the lesson, which surface is the right home for the internal-facing assistant that support agents use to draft replies?
2. In the SupportBot scenario, why is the API (Responses API) chosen for the website widget and the scheduled weekly report?
3. In the OpenAI ecosystem, what is the primary purpose of 'Actions' in a Custom GPT?
4. Select ALL correct answers about the four things SupportBot must do according to the lesson.
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about the constraints that drive SupportBot's architecture decisions.
Sélectionnez toutes les réponses correctes.
Here is the full picture, surface by surface:
| Job | Surface | Why |
|---|---|---|
| Agents drafting replies | Custom GPT + Connectors + Actions | Fast, no hosting, live docs |
| Website chat widget | Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → + file search + function calling | Programmatic, owns auth and logging |
| Multi-agent routing & escalation | Agents SDK | Handoffs and guardrails are built in |
| Weekly report | Scheduled task (start) → APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → + Code Interpreter (scale) | Real computation on a schedule |
Notice the through-line: one backend API serves the lookups, exposed as Actions to the GPT and as function tools to the APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →. One doc source (the Drive folder) feeds both the Connector and the file-search sync. You are not building four systems; you are building two integration points (your APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète →, your docs) and pointing multiple surfaces at them.
A few ChatGPT features quietly improve the agent-facing tool:
When you're *writing* the report templates or the email copy, Canvas is the better editing surface than chat: you iterate on a document in place. And the actual implementation work (the Responses APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.Voir la définition complète → script, the OpenAPI spec, the cron job) is exactly what Codex is for. Use it to scaffold the function-calling loop and the Postgres query, then review every line before it touches customer data.
Before you ship, pre-decide what happens when things break:
Design these on paper first. They are cheaper to decide now than to debug in production.
strict structured outputs, and instruct the model to escalate on failure or low confidence instead of guessing.