Build an OpenAI Chatbot in Python With Persistent Context

Setting up an OpenAI chatbot in Python takes a few lines of code. Keeping conversation state across sessions and giving the bot project rules and current progress is the harder part. Here is how to do both.

Updated 4 min read

An OpenAI chatbot in Python sends a list of messages to the API, reads the reply and appends it to the list before the next call. That messages list is the conversation state: without it, each API call is an independent question rather than a turn in a continuing exchange.

For context that spans more than one chat session, the list needs to persist somewhere outside the script. Tools like fenbs let a connected assistant read project rules and Where we left off at the start of a session, so the bot can continue from an agreed record rather than starting fresh each time.

What you need before you start

  • An OpenAI account with API access and an API key.
  • Python 3.9 or later, installed locally or available in a Google Colab notebook.
  • The openai package: run pip install openai in your terminal or notebook.

Set your API key as an environment variable (OPENAI_API_KEY) rather than pasting it directly into the script. On macOS and Linux, add export OPENAI_API_KEY=your_key to your shell profile. On Windows, add it through the environment variables panel in system settings.

Setting up the basic conversation loop

The core loop initializes a messages list with a system message, adds each user turn, calls the API with the full list and appends the reply. The system message gives the bot its standing instructions for the session.

Basic conversation loop
import os
from openai import OpenAI

client = OpenAI()
messages = [{"role": "system", "content": "You are a helpful assistant."}]

while True:
    user_input = input("You: ")
    if user_input.lower() in ("exit", "quit"):
        break
    messages.append({"role": "user", "content": user_input})
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    reply = response.choices[0].message.content
    messages.append({"role": "assistant", "content": reply})
    print(f"Bot: {reply}")

Keep the system message specific. For a project-focused bot, include the scope: what it should help with, what it must not change, and any conventions it is expected to follow. A vague system message produces inconsistent behavior as the conversation grows longer.

Saving and reloading conversation history

The messages list above disappears when the script exits. To continue a conversation across sessions, write the list to a file after each turn and reload it on startup.

Save and reload history
import json

def load_history(path="history.json"):
    if os.path.exists(path):
        with open(path) as f:
            return json.load(f)
    return [{"role": "system", "content": "You are a helpful assistant."}]

def save_history(messages, path="history.json"):
    with open(path, "w") as f:
        json.dump(messages, f)

A long messages list increases token usage on every call. Trim older turns beyond a practical limit, or summarize earlier parts of the conversation before appending the summary. For production use, a database is safer than a local JSON file and easier to query when something goes wrong.

Adding tool calls to extend what the bot can do

Tool calls let the chatbot take actions or read data during a conversation. You define each tool as a JSON schema object and pass the list to the API call. When the model returns a tool call instead of a direct reply, you run the matching function locally and send the result back as a new message.

The OpenAI Agents SDK provides a higher-level abstraction for chatbots that need many tools or multi-step workflows. For a simple bot with one or two actions, the plain tool-calling API is usually enough and easier to trace when something goes wrong. The OpenAI agent builder covers a no-code path to similar results.

Managing conversation length and token costs

The messages list grows every turn, and the entire list is sent to the API on each call. For a short session this is fine. For a long task or a bot that stays active across hours, a growing list adds to your token costs and will eventually hit the model's context window limit.

A practical approach is to summarize after every ten or twenty turns. Ask the model to compress what has been agreed and what remains, then replace the older turns with that summary. Keep the system message and the most recent turns in full; replace the middle with a compact record of earlier decisions. This preserves the useful context without sending the full transcript on every call.

Running the chatbot in Google Colab

Colab is a practical environment for trying this setup without a local Python installation. Install the package with !pip install openai, store your API key in Colab Secrets under the key icon in the left panel, and read it with os.environ.get("OPENAI_API_KEY").

The input() function does not work inside Colab notebook cells. Use an ipywidgets text field or hardcode a test message to exercise the loop. The rest of the code works unchanged. For connecting a Python environment to an MCP server, the MCP server in Python guide covers the setup. For building a Python chatbot for business deployment, see AI chatbot for business.

How fenbs helps

Give your bot a project record to start from

Connect fenbs over MCP and ask your chatbot to read project rules and Where we left off at the start of each session. Decisions and rules appear first in the AI context, so the bot starts from what is already settled. fenbs does not import chat history or read your Python scripts; it holds the rules, tasks and progress you put there. Create a free account and add the first rules your bot should always follow.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

The setup links project context to each new session.

  1. Create a free account at fenbs.ai and add a project for the work the chatbot supports.
  2. Write project rules as Decisions and rules. Mark recurring instructions as standing rules so they appear first when a connected assistant reads the AI context.
  3. Add current tasks and update Where we left off whenever significant progress is made.
  4. Connect from Integrations using the MCP setup guide for your AI coding tool.
  5. At the start of each session, include a system message instructing the bot to read the project context, including its rules and Where we left off, before it responds to the first user message.

fenbs does not currently offer a Python library for direct API calls from a script. Connection to fenbs goes through an AI app that supports MCP. If your chatbot runs inside Claude Code, Cursor or another supported tool, that tool handles the fenbs connection on your behalf.

Questions people ask.

How do I start an OpenAI chatbot in Python?

Install the openai package, set your API key as an environment variable and call client.chat.completions.create() with a messages list. Each turn appends the user message and the model reply to that list, which you pass on the next call to keep the conversation going.

How do I keep conversation history between sessions?

Save the messages list to a file or database after each turn and reload it when the script starts. Keep the list to a manageable length to control token costs. For production use, a database is more reliable than a local JSON file.

Can I run an OpenAI Python chatbot in Google Colab?

Yes. Install the package with !pip install openai, store your key in Colab Secrets and read it with os.environ.get(). The input() function does not work in notebook cells; use a text widget or a hardcoded test message instead.

What is the difference between a chatbot and an AI agent in Python?

A chatbot responds to turns in a conversation. An agent also takes actions between turns, such as calling tools or running code, and may work through a task across multiple steps before returning a result. The OpenAI Agents SDK provides the agent primitives for Python.

Does fenbs offer a Python SDK?

fenbs connects over MCP, not through a Python library. An AI app that supports MCP can read project context from fenbs. For a Python chatbot, the connection runs through a supported AI coding tool rather than directly from the script.

More in Agent harness (for developers)

All Agent harness (for developers) articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.