What This Guide Is
This is a progressive Python guide built specifically for documentation engineers. Instead of teaching Python in the abstract, every example builds toward a real use case: making documentation accessible to AI agents programmatically.
You'll go from a 6-line dictionary lookup to a fully traced AI agent that serves documentation as a tool β the exact architecture used in production systems like Arize Phoenix, LangChain, and MCP servers.
You don't need a CS degree. If you can read and modify 8 Python concepts (variables, strings, lists, dictionaries, functions, conditions, loops, and API calls), you can follow β and explain β production agent code.
This is the first Python you need. A function that takes a topic and returns documentation. That's it β no frameworks, no APIs, no AI.
def get_doc(topic):
docs = {
"tracing": "Tracing records what your AI application did.",
"span": "A span represents one operation in a trace.",
"evaluation": "Evaluations measure the quality of AI behavior."
}
return docs.get(topic, "Documentation not found.")
print(get_doc("tracing"))
What Each Line Does
def β creates a function (a reusable block of logic)
topic β information coming into the function (the input parameter)
docs β a dictionary: a collection of keyβvalue pairs (like a real documentation index)
.get() β looks up a key in the dictionary, returns a fallback if not found
return β sends the result back to whoever called the function
print() β displays the result in the terminal
Why This Matters
This is already conceptually relevant to documentation engineering. Instead of making someone leave their workflow to search docs manually, you expose documentation programmatically β as data that code can consume.
Now make it realistic. Instead of exact-match lookup, add search β a user types a partial query and gets the matching doc.
def search_docs(query):
"""Search product documentation."""
docs = {
"trace": "A trace represents an end-to-end request.",
"span": "A span represents an individual operation.",
"tool": "A tool allows an agent to perform an action.",
"evaluation": "An evaluation measures application quality."
}
for topic, content in docs.items():
if query.lower() in topic.lower():
return content
return "No documentation found."
result = search_docs("span")
print(result)
New Concepts
"""docstring""" β describes what a function does (agents read these to decide when to call a tool)
for ... in β loops through every item in the dictionary
.lower() β converts text to lowercase for case-insensitive matching
if ... in β checks if the query appears inside the topic name
The Architecture You're Building
User β Agent β Documentation Tool β Documentation Source β Answer
That flow is exactly the architecture you should be comfortable discussing. The important concept isn't memorizing the syntax β it's understanding this pipeline.
This is where it gets real. You define a function, then describe it as a tool that an AI model can choose to call. This is exactly how production agent systems work.
def search_arize_docs(topic):
"""Return documentation for an Arize concept."""
docs = {
"trace": "A trace represents the complete execution path.",
"span": "A span represents one operation inside a trace.",
"evaluation": "Evaluations measure application behavior."
}
return docs.get(topic.lower(), "Documentation not found.")
tools = [
{
"name": "search_arize_docs",
"description": "Search Arize product documentation",
"parameters": {
"topic": "Documentation topic to search"
}
}
]
When a user asks "What is a span?", here's what happens:
User asks: "What is a span?"
β
βΌ
Agent determines: I need documentation.
β
βΌ
search_arize_docs("span")
β
βΌ
Documentation returned
β
βΌ
Agent generates answer using the retrieved doc
Key Insight
Now you're talking about tool invocation, not merely Python. The model reads the tool description (the docstring + parameters), decides it needs documentation, calls your function, and uses the result to generate an answer. This is exactly how MCP tools, OpenAI function calling, and LangChain tools work.
How to Describe This
"I defined a documentation lookup function and exposed it as a tool that an AI agent can invoke. The agent reads the tool description, determines when documentation is needed, calls the function with the right parameters, and uses the result to generate an accurate answer. This is the same pattern used in MCP servers and OpenAI function calling."
This is where it becomes production-grade. Arize Phoenix traces every step the agent takes β so you can see what happened, what went wrong, and how to improve it.
from phoenix.otel import register
tracer_provider = register(
project_name="documentation-agent"
)
from openinference.instrumentation.openai import OpenAIInstrumentor
OpenAIInstrumentor().instrument(
tracer_provider=tracer_provider
)
Now every agent operation is traced. Here's what Phoenix captures:
USER
β
βΌ
AI AGENT
β
βββ LLM call β Phoenix captures prompt, model, tokens
β
βββ search_docs() β Phoenix captures tool name, input, output
β
βββ documentation retrieved β Phoenix captures the doc content returned
β
βββ answer generated β Phoenix captures the final response
β
βΌ
PHOENIX DASHBOARD
β
βββ Trace (the full request)
βββ Spans (each individual step)
βββ Tool calls (which tools, what inputs)
βββ Inputs / Outputs (what went in, what came out)
βββ Latency (how long each step took)
What Each Part Does
register() β connects your app to Phoenix and starts recording traces
tracer_provider β the connection object that all instrumentors use
OpenAIInstrumentor β automatically traces all OpenAI API calls (prompts, responses, tokens)
.instrument() β activates the tracing for that specific provider
How to Describe This
"Phoenix tracing records every step an agent takes β the LLM calls, tool invocations, inputs, outputs, and latency. I register a tracer provider, instrument the LLM client, and then every operation becomes visible in the Phoenix dashboard. I've done this in production β I instrumented my own multi-provider app with Phoenix, captured 50 spans across 6 AI providers, and documented the setup process including Node.js-specific gotchas."
Here's the real-world scenario. A developer hits an error. Instead of leaving their IDE to search docs manually, an AI agent serves the relevant documentation instantly.
error = "AuthenticationError: API key invalid"
result = search_docs("authentication")
Without a documentation agent, the developer's workflow looks like this:
Developer β stop coding β open Google β search "Arize auth error"
β find docs site β navigate to authentication page
β read through docs β find the relevant section
β return to IDE β apply the fix
Total context switches: 6+
Time lost: 5β15 minutes
With a documentation agent:
Developer β error appears β AI assistant catches it
β calls documentation tool β relevant doc returned
β answer appears in IDE
Total context switches: 0
Time: seconds
How to Describe This
"The value of documentation engineering isn't just writing good docs β it's making docs accessible where developers already work. A documentation tool lets an AI agent serve the right doc at the right moment without the developer ever leaving their IDE. That's what reduces time-to-resolution from minutes to seconds."
Production documentation systems don't hardcode docs in dictionaries β they call APIs. Here's the fundamental pattern for every API call you'll encounter:
import requests
response = requests.get(
"ARIZE_API_ENDPOINT",
headers={
"Authorization": "YOUR_API_KEY"
}
)
data = response.json()
print(data)
What Each Line Does
import requests β loads the HTTP library (like opening a browser programmatically)
requests.get() β sends an HTTP GET request to a URL
headers β authentication credentials sent with the request
.json() β converts the API response into Python data you can work with
Once you understand this pattern, SDK operations become readable:
datasets = get_datasets()
experiments = get_experiments()
monitors = get_monitors()
How to Describe This
"Every API follows the same pattern: import, authenticate, request, parse response. Once you recognize that pattern, you can read and document any SDK β whether it's Arize AX, OpenAI, or a custom internal API. The specific endpoints and authentication methods change, but the structure is always the same."
You don't need a full Python course. If you can read, modify, and explain these 8 things, you can follow a surprising amount of production Python used in documentation and SDK examples.
topic = "tracing"
message = "Search the documentation"
topics = ["tracing", "spans", "evaluations"]
doc = {
"title": "Tracing",
"url": "/docs/tracing"
}
def search_docs(query):
return "documentation"
if topic == "tracing":
print("Tracing documentation")
for topic in topics:
print(topic)
response = client.some_operation()
How to Describe This
"I focus on the 8 Python patterns that appear in every SDK and documentation example: variables, strings, lists, dictionaries, functions, conditions, loops, and API calls. I don't need to be a Python developer β I need to read, modify, and accurately document code that uses these patterns. That's what documentation engineers do."