Build an IT Documentation Agent

Use Python and Gemini AI to auto-generate and publish IT docs to Confluence.

Introduction

30 Second Summary

IT documentation is one of those things every team knows they need, but nobody has time to write. Outdated runbooks and missing guides slow down troubleshooting when it matters most.

In this project, you will build a Python agent that generates IT documentation from your knowledge base and publishes it directly to Confluence. You'll use Google Gemini's free API to turn simple notes into structured, professional docs with a single command.

What You'll Build

A command-line Python agent that reads Markdown knowledge base files, generates structured IT documentation using Google Gemini, and publishes formatted pages to Confluence Cloud via its REST API.

By the end of this project, you'll have:

  • A folder of Markdown knowledge base files describing your IT tools and processes.
  • A Python script that loads relevant context and generates documentation via the Gemini API.
  • A Confluence integration that publishes formatted pages via the REST API.
  • Secret Mission: Add a batch mode that generates an entire documentation set from a template list in one command.

Are there any prerequisites?

None. This guide walks you through installing Python, setting up VS Code, creating your Google AI Studio account, and configuring Confluence from scratch. No prior programming experience is assumed.

Before We Start

Before We Start...

Set Up Python and VS Code

Before you can build anything, you need two core tools on your machine: Python (the programming language your agent runs on) and VS Code (the code editor where you'll write and run your scripts).

In this step, you'll install both tools and confirm they're working together. Once Python responds to a version check inside VS Code's terminal, you're ready to start building.

In this step, get ready to:
  • Install Python 3 with PATH configured.
  • Install VS Code.
  • Verify Python works from the VS Code terminal.
Install Python 3

Python is the language your documentation agent will be written in. The Gemini SDK requires Python 3.9 or higher.

  • Open your browser and go to https://www.python.org/downloads/.
  • Click the large Download Python 3.x.x button (the latest version will be shown).
  • Run the downloaded installer.
  • On the first screen of the installer, check the box that says Add python.exe to PATH. This is critical.
  • Click Install Now and wait for the installation to complete.
  • Click Close when the installer finishes.

Why is Add python.exe to PATH important?

Adding Python to your PATH means your terminal can find the python command no matter which folder you're in. Without this, you'd get a "command not found" error every time you try to run a script.

Install VS Code

VS Code is a free code editor that includes a built-in terminal. You'll write all your Python files here and run commands without leaving the app.

  • Open your browser and go to https://code.visualstudio.com/download.
  • Click the Windows download button.
  • Run the downloaded installer and accept the default settings.
  • When installation completes, check Launch Visual Studio Code and click Finish.

VS Code opens with a Welcome tab. You can close this tab.

Verify Python in the VS Code terminal

Now you'll confirm that Python is reachable from inside VS Code. If this works, your development environment is ready.

  • In VS Code, open the terminal by pressing Ctrl+` (that's the backtick key, above Tab on your keyboard).
  • A terminal panel appears at the bottom of VS Code.
  • Check your Python installation by running this command:
python --version

You should see output like Python 3.13.3 (your exact version number may differ, but it must be 3.9 or higher).

✔️ I see a version number

Python is installed and your PATH is configured correctly. You're all set for the next step.

ⓧ Command not found or I see Python 2.x

This means Python wasn't added to your PATH during installation. Here's how to fix it.

  • Close VS Code completely.
  • Re-run the Python installer you downloaded earlier.
  • Select Modify.
  • Click Next on the Optional Features screen.
  • On the Advanced Options screen, check Add Python to environment variables.
  • Click Install.
  • Re-open VS Code and try the version check again in a new terminal.

Still not working?

Make sure you opened a new terminal in VS Code after reinstalling. Terminals that were open before the PATH change won't pick up the update.

Help me fix Python not being recognized in my VS Code terminal on Windows.

Your development environment is ready. Next up, you'll create the accounts and API keys that let your agent talk to Gemini and Confluence.

Set Up Accounts and API Keys

Your agent needs two external services to work. It uses Google Gemini to generate documentation from your prompts, and it uses Confluence Cloud to publish the finished pages where your team can read them.

In this step, you will create free accounts for both services and collect the credentials your Python code needs to connect to them.

In this step, get ready to:
  • Create a Google AI Studio account and generate a Gemini API key.
  • Create a free Confluence Cloud instance and a space for your docs.
  • Generate a Confluence API token and note your credentials.
Create a Google AI Studio account and get your API key

Google AI Studio is the portal where you manage your Gemini API keys. The free tier gives you 10 requests per minute and 250 requests per day, which is more than enough for generating IT documentation.

  • Open your browser and go to https://aistudio.google.com/.
  • Sign in with your Google account. If you do not have one, click Create account and follow the prompts.
  • Once signed in, you will land on the AI Studio homepage.
  • Click Get API key in the left sidebar.
  • Click Create API key.
  • If prompted to select a project, accept the default project that Google creates for new users.
  • Copy the generated key and paste it somewhere safe (a temporary text file works).

What is an API key?

An API key is a unique string that identifies your application when it sends requests to an external service. Your Python code will include this key so that Google knows which account the request belongs to.

Create API key button greyed out?

This happens when you do not have the right permissions on the selected Google Cloud project. Click Create API key in new project instead. This creates a fresh project you fully own.

Help me fix the greyed out Create API key button

Create a free Confluence Cloud instance

Confluence Cloud is where your generated documentation will live. The free plan supports up to 10 users, unlimited pages, and full REST API access. No credit card is required.

  • Open https://www.atlassian.com/software/confluence/free in a new browser tab.
  • Enter a personal email address and click Sign up. You can also sign up with your Google, Microsoft, Apple, or Slack account.
  • Follow the account creation prompts (verify your email, set a password, and choose a site name).
  • When asked to select a product, make sure Confluence is selected.
  • After setup completes, you will land on your Confluence homepage at a URL like https://yoursite.atlassian.net/wiki.

Now create a space where your agent will publish pages.

  • Click Create in the top navigation bar, then select Space.
  • Enter a space name (for example, IT Docs).
  • Select Knowledge base as the purpose.
  • Note the Space key that Confluence generates (visible in the creation dialog or in your space URL). It will be a short uppercase string like ID or ITDOCS.
  • Click Create space.

What is a space key?

A space key is a short unique identifier that appears in your Confluence URLs. Your Python code uses this key to tell the API which space to publish pages into.

You will store it in your project's .env file in the next step.

Generate a Confluence API token

Confluence Cloud uses email plus an API token for authentication. This is safer than using your Atlassian password directly.

  • Open https://id.atlassian.com/manage-profile/security/api-tokens in a new tab.
  • Sign in with the same Atlassian account you just created.
  • Click Create API token.
  • Enter a label like IT Doc Agent to identify the token.
  • Click Create.
  • Copy the token immediately and paste it into your temporary text file. You will not be able to see it again after closing the dialog.

Keep your credentials handy

Before moving on, confirm you have all five values noted somewhere accessible:

  • Your Gemini API key (from Google AI Studio).
  • Your Confluence site URL (for example, https://yoursite.atlassian.net/wiki).
  • Your Confluence email address.
  • Your Confluence API token.
  • Your Confluence space key.

Can't find your space key?

Navigate to your space in Confluence and look at the URL. It will contain the space key, for example https://yoursite.atlassian.net/wiki/spaces/ITDOCS. The uppercase segment after /spaces/ is your space key.

Help me find my Confluence space key

You now have all the accounts and credentials your agent needs. Next up, you will create the project folder, install your Python packages, and store these credentials securely in a .env file.

Create the Project and Install Dependencies

You have your accounts and API keys ready. Now you need a dedicated workspace where your Python agent will live.

In this step, you'll create a project folder, set up an isolated Python environment, and install the packages your agent needs. You'll also create a secure file to store your API credentials.

In this step, get ready to:
  • Create your project folder and open it in VS Code.
  • Set up a Python virtual environment and install dependencies.
  • Create a .env file to store your API credentials securely.
Create your project folder
  • Move to your Desktop by running this command in your VS Code terminal:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir it-doc-agent
cd it-doc-agent
  • Confirm the folder was created by running:
ls

You should see an empty directory. This is expected since you just created it.

Now open this folder in VS Code so all your files and terminal sessions are rooted here.

  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the it-doc-agent folder, then click Select Folder.

VS Code reloads with it-doc-agent shown in the Explorer sidebar on the left.

  • Open a fresh terminal by pressing Ctrl+` (backtick key, usually above Tab).

This terminal automatically starts inside your it-doc-agent folder.

Don't see it-doc-agent in the Explorer sidebar?

Make sure you selected the it-doc-agent folder itself, not the Desktop folder. If VS Code shows your entire Desktop, go to File > Open Folder again and select the correct folder.

Help me open my project folder in VS Code

Set up a virtual environment and install packages

A virtual environment is an isolated space for your project's Python packages. It keeps this project's dependencies separate from other Python projects on your machine.

  • Create a virtual environment by running this command:
python -m venv venv
  • Activate the virtual environment by running:
.\venv\Scripts\activate

You should see (venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.

What does (venv) mean?

The (venv) prefix tells you that any pip install commands will install packages into this project's isolated environment, not your system-wide Python installation.

Not seeing (venv) in your prompt?

If you get an error about execution policies, run this command first to allow scripts in the current session:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

Then try .\venv\Scripts\activate again.

Help me activate my virtual environment on Windows

Now you'll create a requirements.txt file that lists the packages your project needs. This makes it easy to reinstall everything later.

  • In VS Code's Explorer sidebar, click the new file icon (a page with a plus sign) next to IT-DOC-AGENT.
  • Name the file requirements.txt and press Enter.
  • Paste the following content into the file:
google-genai
requests
python-dotenv

What are these packages?

  • google-genai is Google's official SDK for the Gemini API. Your agent uses it to generate documentation.
  • requests is a popular HTTP library. Your agent uses it to talk to the Confluence REST API.
  • python-dotenv loads your API keys from a .env file so you never hardcode secrets into your scripts.
  • Save requirements.txt by pressing Ctrl+S.
  • Install all three packages by running this command in your terminal:
pip install -r requirements.txt

You should see output showing each package being downloaded and installed. Look for Successfully installed at the end.

Seeing a permission error or install failure?

Make sure (venv) is showing in your terminal prompt. If it's missing, the virtual environment is not active. Run .\venv\Scripts\activate again before retrying the install.

Help me fix my pip install error

Create your .env file for API credentials

Your agent needs your Gemini API key and Confluence credentials to work. A .env file keeps these secrets in one place, separate from your code.

  • In VS Code's Explorer sidebar, click the new file icon next to IT-DOC-AGENT.
  • Name the file .env and press Enter.
  • Paste the following template into the file:
GEMINI_API_KEY=your-api-key-here
CONFLUENCE_URL=https://yoursite.atlassian.net/wiki
CONFLUENCE_EMAIL=your-email@example.com
CONFLUENCE_API_TOKEN=your-api-token-here
CONFLUENCE_SPACE_KEY=your-space-key-here
  • Replace your-api-key-here with the Gemini API key you generated in Google AI Studio.
  • Replace https://yoursite.atlassian.net/wiki with your actual Confluence site URL.
  • Replace your-email@example.com with the email address you used to create your Confluence account.
  • Replace your-api-token-here with the Confluence API token you generated.
  • Replace your-space-key-here with your Confluence space key (found in your space settings or the URL when viewing your space).

Where do I find my Confluence space key?

Go to your Confluence space and look at the URL. The space key is the short code after /spaces/ in the URL. For example, if the URL is https://yoursite.atlassian.net/wiki/spaces/IT/overview, your space key is IT.

  • Save .env by pressing Ctrl+S.

You should see both .env and requirements.txt listed in the Explorer sidebar, alongside the venv folder.

Keep your .env file private

Never share your .env file or commit it to version control. It contains credentials that grant access to your accounts. If you use Git later, add .env to your .gitignore file.

VS Code not showing the .env file?

Files starting with a dot are sometimes hidden by default. Check that you typed the name as .env (with the dot at the start). If the file exists but is hidden in Explorer, click the gear icon in the Explorer panel and make sure hidden files are visible.

Help me create a .env file in VS Code

✔️ Awesome, I've got everything!

Great. Double check you've saved both files and that (venv) is still showing in your terminal prompt.

ⓧ I'd like to double check the full code

Here are the two files you should have in your project folder.

google-genai
requests
python-dotenv
GEMINI_API_KEY=your-api-key-here
CONFLUENCE_URL=https://yoursite.atlassian.net/wiki
CONFLUENCE_EMAIL=your-email@example.com
CONFLUENCE_API_TOKEN=your-api-token-here
CONFLUENCE_SPACE_KEY=your-space-key-here

Your .env values should contain your actual credentials, not the placeholder text shown above.

Your project workspace is ready with all dependencies installed and credentials stored. Next up, you'll build the knowledge base that feeds your agent the context it needs to generate useful documentation.

Build the Knowledge Base

Your agent needs a source of truth to generate useful documentation. Without context about your actual tools and processes, it would produce generic content with no grounding in reality.

In this step, you'll create a set of Markdown files that describe your IT environment. Then you'll build a Python module that reads and filters these files so your agent can find the right context for any documentation request.

In this step, get ready to:
  • Create a knowledge_base/ folder with sample IT tool descriptions.
  • Build a Python loader that reads and filters knowledge base files by keyword.
  • Test that the loader correctly finds and returns content.
Create the knowledge base folder and files

A knowledge base is just a folder of Markdown files, each describing one area of your IT environment. Your agent will read these files to understand what tools you use, how they connect, and what common issues arise.

  • Create the knowledge_base folder by running this command in your VS Code terminal:
mkdir knowledge_base
  • In the VS Code Explorer sidebar, right-click the knowledge_base folder and select New File....
  • Name the file monitoring.md and paste this content:
# Monitoring Stack

## Tools
- **Datadog**: Primary monitoring and alerting platform
- **PagerDuty**: Incident management and on-call rotation

## Architecture
- Datadog agents installed on all production servers
- Custom dashboards for each service team
- Alerts route to PagerDuty based on severity

## Common Issues
- Agent disconnection: Check network connectivity and agent service status
- Missing metrics: Verify agent configuration file at /etc/datadog-agent/datadog.yaml
- Alert fatigue: Review threshold settings in Datadog monitors
  • Create another file in knowledge_base called ci-cd.md and paste this content:
# CI/CD Pipeline

## Tools
- **GitHub Actions**: Primary CI/CD platform
- **Docker**: Container builds and deployment
- **AWS ECR**: Container registry

## Pipeline Flow
1. Developer pushes code to GitHub
2. GitHub Actions triggers build workflow
3. Docker image built and pushed to AWS ECR
4. Deployment triggered to staging environment
5. After approval, deployed to production

## Common Issues
- Build failures: Check GitHub Actions logs for dependency errors
- Docker build timeout: Increase timeout in workflow YAML
- ECR push denied: Verify IAM role permissions
  • Create one more file in knowledge_base called cloud-infra.md and paste this content:
# Cloud Infrastructure

## Tools
- **AWS**: Primary cloud provider
- **Terraform**: Infrastructure as Code
- **AWS CloudWatch**: Logging and monitoring

## Architecture
- Multi-AZ deployment across us-east-1
- VPC with public and private subnets
- Application Load Balancer for traffic distribution

## Common Issues
- High latency: Check CloudWatch metrics for CPU and memory
- Deployment failures: Review Terraform plan output for conflicts
- Cost spikes: Check AWS Cost Explorer for unexpected resource usage

What is a knowledge base?

Each file represents one domain of your IT environment (monitoring, CI/CD, cloud infrastructure). The structured format with Tools, Architecture, and Common Issues sections gives your agent consistent context to work with.

In a real workplace, you would expand these files with your actual tools, runbooks, and tribal knowledge. The more detail you add, the better documentation your agent produces.

  • Save all three files.
  • Confirm the files exist by running:
ls knowledge_base

You should see ci-cd.md, cloud-infra.md, and monitoring.md listed in the output.

Don't see the files?

Make sure you created the files inside the knowledge_base folder, not in the project root. Check the VS Code Explorer to confirm the folder structure shows knowledge_base/monitoring.md, not just monitoring.md at the top level.

help me find where my knowledge base files ended up

Build the knowledge base loader

Your agent needs a way to programmatically read these Markdown files and filter them by topic. A loader module handles this so the rest of your code can just ask for relevant context without worrying about file paths.

  • Create a new file called kb_loader.py in your project root (the same level as .env) and paste this code:
import os


def get_knowledge_base_path():
    """Return the path to the knowledge base folder."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(script_dir, "knowledge_base")


def list_topics():
    """List all available knowledge base topics."""
    kb_path = get_knowledge_base_path()
    topics = []
    for filename in os.listdir(kb_path):
        if filename.endswith(".md"):
            # Convert filename to readable topic name
            topic_name = filename.replace(".md", "").replace("-", " ").title()
            topics.append(topic_name)
    return topics

What does this code do?

get_knowledge_base_path() builds the full path to your knowledge_base/ folder relative to where the script lives. This means it works no matter where you run the script from.

list_topics() scans the folder for .md files and converts filenames like ci-cd.md into readable names like "Ci Cd". This powers the --list-topics flag you'll add to your CLI later.

You won't see a change yet. The next chunk adds the main loading function that ties everything together.

  • Add the load_knowledge_base() function below your existing code in kb_loader.py:
def load_knowledge_base(keywords=None):
    """Load knowledge base files, optionally filtered by keywords."""
    kb_path = get_knowledge_base_path()
    content_parts = []

    for filename in os.listdir(kb_path):
        if not filename.endswith(".md"):
            continue

        filepath = os.path.join(kb_path, filename)
        with open(filepath, "r", encoding="utf-8") as f:
            file_content = f.read()

        # If no keywords specified, load all files
        if keywords is None:
            content_parts.append(file_content)
        else:
            # Check if any keyword matches the file content or filename
            lower_content = file_content.lower()
            lower_filename = filename.lower()
            for keyword in keywords:
                if keyword.lower() in lower_content or keyword.lower() in lower_filename:
                    content_parts.append(file_content)
                    break

    return "\n\n---\n\n".join(content_parts)

What does this code do?

load_knowledge_base() is the main function your agent will call. When keywords is None, it loads every Markdown file in the knowledge base.

When you pass keywords like ["monitoring"], it only returns files where the keyword appears in the content or filename. This filtering keeps your prompts focused and avoids sending irrelevant context to the LLM.

  • Save kb_loader.py.

✔️ Awesome, I've got everything!

Great. Make sure you've saved kb_loader.py before moving on to testing.

ⓧ I'd like to double check the full code

Here is the complete kb_loader.py file for comparison:

import os


def get_knowledge_base_path():
    """Return the path to the knowledge base folder."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(script_dir, "knowledge_base")


def list_topics():
    """List all available knowledge base topics."""
    kb_path = get_knowledge_base_path()
    topics = []
    for filename in os.listdir(kb_path):
        if filename.endswith(".md"):
            topic_name = filename.replace(".md", "").replace("-", " ").title()
            topics.append(topic_name)
    return topics


def load_knowledge_base(keywords=None):
    """Load knowledge base files, optionally filtered by keywords."""
    kb_path = get_knowledge_base_path()
    content_parts = []

    for filename in os.listdir(kb_path):
        if not filename.endswith(".md"):
            continue

        filepath = os.path.join(kb_path, filename)
        with open(filepath, "r", encoding="utf-8") as f:
            file_content = f.read()

        if keywords is None:
            content_parts.append(file_content)
        else:
            lower_content = file_content.lower()
            lower_filename = filename.lower()
            for keyword in keywords:
                if keyword.lower() in lower_content or keyword.lower() in lower_filename:
                    content_parts.append(file_content)
                    break

    return "\n\n---\n\n".join(content_parts)
Test the knowledge base loader

Before connecting this to your AI agent, you should confirm the loader actually finds and returns content from your Markdown files.

  • Test the list_topics() function by running this command in your terminal:
python -c "from kb_loader import list_topics; print(list_topics())"

You should see a list of your three topics printed, something like ['Ci Cd', 'Cloud Infra', 'Monitoring'].

  • Test the keyword filtering by running this command:
python -c "from kb_loader import load_knowledge_base; result = load_knowledge_base(keywords=['monitoring']); print(result[:200])"

You should see the first 200 characters of your monitoring.md content printed, starting with # Monitoring Stack.

Seeing a ModuleNotFoundError?

Make sure you're running the command from your project folder (the one containing kb_loader.py). Python can only import files in the current directory.

Also check that your virtual environment is still active. You should see (venv) at the start of your terminal prompt. If not, reactivate it by running .\venv\Scripts\activate.

help me debug my kb_loader import error

Seeing a FileNotFoundError?

This means kb_loader.py can't find the knowledge_base/ folder. Confirm the folder is in the same directory as kb_loader.py by checking the VS Code Explorer sidebar.

help me fix my knowledge base file path issue

Your knowledge base is loaded and searchable. Next up, you'll build the documentation generator that sends this context to Gemini and gets structured IT docs back.

Build the Documentation Generator

Your knowledge base is loaded and ready. Now you need the brain of the operation: a module that takes that raw context, sends it to an AI model, and gets back structured documentation.

In this step, you will connect to the Gemini API using a system prompt that tells the model exactly how to format IT docs. The key challenge is crafting a prompt that produces consistent, Confluence-ready HTML output every time.

In this step, get ready to:
  • Write a system prompt that instructs Gemini to generate structured IT documentation.
  • Create a function that sends the knowledge base context plus a user request to Gemini.
  • Test the generator by asking it to create a troubleshooting guide and print the result.
Write the system prompt

A system prompt gives the AI model a persistent set of instructions that shape every response it generates. For your documentation agent, the system prompt defines the model's role, formatting rules, and constraints.

  • Create a new file called doc_generator.py in your project folder (the same folder where kb_loader.py lives).
  • Add the following imports and system prompt to the file:
import os
from google import genai
from google.genai import types
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# System prompt that defines how Gemini should generate documentation
SYSTEM_PROMPT = """You are an IT documentation specialist. Your job is to generate 
clear, well-structured IT documentation based on the provided knowledge base context.

Follow these rules:
1. Use the knowledge base context to ground your documentation in actual tools and processes.
2. Structure docs with clear headings, bullet points, and numbered steps where appropriate.
3. Include practical troubleshooting tips when relevant.
4. Keep language concise and professional.
5. Format output in HTML suitable for Confluence (use <h2>, <h3>, <p>, <ul>, <li>, <ol>, <table>, <tr>, <td>, <th> tags).
6. Do not invent tools or processes not mentioned in the knowledge base.
"""

What does this code do?

The imports bring in the Gemini SDK (google-genai) and python-dotenv for reading your API key from the .env file.

The SYSTEM_PROMPT is a constant string that gets sent with every API call. It tells Gemini to act as a documentation specialist and output HTML formatted specifically for Confluence's storage format. Rule 6 is especially important: it prevents the model from hallucinating tools your team doesn't actually use.

  • Save doc_generator.py.
Create the generate_documentation function

This function is the core of your agent. It takes a documentation request and the knowledge base context, combines them into a prompt, and sends everything to Gemini.

  • In doc_generator.py, add the following function below the SYSTEM_PROMPT constant:
def generate_documentation(request, knowledge_base_context):
    """Generate IT documentation using Gemini."""
    # Initialize the Gemini client with your API key
    client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))

    # Build the prompt combining knowledge base context and the user's request
    prompt = f"""Based on the following knowledge base context, generate the requested documentation.

KNOWLEDGE BASE CONTEXT:
{knowledge_base_context}

DOCUMENTATION REQUEST:
{request}

Generate a well-structured IT documentation page in HTML format suitable for Confluence.
"""

    # Call Gemini with the system prompt and low temperature for consistent output
    response = client.models.generate_content(
        model="gemini-2.5-flash",
        contents=prompt,
        config=types.GenerateContentConfig(
            system_instruction=SYSTEM_PROMPT,
            temperature=0.3,
        ),
    )

    return response.text

What does this code do?

  • genai.Client(api_key=...) creates a connection to the Gemini API using the key from your .env file.
  • The prompt f-string injects the knowledge base context and the user's request into a structured template. This gives Gemini all the information it needs in one message.
  • temperature=0.3 keeps the output focused and consistent. A lower temperature means less creative randomness, which is exactly what you want for technical documentation.
  • model="gemini-2.5-flash" uses the Gemini 2.5 Flash model, which is free at up to 10 requests per minute.

Why a low temperature for documentation?

Temperature controls how "creative" the model is. For a creative story, you might use 0.9. For IT documentation, you want repeatable, accurate output that sticks closely to your knowledge base. A temperature of 0.3 gives the model just enough flexibility to write naturally while staying grounded in facts.

  • Save doc_generator.py.

Seeing a red underline on the imports?

If VS Code shows an import error under from google import genai, make sure your virtual environment is selected as the Python interpreter. Press Ctrl+Shift+P, type Python: Select Interpreter, and choose the one with venv in its path.

help me fix import errors in my doc_generator.py file

Test the documentation generator

Time to see your agent in action. You will load the monitoring knowledge base and ask Gemini to generate a troubleshooting guide from it.

  • In your VS Code terminal (with the virtual environment still active), run this command to test the generator:
python -c "from kb_loader import load_knowledge_base; from doc_generator import generate_documentation; context = load_knowledge_base(keywords=['monitoring']); print(generate_documentation('Create a troubleshooting guide for our monitoring stack', context))"

What should I see?

After a few seconds, you should see a block of HTML printed in your terminal. It will contain tags like <h2>, <ul>, and <li> with troubleshooting steps that reference Datadog, PagerDuty, and the common issues from your monitoring.md file.

The content should feel grounded in your knowledge base, not generic. If it mentions tools that are not in your Markdown files, something is wrong with the prompt.

Getting an API error?

  • If you see API key not valid, double-check that your GEMINI_API_KEY value in .env matches the key from Google AI Studio exactly (no extra spaces or quotes around the value).
  • If you see ModuleNotFoundError, confirm your virtual environment is active. You should see (venv) at the start of your terminal prompt.
  • If the command hangs for more than 30 seconds, the free tier may be experiencing high demand. Wait a minute and try again.

help me debug my Gemini API call in doc_generator.py

✔️ Awesome, I've got everything!

Great. Double check you have saved doc_generator.py before moving on.

ⓧ I'd like to double check the full code

Here is the complete doc_generator.py file:

import os
from google import genai
from google.genai import types
from dotenv import load_dotenv

load_dotenv()

SYSTEM_PROMPT = """You are an IT documentation specialist. Your job is to generate 
clear, well-structured IT documentation based on the provided knowledge base context.

Follow these rules:
1. Use the knowledge base context to ground your documentation in actual tools and processes.
2. Structure docs with clear headings, bullet points, and numbered steps where appropriate.
3. Include practical troubleshooting tips when relevant.
4. Keep language concise and professional.
5. Format output in HTML suitable for Confluence (use <h2>, <h3>, <p>, <ul>, <li>, <ol>, <table>, <tr>, <td>, <th> tags).
6. Do not invent tools or processes not mentioned in the knowledge base.
"""


def generate_documentation(request, knowledge_base_context):
    """Generate IT documentation using Gemini."""
    client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))

    prompt = f"""Based on the following knowledge base context, generate the requested documentation.

KNOWLEDGE BASE CONTEXT:
{knowledge_base_context}

DOCUMENTATION REQUEST:
{request}

Generate a well-structured IT documentation page in HTML format suitable for Confluence.
"""

    response = client.models.generate_content(
        model="gemini-2.5-flash",
        contents=prompt,
        config=types.GenerateContentConfig(
            system_instruction=SYSTEM_PROMPT,
            temperature=0.3,
        ),
    )

    return response.text

Your documentation generator is working. Next up, you will connect to Confluence and publish these AI-generated docs as real pages in your workspace.

Connect to Confluence and Publish

Your agent can generate structured IT documentation from your knowledge base. The missing piece is getting that documentation somewhere your team can actually read it.

In this step, you'll build a Confluence publisher module. It takes Gemini's HTML output and creates a formatted page in your Confluence space using the REST API.

In this step, get ready to:
  • Create authentication helpers for the Confluence API.
  • Build a function that publishes HTML pages to your Confluence space.
  • Test the full generate-and-publish pipeline end to end.
Create the authentication helpers

The Confluence REST API uses basic authentication with your email and API token. You'll create a dedicated module that handles auth and URL configuration, keeping your publishing logic clean.

  • In the VS Code Explorer sidebar, right-click in your project folder and select New File.
  • Name the file confluence_publisher.py.
  • Add the imports and helper functions by copying the following code into the file:
import os
import requests
from requests.auth import HTTPBasicAuth
from dotenv import load_dotenv

load_dotenv()


def get_auth():
    """Return HTTPBasicAuth for Confluence API."""
    email = os.getenv("CONFLUENCE_EMAIL")
    token = os.getenv("CONFLUENCE_API_TOKEN")
    return HTTPBasicAuth(email, token)


def get_base_url():
    """Return the Confluence base URL."""
    return os.getenv("CONFLUENCE_URL")

What does this code do?

This sets up the foundation for your Confluence integration.

  • HTTPBasicAuth packages your email and API token into the format Confluence expects for authentication.
  • load_dotenv() loads your .env variables so the functions can read your credentials securely.
  • The two helper functions keep credentials out of your main publishing logic, making the code easier to maintain.
  • Save confluence_publisher.py.
Build the page publisher function

Confluence pages are created by POSTing JSON to the REST API. The page body uses a format called "storage representation" which is HTML-based. Since Gemini already outputs HTML, you can pass it directly into the API payload.

  • In confluence_publisher.py, add the following function below get_base_url():

def publish_page(title, body_html, parent_id=None):
    """Publish a page to Confluence Cloud."""
    base_url = get_base_url()
    space_key = os.getenv("CONFLUENCE_SPACE_KEY")
    auth = get_auth()

    url = f"{base_url}/rest/api/content/"

    # Build the page payload in Confluence storage format
    page_data = {
        "type": "page",
        "title": title,
        "space": {"key": space_key},
        "body": {
            "storage": {
                "value": body_html,
                "representation": "storage",
            }
        },
    }

    # Optionally nest under a parent page
    if parent_id:
        page_data["ancestors"] = [{"id": parent_id}]

    headers = {"Content-Type": "application/json"}

    response = requests.post(url, json=page_data, auth=auth, headers=headers)

    if response.status_code == 200:
        page_info = response.json()
        page_url = f"{base_url}{page_info['_links']['webui']}"
        return {"success": True, "url": page_url, "id": page_info["id"]}
    else:
        return {"success": False, "error": response.text, "status": response.status_code}

What does this code do?

This function handles the full lifecycle of creating a Confluence page.

  • It builds a JSON payload with the page title, space key, and body HTML wrapped in Confluence's storage representation format.
  • The optional parent_id parameter lets you nest pages under an existing page (useful for organising docs into sections).
  • On success (HTTP 200), it returns the new page's URL and ID. On failure, it returns the error details so you can debug.

What is Confluence storage format?

Confluence stores page content as XHTML-based markup called "storage format." Standard HTML tags like <h2>, <p>, and <ul> work directly. Your Gemini system prompt already asks the model to output compatible HTML, so no extra conversion is needed.

  • Save confluence_publisher.py.

Seeing a red underline on the imports?

Make sure your virtual environment is activated in the VS Code terminal. You should see (venv) at the beginning of your terminal prompt. If not, run .\venv\Scripts\activate again.

help me fix import errors in my confluence_publisher.py file

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before moving on to the test.

ⓧ I'd like to double check the full code

Here is the complete confluence_publisher.py file. Make sure yours matches exactly.

import os
import requests
from requests.auth import HTTPBasicAuth
from dotenv import load_dotenv

load_dotenv()


def get_auth():
    """Return HTTPBasicAuth for Confluence API."""
    email = os.getenv("CONFLUENCE_EMAIL")
    token = os.getenv("CONFLUENCE_API_TOKEN")
    return HTTPBasicAuth(email, token)


def get_base_url():
    """Return the Confluence base URL."""
    return os.getenv("CONFLUENCE_URL")


def publish_page(title, body_html, parent_id=None):
    """Publish a page to Confluence Cloud."""
    base_url = get_base_url()
    space_key = os.getenv("CONFLUENCE_SPACE_KEY")
    auth = get_auth()

    url = f"{base_url}/rest/api/content/"

    page_data = {
        "type": "page",
        "title": title,
        "space": {"key": space_key},
        "body": {
            "storage": {
                "value": body_html,
                "representation": "storage",
            }
        },
    }

    if parent_id:
        page_data["ancestors"] = [{"id": parent_id}]

    headers = {"Content-Type": "application/json"}

    response = requests.post(url, json=page_data, auth=auth, headers=headers)

    if response.status_code == 200:
        page_info = response.json()
        page_url = f"{base_url}{page_info['_links']['webui']}"
        return {"success": True, "url": page_url, "id": page_info["id"]}
    else:
        return {"success": False, "error": response.text, "status": response.status_code}
Test the full generate-and-publish flow

Time to see your agent publish a real page. You'll generate a monitoring overview from your knowledge base and send it straight to Confluence.

  • In your VS Code terminal, run the following command to test the full pipeline:
python -c "from kb_loader import load_knowledge_base; from doc_generator import generate_documentation; from confluence_publisher import publish_page; context = load_knowledge_base(keywords=['monitoring']); doc = generate_documentation('Create a brief monitoring overview', context); result = publish_page('Test Doc - Monitoring Overview', doc); print(result)"

What does this command do?

This one-liner exercises the entire pipeline in sequence.

  • It loads your monitoring knowledge base file.
  • It sends the content to Gemini with a documentation request.
  • It publishes the generated HTML to your Confluence space as a page titled "Test Doc - Monitoring Overview."
  • Check the terminal output. You should see a dictionary with 'success': True and a URL pointing to your new Confluence page.
  • Open that URL in your browser to verify the page exists with formatted headings, bullet points, and content about your monitoring stack.

Seeing 'success': False in the output?

Check the status code in the output to diagnose the problem.

  • Status 401 (Unauthorized): Double check your CONFLUENCE_EMAIL and CONFLUENCE_API_TOKEN in your .env file. The email must match the account that owns the API token.
  • Status 404 (Not Found): Verify your CONFLUENCE_URL ends with /wiki and your CONFLUENCE_SPACE_KEY matches the space key shown in your Confluence URL when browsing that space.
  • Status 400 (Bad Request): The page title might already exist in your space. Try changing the title to something unique.

help me debug my Confluence API error

Your agent can now generate documentation and publish it to a live Confluence space. Next up, you'll tie everything together with a polished command-line interface so you can run the full pipeline with a single command.

Build the CLI Interface

You have three separate Python modules that each handle one job: loading knowledge base files, generating documentation with Gemini, and publishing to Confluence. Right now, the only way to use them is by importing and calling functions manually.

In this step, you will tie everything together into a single main.py script with a proper command-line interface. This gives you a one-command tool you can run from the terminal to generate and publish docs instantly.

In this step, get ready to:
  • Combine all modules into a CLI entry point with argparse.
  • Add a --list-topics flag that shows available knowledge base files.
  • Run the full pipeline end-to-end and get a Confluence URL back.
Create main.py with the CLI interface

Python's built-in argparse module lets you define command-line arguments and flags that users can pass when running your script. You will use it to accept a documentation request, optional keywords for filtering, and utility flags like --list-topics.

  • Create a new file called main.py in your project folder (the same folder where kb_loader.py lives).
  • Paste the following code into main.py:
import argparse
from kb_loader import load_knowledge_base, list_topics
from doc_generator import generate_documentation
from confluence_publisher import publish_page


def main():
    parser = argparse.ArgumentParser(
        description="IT Documentation Agent - Generate and publish docs to Confluence"
    )
    parser.add_argument("request", nargs="?", help="Documentation request (e.g., 'Generate a troubleshooting guide for our monitoring stack')")
    parser.add_argument("--title", help="Title for the Confluence page")
    parser.add_argument("--keywords", nargs="+", help="Keywords to filter knowledge base files")
    parser.add_argument("--list-topics", action="store_true", help="List available knowledge base topics")
    parser.add_argument("--no-publish", action="store_true", help="Generate doc without publishing to Confluence")

    args = parser.parse_args()

    if args.list_topics:
        print("\nAvailable Knowledge Base Topics:")
        print("-" * 35)
        for topic in list_topics():
            print(f"  - {topic}")
        print()
        return

    if not args.request:
        parser.print_help()
        return

    print(f"\n[1/3] Loading knowledge base...")
    context = load_knowledge_base(keywords=args.keywords)

    if not context:
        print("No matching knowledge base files found. Try different keywords or omit --keywords to load all.")
        return

    print(f"[2/3] Generating documentation with Gemini...")
    doc_html = generate_documentation(args.request, context)

    if args.no_publish:
        print("\n--- Generated Documentation (HTML) ---\n")
        print(doc_html)
        return

    title = args.title or f"Generated: {args.request[:50]}"
    print(f"[3/3] Publishing to Confluence...")
    result = publish_page(title, doc_html)

    if result["success"]:
        print(f"\nDone! Page published successfully.")
        print(f"View it here: {result['url']}")
    else:
        print(f"\nFailed to publish. Status: {result['status']}")
        print(f"Error: {result['error']}")


if __name__ == "__main__":
    main()

What does this code do?

This file imports all three of your modules and orchestrates them through a single main() function.

  • argparse defines five arguments: a positional request (the doc you want generated), --title for the Confluence page name, --keywords to filter the knowledge base, --list-topics to see available files, and --no-publish to preview without publishing.
  • The nargs="?" on the request argument makes it optional so the script can handle --list-topics without requiring a request.
  • The pipeline prints progress indicators ([1/3], [2/3], [3/3]) so you know which stage is running.
  • Save main.py.

Seeing a red underline on an import?

If VS Code shows a warning under from kb_loader import, make sure main.py is in the same folder as kb_loader.py, doc_generator.py, and confluence_publisher.py. Also confirm your virtual environment is selected as the Python interpreter in VS Code.

Help me fix import errors in my Python project

List available topics

The --list-topics flag gives you a quick overview of what knowledge base files are available before you write a documentation request.

  • Test the flag by running this command in your VS Code terminal:
python main.py --list-topics
  • You should see output listing your three knowledge base topics:
Available Knowledge Base Topics:
-----------------------------------
  - Monitoring
  - Ci Cd
  - Cloud Infra

Why is this useful?

When you use the --keywords flag later, you will need to know what topics exist in your knowledge base. This flag makes that easy without opening the folder.

Seeing a ModuleNotFoundError?

If the terminal says ModuleNotFoundError: No module named 'kb_loader', make sure you are running the command from the same folder where your Python files live. Run ls or dir to confirm you can see main.py and kb_loader.py in the output.

Help me fix ModuleNotFoundError in my project

Run the full pipeline end-to-end

Now for the real test. You will run a single command that loads your knowledge base, sends a request to Gemini, generates a formatted document, and publishes it straight to Confluence.

  • Run the full pipeline by running this command:
python main.py "Generate a troubleshooting guide for our monitoring stack" --keywords monitoring --title "Monitoring Troubleshooting Guide"

What do these flags do?

  • The first argument (in quotes) is your documentation request. This is the prompt that tells Gemini what to write.
  • --keywords monitoring filters the knowledge base to only load files containing "monitoring".
  • --title sets the Confluence page title instead of using the auto-generated one.
  • Watch the progress indicators in your terminal. You should see:
[1/3] Loading knowledge base...
[2/3] Generating documentation with Gemini...
[3/3] Publishing to Confluence...

Done! Page published successfully.
View it here: https://yoursite.atlassian.net/wiki/spaces/...
  • Click the URL in the terminal output to open your new Confluence page.
  • Confirm the page has a proper title and formatted content with headings, bullet points, and troubleshooting tips.

Seeing "Failed to publish"?

If you see a 401 status, double-check that your CONFLUENCE_EMAIL and CONFLUENCE_API_TOKEN in .env are correct. If you see a 404, verify your CONFLUENCE_URL ends with /wiki and your CONFLUENCE_SPACE_KEY matches the space key shown in your Confluence URL bar.

Help me debug my Confluence publish error

✔️ Awesome, I've got everything!

Great. Double check you have saved main.py.

ⓧ I'd like to double check the full code

Here is the complete main.py file for comparison:

import argparse
from kb_loader import load_knowledge_base, list_topics
from doc_generator import generate_documentation
from confluence_publisher import publish_page


def main():
    parser = argparse.ArgumentParser(
        description="IT Documentation Agent - Generate and publish docs to Confluence"
    )
    parser.add_argument("request", nargs="?", help="Documentation request (e.g., 'Generate a troubleshooting guide for our monitoring stack')")
    parser.add_argument("--title", help="Title for the Confluence page")
    parser.add_argument("--keywords", nargs="+", help="Keywords to filter knowledge base files")
    parser.add_argument("--list-topics", action="store_true", help="List available knowledge base topics")
    parser.add_argument("--no-publish", action="store_true", help="Generate doc without publishing to Confluence")

    args = parser.parse_args()

    if args.list_topics:
        print("\nAvailable Knowledge Base Topics:")
        print("-" * 35)
        for topic in list_topics():
            print(f"  - {topic}")
        print()
        return

    if not args.request:
        parser.print_help()
        return

    print(f"\n[1/3] Loading knowledge base...")
    context = load_knowledge_base(keywords=args.keywords)

    if not context:
        print("No matching knowledge base files found. Try different keywords or omit --keywords to load all.")
        return

    print(f"[2/3] Generating documentation with Gemini...")
    doc_html = generate_documentation(args.request, context)

    if args.no_publish:
        print("\n--- Generated Documentation (HTML) ---\n")
        print(doc_html)
        return

    title = args.title or f"Generated: {args.request[:50]}"
    print(f"[3/3] Publishing to Confluence...")
    result = publish_page(title, doc_html)

    if result["success"]:
        print(f"\nDone! Page published successfully.")
        print(f"View it here: {result['url']}")
    else:
        print(f"\nFailed to publish. Status: {result['status']}")
        print(f"Error: {result['error']}")


if __name__ == "__main__":
    main()

Your IT documentation agent is complete. You now have a single command that reads your knowledge base, generates professional documentation with AI, and publishes it to a live Confluence page. Next up, you will take on the Secret Mission and add batch mode to generate entire documentation sets in one go.

Secret mission

Add Batch Mode for Bulk Documentation Generation

Your agent can generate one doc at a time. But real IT teams need entire documentation sets created at once. Can you add a batch mode that reads a template file and generates all docs sequentially, complete with progress tracking and rate limiting?

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally and uses free-tier APIs, so there are no ongoing costs. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Resources you used:

  • Python virtual environment (venv) in your project folder.
  • Project folder with Python scripts (main.py, kb_loader.py, doc_generator.py, confluence_publisher.py).
  • Knowledge base Markdown files in knowledge_base/.
  • .env file containing your API keys.
  • Google AI Studio account and API key.
  • Confluence Cloud free instance and API token.
  • Pages published to your Confluence space.

Keep everything running

No action needed. Choose this if you plan to keep using the documentation agent or want to expand your knowledge base.

  • Your project folder, virtual environment, and all scripts stay on your Desktop.
  • Your Google AI Studio API key remains active on the free tier.
  • Your Confluence Cloud instance stays available at no cost.

Pause - I'll come back to this later

Free up local resources while keeping your accounts and files intact for later use.

  • Deactivate your virtual environment by running deactivate in your terminal.
  • Keep your project folder as-is. You can reactivate the virtual environment later.
  • Your Google AI Studio and Confluence accounts will remain active on their free tiers with no action needed.

Delete - I don't want to use this again

Remove all project resources and revoke access tokens.

  • Delete your project folder from your Desktop.
  • Revoke your Google AI Studio API key at https://aistudio.google.com/ under the API keys section.
  • Revoke your Confluence API token at https://id.atlassian.com/manage-profile/security/api-tokens.
  • Delete any generated pages from your Confluence space if you no longer need them.
  • Optionally, delete your Confluence Cloud site from the Atlassian admin panel if you do not plan to use it for other projects.

Nice Work!

Nice Work!

You just built an AI-powered IT documentation agent from scratch. You can now generate structured, context-aware documentation and publish it directly to Confluence with a single command.

Here's what you learned:

  • Built a structured knowledge base of Markdown files and a Python loader that filters context by keywords.
  • Integrated with the Google Gemini API using system instructions and temperature control to generate professional IT documentation.
  • Connected to the Confluence Cloud REST API to publish formatted pages with a reusable CLI tool.
  • Added batch mode to generate entire documentation sets from a template file in one command.

Ready to quiz yourself?