cd /news/ai-agents/find-every-ai-agent-in-your-python-c… · home › topics › ai-agents › article
[ARTICLE · art-162462] src=pub.towardsai.net ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Find every AI agent in your Python code: OpenAI Agents SDK, LangGraph, CrewAI and Google ADK

An open-source tool called Marshal can inventory AI agents written in Python by parsing source files with Python's built-in ast module, without importing or executing any code, according to the tool's author. Marshal recognizes agent constructor calls across the OpenAI Agents SDK, LangGraph, CrewAI and Google ADK, plus direct calls to the OpenAI, Anthropic, Google GenAI, LiteLLM and Bedrock Runtime APIs, which it records as inferred agents. Run against four public example repositories — OpenAI's Agents SDK examples, Google's ADK samples, CrewAI's project template and Anthropic's quickstarts — Marshal found 22 agents, with per-agent completeness scores ranging from 10% to 37% because model names and other values read from environment variables are recorded as unknown.

by read5 min views1 publishedNov 2, 2026

Agents written in code don’t show up in any admin console. Static analysis can list them, with their models and tools, without running a line of the code.

An agent built in Copilot Studio at least appears in Copilot Studio’s admin pages. An agent written in Python appears nowhere. It’s a constructor call in some module, with its model name in a config file, its prompt in a text file and its tools in three other modules. It changes with every commit, and it may be one of a dozen across your repositories.

If someone asks which of your services run agents, which models they call and which functions they can invoke, the answer is often a grep and a guess. I wrote a reader for Marshal, an open-source AI agent inventory, that answers it from the code instead. In an earlier article I covered the inventory for agents built on platforms. This one is about agents in code.

Marshal parses Python files with Python’s own ast module, the way a linter does. Nothing is imported or executed, so it's safe to point at any repository, and it needs no API keys.

Each call to an agent constructor is one agent:

Code that calls a model API directly and passes it tools is an agent loop too, even without a framework. Marshal records those calls to the OpenAI, Anthropic, Google GenAI, LiteLLM and Bedrock Runtime APIs as agents, marked as inferred.

A small evaluator resolves what can be known without running anything: string literals, f-strings, names in the same module, imports between the project’s own modules, and prompt files read from disk. Anything else, such as a model name read from an environment variable, is recorded as unknown with the reason. Marshal doesn’t fill in a value it can’t see in the code.

I ran it on four public example repositories: OpenAI’s Agents SDK examples, Google’s ADK samples, CrewAI’s project template and Anthropic’s quickstarts.

$ for repo in */; do marshal collect "$repo" --event shipped --environment prod; done$ marshal lsAGENT                                PLATFORM       LATEST  SHIPPED  FRESHNESS        COMPLETEanthropic-quickstarts/sampling-loop  anthropic-api  v1      prod v1  prod: manual 0d  25%crewai-template/reporting-analyst    crewai         v1      prod v1  prod: manual 0d  30%crewai-template/researcher           crewai         v1      prod v1  prod: manual 0d  30%google-adk/critic-agent              google-adk     v1      prod v1  prod: manual 0d  37%google-adk/reviser-agent             google-adk     v1      prod v1  prod: manual 0d  25%openai-agents/faq-agent              openai-agents  v1      prod v1  prod: manual 0d  20%openai-agents/seat-booking-agent     openai-agents  v1      prod v1  prod: manual 0d  20%openai-agents/triage-agent           openai-agents  v1      prod v1  prod: manual 0d  10%# 14 more openai-agents rows

That’s 22 agents across four frameworks. The Anthropic one has no framework at all: it’s the computer-use demo’s sampling loop, found because it calls the Messages API with tools.

The COMPLETE column says how much of each agent the code states. A low number is information too. It tells you which agents depend on values that only exist at run time.

Here is part of the record for the FAQ agent in OpenAI’s customer service example:

agent: customer_service/faq-agentplatform: openai-agentssource:  format: python  artifact: main.py  locator: agents.Agent at line 94spec:  display_name:    value: FAQ Agent    provenance: declared  model:    requested:      provenance: unknown      basis: the SDK's default model is used    provider:      value: openai      provenance: derived      basis: the OpenAI Agents SDK's default client  instructions:    provenance: derived    basis: 'main.py:94; unresolved parts in braces: RECOMMENDED_PROMPT_PREFIX'  tools:  - ref: tool/python.customer_service/main:faq_lookup_tool    name: faq_lookup_tool    description: Lookup frequently asked questions.

Every value says where it came from. The name is declared in the code. The provider is derived from a documented rule, because the SDK uses OpenAI’s client unless you pass another. The model is unknown, because the agent relies on the SDK’s default, which a new SDK release can change. The instructions are recorded with the one part that couldn’t be resolved, a prefix imported from the SDK package, left in braces.

For an audit, that unknown model is a finding. It means the agent’s model changes when someone upgrades a dependency, without any change to the agent’s own code.

The inventory gets more useful once it runs on every pull request. Here is a one-line change to the same example that gives the FAQ agent the seat-booking agent’s tool:

-    tools=[faq_lookup_tool],+    tools=[faq_lookup_tool, update_seat],

Marshal compares the proposed agents with what’s shipped and ranks the change:

customer_service/faq-agent (openai-agents)  prod: v1 → v2
HIGH  + tool tool/python.customer_service/main:update_seat (scope unknown, reversible unknown)
Completeness 15%

It’s HIGH because the code doesn’t say whether update_seat only reads or also writes, and Marshal doesn't guess from a function's name. A new tool whose effect is unknown gets the same rank as a new write tool. In CI, the GitHub Action posts this as a pull request comment, and the GitLab CI template does the same on a merge request.

The reverse question matters before you change a function that agents call:

$ marshal deps "tool/python.*:update_seat"AGENT                                VERSION  WHERE          RELATION  REFcustomer_service/faq-agent           v2       latest         tool      tool/python.customer_service/main:update_seatcustomer_service/seat-booking-agent  v1       prod (latest)  tool      tool/python.customer_service/main:update_seat

Tool references include the project, so two copies of the same template in different repositories stay two different tools.

Static analysis has limits, and the records say where they are. A model name from an environment variable or a function parameter is unknown. Tools assembled at run time are reported with a warning; the Anthropic sampling loop builds its tool list at run time, so its record says so. Custom LangGraph StateGraph workflows aren't read yet, only the prebuilt agent constructors, and neither are model calls whose arguments arrive through **kwargs.

When a framework changes its API, a weekly job in Marshal’s repository runs the tests against each framework’s latest public examples and opens an issue when they fail.

Find every AI agent in your Python code: OpenAI Agents SDK, LangGraph, CrewAI and Google ADK was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

── more in #ai-agents 4 stories · sorted by recency
── more on @marshal 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/find-every-ai-agent-…] indexed:0 read:5min 2026-11-02 · —