默认把 trace 以 JSON 文件写到本地 ./monocle 目录,需自行接入后端查看;测试工具是独立包 monocle_test_tools,需单独安装;追踪 Claude Code、Codex、Copilot 需额外运行 monocle-apptrace *-setup 注册钩子。
monocle
monocle2aiApache-2.0活跃维护面向 GenAI 应用的 Python 追踪框架,基于 OpenTelemetry 采集 LLM 调用与 Agent 执行链路,帮开发者定位问题、做可观测性。
Monocle is a framework for tracing GenAI app code. This repo contains implementation of Monocle for GenAI apps written in Python.
pip install monocle_apptrace
pip install monocle_test_toolsREADME 未说明
基于 OpenTelemetry 的 GenAI 应用追踪与测试框架,让 Agent 黑盒变成可观测的分步链路
面向 GenAI 应用的 Python 追踪框架,基于 OpenTelemetry 采集 LLM 调用与 Agent 执行链路,帮开发者定位问题、做可观测性。
核心能力
- 用 Metamodel 把 agent、prompt、tool、向量操作映射为标准化 span 属性
- 为 LangChain、LlamaIndex、Haystack、Google ADK 等框架自动埋点生成 span
- 输出标准 OTLP span,可接入现有 collector 与 APM 后端
- monocle-test-tools 基于 pytest 对 trace 断言工具调用与 token 成本
- 支持 in-code 初始化与 wrapper 命令行两种零侵入追踪模式
容易踩的坑
- v0.8.16Version 0.8.16最新正式版2026-10-30 · 2026-10-30 19:06 UTC
This is a patch release on the previous 0.8.15 release, fixing the issue(s) below.
- feat(test_tools): a failed scenario test leads with a short reason and the turn it failed at, short enough for pytest's one-line summary, followed by the judge's reasoning and the conversation with each turn's trace id; the harness's own frames are hidden from the traceback.
--monocle-scenario-results(orMONOCLE_SCENARIO_RESULTS=true) also logs every result of a run to.monocle/test_results/scenarios_<time>.log. Off by default (#840) - fix(instrumentation): the LangChain inference span records every tool the model asked for, not just the first. A model can return several tool calls in one response, and
entity.3.nameanddata.outputboth kept onlytool_calls[0]— so a turn that booked a flight and a hotel together named one of them, even though both tools ran and both have their ownagentic.tool.invocationspan. One tool call still reads exactly as before; several are listed, so no existing trace changes shape.agent_inference_typelikewise reports a delegation wherever the handoff sits in the list (#261, #841) - feat(instrumentation): the workflow span sets
parent.is_remote = truewhen its parent came from another process, such as an A2A caller. An exported span keeps onlyparent_id, so a reader could not tell the root of this app's part of a shared trace from a span whose parent went missing. Spans with a local parent or no parent are unchanged (#841) - fix(instrumentation): the FastAPI http span records a usable url. It was built from the socket the server is bound to, so an app listening on IPv6 reported the unparseable
http://::1:10333/. The Host header the client sent is used when present (http://localhost:10333/), and the socket fallback brackets an IPv6 host (#837) - feat(test_tools): scenario tests — describe an agent in a sentence and the goals people bring to it, and
@MonocleValidator().monocle_scenario_testcase(seed)generates multi-turn test conversations from it: different kinds of users, users who hold details back until asked, requests the agent should refuse, and red-team attacks adapted from DeepTeam's templates.test_scenario_async(agent, agent_type, scenario)runs each one live against the agent as its own pytest case, with a simulated user playing the customer and an LLM judge deciding after each reply whether the scenario's success criteria are met — checked against the turn's actual tool calls, not the agent's claims. Generated scenarios are cached inscenarios.jsonbeside the test, so later runs make no model call, and every conversation is traced as its own session. See test_tools/README.md (#830, #842) - chore(deps):
monocle_test_toolsnow installslangchain,langchain-openaiandpyyamlby default, for the scenario tests' simulated user, judge and seed files. Thetest_agentextra is kept, empty, so existing installs keep working (#830) - feat(instrumentation): while the
MONOCLE_SUPPRESS_SPANScontext value isTrue, instrumented calls still run but emit no spans — unlikeMONOCLE_SKIP_EXECUTIONS, which skips the call. Scenario tests use it to keep the simulated user's and judge's own LLM calls out of the agent's trace (#830) - fix(instrumentation): LlamaIndex, LangChain and Haystack retrieval spans record the full retrieved context instead of its first 100 characters, so an eval of a RAG answer sees what the model was actually given; LlamaIndex also kept only the first document. All documents a
- feat(test_tools): a failed scenario test leads with a short reason and the turn it failed at, short enough for pytest's one-line summary, followed by the judge's reasoning and the conversation with each turn's trace id; the harness's own frames are hidden from the traceback.
- v0.8.15Version 0.8.152026-09-11 · 2026-09-11 19:10 UTC
查看更新说明
This is a patch release on the previous 0.8.14 release, fixing the issue(s) below.
- fix(instrumentation): a streaming inference whose consumer stops reading early now emits a span — the tokens it spent were previously unreported.
close()/aclose()on the stream is the only deterministic end signal, since Python leaves an abandoned generator to the garbage collector, so both the in-place patch path and the fallback wrapper classes emit there, guarded so aclose()after full consumption cannot produce a second span (#818) - fix(test_tools): an Okahu endpoint environment variable that is set but empty falls back to the default endpoint instead of building a scheme-less URL.
os.getenv(name, DEFAULT)only applies its default when the name is absent, and an undefined CI variable expands to"", so requests raised "No scheme supplied" on/v1/eval/templates;OKAHU_API_KEYis likewise no longer.strip()ped unguarded when unset (#817) - fix(test_tools): remote trace retrieval waits up to
MONOCLE_REMOTE_TRACE_ID_TIMEOUTseconds (default 60) for the agent's spans to reach the backend, instead of a hard-coded 10s that was under the time an out-of-process export takes (#817) - fix(test_tools): a failing test now reports its own error.
post_test_cleanupalready stops the scope token, but both wrappers stopped it a second time, and the double detach raisedRuntimeError: <Token ...> has already been used oncefrom thefinallyblock while the real exception was propagating (#814) - fix(test_tools):
@pytest.mark.xfailapplies to fluent assertions. They record rather than raise, so the outcome is flipped to failed after pytest's own xfail hookwrapper has already seen a passing call — intentional-failure tests reported as hard failures, and a test that silently stopped failing was masked as a pass (#814) - fix(instrumentation):
reset_span_processorsre-appends the trace-return processor the waysetup_monocle_telemetrydoes; rebuilding the processor list on an initialised instrumentor silently dropped trace return for the rest of the process (#814) - fix(test_tools): the llamaindex runner passes
memory=only to callables that accept it, and binds it withfunctools.partialforrun_in_executor, which takes no kwargs (#814) - feat(test_tools): the Okahu enumerators walk every page instead of stopping at the server's first page of 100, so a fact past the first page becomes a test case rather than being silently absent.
page_sizeis bounds-checked locally rather than reaching the wire as an opaque HTTP 400, and a short collection warns against the advertisedfact_countrather than raising, since discovery runs at collection time (#813) - feat(test_tools):
setup_test_casesrefuses a discovery window holding more thanmax_factsfacts (argument, thenOKAHU_MAX_FACTS, then 1000) — paginating the enumerators removed the accidental ceiling the 100-fact page used to impose, and an unbounded window is minutes of collection time and a large token bill. It refuses rather than truncating, since a silent subset is the defect pagination set out to remove (#813) - feat(test_tools): the Okahu API timeout is 120s and overridable by
OKAHU_API_TIMEOUT; precedence is explicit argument, then the variable, then the default. An unusable value is logged and ignored rather than stopping span loading (#810) - feat(test_tools): a fact whose spans will not load is emitted carrying the reason in
FluentTestCase.load_errorand appears as one
- fix(instrumentation): a streaming inference whose consumer stops reading early now emits a span — the tokens it spent were previously unreported.
- v0.8.14Version 0.8.142026-08-27 · 2026-08-27 16:47 UTC
查看更新说明
This is a patch release on the previous 0.8.13 release, fixing the issue(s) below.
- fix(exporters): span obfuscation no longer swallows the sentence punctuation after an unquoted credential value —
password=hunter2. Next sentence.now redacts topassword=<REDACTED>. Next sentence.instead ofpassword=<REDACTED> Next sentence.. Dots inside the value are still treated as part of the secret - fix(instrumentation):
extract_tool_name/extract_tool_typein the LiteLLM metamodel now recognize ReAct-style text tool calls ("Action: ", used by CrewAI), matchingextract_finish_reason's existing handling of the same response shape. Previously the span was typed as a tool call buttool.name/tool.typestayedNone(#797) - feat(test_tools):
check_eval'seval_nameaccepts either a built-in eval template name or the path of a custom eval template JSON file (apathlib.Pathor a path-like string), instead of the caller having to switch to thetemplate_pathparameter for custom templates. Which kind it is is detected from the value, using the evaluator's existing built-in vs. custom rule (BaseEval.classify_eval_input) - feat(exporters)!: pluggable sensitive-data obfuscation for span exports, on by default —
data.input/data.outputpayloads are scrubbed before a span reaches any exporter, so credentials never leave the process. Redacts API keys (OpenAI, Anthropic, AWS, Google, GitHub, Slack), bearer tokens, JWTs, PEM private keys andapi_key/password/client_secret-style assignments, and deliberately leaves everything else alone. Disable withMONOCLE_DISABLE_SPAN_OBFUSCATION=true,MONOCLE_SPAN_OBFUSCATORS=none, orsetup_monocle_telemetry(span_obfuscators=[]). Add PII detection withMONOCLE_SPAN_OBFUSCATORS=credentials,presidio(pip install monocle_apptrace[obfuscation]), or plug in your ownSpanObfuscatorbymodule:ClassNamepath; scope it withMONOCLE_OBFUSCATE_SPAN_TYPES. See docs/monocle_span_obfuscation.md
- fix(exporters): span obfuscation no longer swallows the sentence punctuation after an unquoted credential value —
- v0.8.13Version 0.8.132026-08-20 · 2026-08-20 03:45 UTC
查看更新说明
This is a patch release on the previous 0.8.12 release, fixing the issue(s) below.
- feat(test_tools):
check_eval'seval_nameaccepts either a built-in eval template name or the path of a custom eval template JSON file (apathlib.Pathor a path-like string), instead of the caller having to switch to thetemplate_pathparameter for custom templates. Which kind it is is detected from the value, using the evaluator's existing built-in vs. custom rule (BaseEval.classify_eval_input) (#791) - fix!: an agent deployed to AWS Bedrock AgentCore now authorizes each caller before returning its spans, the same gate every HTTP framework applies — the deployment declares a key in
MONOCLE_TRACE_RETRIEVAL_DEFAULT_KEY(or a callback inMONOCLE_TRACE_RETRIEVAL_CALLBACK), and theagentcorerunner presentsMONOCLE_TRACE_RETRIEVAL_KEYon the invocation. PreviouslyMONOCLE_ENABLE_TRACE_RETURNalone returned spans to every caller. Migration: deployments using trace return must setMONOCLE_TRACE_RETRIEVAL_DEFAULT_KEYand tests must setMONOCLE_TRACE_RETRIEVAL_KEYto match, or no spans come back (#793) - feat(test_tools): the test generator automatically discovers the evals already configured for an agent and adds matching
check_evalassertions to the generated tests, resolving the evaluator through the eval registry (BaseEval) instead of importing Okahu directly; custom eval templates are supported and the eval trace search is no longer capped at 90 days (#777) - fix(instrumentation): health check spans that answer with a response body (
{"status":"ok"},OK, ...) are recognized as health checks and sampled down to one span per reset counter, instead of being exported as real traffic. Recognition is by route (/health,/healthz,/livez,/readyz,/pingand friends, including any path ending in one of them such as/actuator/health), replaceable viaMONOCLE_HEALTH_CHECK_ROUTES; request params or a request body still force an export. Failing health checks are also always exported now onfastapi,flask,aiohttpandazfunc, whose metamodels reportstatus_coderather than theerror_codethe check previously read (#792)
- feat(test_tools):
- v0.8.12Version 0.8.122026-08-17 · 2026-08-17 19:46 UTC
查看更新说明
This is a patch release on the previous 0.8.11 release, fixing the issue(s) below.
- feat(exporters): add ClickHouse span exporter (
MONOCLE_EXPORTER=clickhouse), configured viaMONOCLE_CLICKHOUSE_CONNECTION_URL; install with theclickhouseextra - feat(exporters): configurable file-name prefix for file and Azure Blob exporters via
MONOCLE_FILE_PREFIXandMONOCLE_BLOB_FILE_PREFIX; S3MONOCLE_S3_KEY_PREFIXrenamed toMONOCLE_S3_FILE_PREFIX(old name still works with deprecation warning) (#149) - chore(deps): add
opentelemetry-exporter-otlp-proto-httpas a default dependency so the OTLP exporter works out of the box (#570) - feat(exporters): add
MONOCLE_CONSOLEenv var to enable console output alongside any configured exporter (#577) - fix(test_tools): lazy-load
SentenceTransformerto prevent crash at pytest collection time in network-restricted environments (#576) - feat(test_tools): add
agentcorerunner to invoke an agent deployed to AWS Bedrock AgentCore Runtime remotely via boto3invoke_agent_runtime, with session-based retrieval of the deployed agent's spans from Okahu - feat(test_tools): runners can identify their remote spans by a fact other than the trace id via
AgentRunner.get_remote_trace_query(); theagentcorerunner uses it to correlate the deployed agent's spans by the AgentCore session, so existing assertions apply to them - feat: an agent deployed to AWS Bedrock AgentCore returns its spans in the invocation response when
MONOCLE_ENABLE_TRACE_RETURNis set, and theagentcorerunner strips them off before the caller sees the response — no trace backend needed. Falls back to session-based retrieval when the deployed agent does not return them - feat(instrumentation): custom spans can omit the traced method's inputs and/or outputs via
@monocle_trace_method(exclude="inputs")or anexclude: [inputs, outputs]key in aninstrumentconfig entry, so methods handling credentials, PII or payment details can be traced without capturing that data — excluded accessors are left out of the processor, so the values are never serialized. An excluded-output span still recordserror_code, and an unrecognized exclusion name warns instead of raising (#784) - feat(test_tools): assertions can be scoped to a single turn of a multi-turn run, and
check_evalnow reports every failing fact with a per-fact breakdown instead of raising on the first one (#775) - fix(test_tools):
run_agent_asyncauto-numbers turns per session ("1", "2", ...) whenturn_idis unset, matching the documented default that previously applied only to the multi-turn runner; the resolved turn id is also persisted back onto the turn (#780) - chore(deps): bump
GitPythonto 3.1.58 inmonocle_test_tools(#776) - feat(test_tools): the eval-result matrix row is now template-agnostic —
judge_outputcarries the judge's structured output verbatim, and thehallucination-specificclaim_verdicts,hallucination_typesandentity_match_checkcolumns are removed. Previously only those three fields were promoted, so every other template'sstructure_output(e.g.addressed_aspects/missing_aspects/completeness_scoreonconversation_completeness) was dropped and downstream analysis had only the free-textexplanationto parse. Migration: readrow["judge_output"]["claim_verdicts"]instead ofrow["claim_verdicts"].
- feat(exporters): add ClickHouse span exporter (
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
How it works
At its core, Monocle is a GenAI-specific observability layer built on OpenTelemetry.
- 🧬 Metamodel — defines entities such as agents, prompts, responses, tools, and vector operations, and maps them to standardized span attributes. See the metamodel docs for details.
- 🔌 Instrumentation adapters — for GenAI frameworks automatically create spans for key operations (agent runs, tool calls, LLM invocations, retrieval queries) without you wiring them manually.
- 📤 OTLP-compatible traces — your existing collectors, backends, and dashboards just work.
Because the traces are structured and consistent, they are easy for humans, dashboards, and even SRE/QA agents to consume.
Why developers love Monocle
- 🔍 Turn black-box agents into step-by-step traces — see every model call, tool invocation, vector lookup, and intermediate state in one connected timeline.
- 🧩 Works with the GenAI stack you already use — LangChain, LlamaIndex, Haystack, Google ADK, OpenAI, Anthropic and more are supported through first-class instrumentation.
- 📡 Speaks OpenTelemetry natively — Monocle emits standard OTLP spans so you can send them to any observability backend (file, console, cloud storage, or your favorite APM).
- 🧪 Makes AI testing real, not aspirational — with
monocle-test-tools, you can assert on traces themselves — agents invoked, tools used, token costs, error states — not just input/output pairs. - 🏛️ Linux Foundation & CNCF community DNA — built and governed in the open, with contributions from the broader AI and cloud-native observability communities.
If you care about debuggability, reliability, or compliance for AI agents, Monocle is meant for you.
Who Monocle is for
- 👩💻 App developers — trace GenAI apps in any environment without decorating every function with bespoke OpenTelemetry code.
- 🏗️ Platform / infra engineers — prefer wrapping and operators over asking product teams to refactor their apps for observability.
- 🏢 Enterprises & SREs — standardized, OTel-compliant traces and CI-friendly AI tests that fit existing pipelines and dashboards.
What's in this repo
This repository contains the Python implementation of Monocle's tracing SDK and metamodel (monocle_apptrace), including:
- Core instrumentation utilities.
- A community-curated metamodel for consistent tracing of GenAI components (agents, LLM calls, tools, vector stores, etc.).
- Framework-specific adapters (e.g., LangChain, LlamaIndex, Haystack, Google ADK) so you don't have to handcraft spans.
- Export configuration for local JSON files, console, and cloud storage backends.
There is also a separate package, monocle-test-tools, which provides a testing and validation framework for AI agent tracing, built on top of pytest.
Quick Start
1. Install
pip install monocle_apptrace
2. Initialize telemetry once
from monocle_apptrace import setup_monocle_telemetry
setup_monocle_telemetry(workflow_name="simple_math_app")
This wires up OpenTelemetry, configures the Monocle metamodel, and auto-instruments supported frameworks without requiring you to manually create spans.
3. Run your app and inspect traces
By default, Monocle exports traces as JSON files under a local ./monocle directory:
monocle_trace_{workflow_name}_{trace_id}_{timestamp}.json
Each file contains an array of OpenTelemetry spans capturing agent runs, tool calls, and LLM interactions. Load them into any OTLP-compatible backend, or use the Okahu VS Code extension for a rich Gantt-style timeline visualization.
Use a scope to attach attributes like user_id, session_id, or tenant_id to every span created inside a block. Great for filtering traces by tenant or correlating a multi-step flow.
from monocle_apptrace.instrumentation.common.instrumentor import (
monocle_trace_scope,
monocle_trace_scope_method,
)
# Context manager — scope applies to every span inside the with-block
with monocle_trace_scope("user_id", "user-123"):
result = my_agent.run("What's the weather in London?")
# Decorator — scope applies to every call of the function
@monocle_trace_scope_method("tenant_id", "acme-corp")
def handle_request(payload):
...
Async equivalents (amonocle_trace_scope) and full reference: Scope API docs.
Span payloads are scrubbed inside your process before export, on by default — API keys, passwords, tokens and private keys are redacted, and an inline image becomes <IMAGE:image/png,1.4MB> instead of megabytes of base64.
Add your own secrets without writing any code:
# redact these variables' values wherever they appear in a span
export MONOCLE_OBFUSCATE_ENV_VALUES=OKAHU_API_KEY,DB_PASSWORD
# add regexes for shapes whose value you don't hold
export MONOCLE_OBFUSCATE_EXTRA_PATTERNS='{"corp_token": "CORP-[0-9]{6}"}'
MONOCLE_OBFUSCATE_ENV_VALUES is the stronger of the two: your app already holds its own secrets, so no regex has to describe them and they are caught wherever they land — including as a positional argument, where nothing names them. Bad configuration (a missing variable, a value under 8 characters, invalid JSON, a regex that does not compile) is skipped with a warning rather than failing startup.
Both apply to obfuscators built from the environment. Passing span_obfuscators=[...] to setup_monocle_telemetry replaces that configuration entirely, so pass them along to keep them:
from monocle_apptrace.exporters import RegexSpanObfuscator, extra_patterns_from_env
setup_monocle_telemetry(
workflow_name="my-agent",
span_obfuscators=[RegexSpanObfuscator(extra_patterns=extra_patterns_from_env())],
)
Full reference: obfuscating sensitive data.
Testing AI agents with monocle-test-tools
monocle-test-tools is the companion test framework that lets you write pytest-style tests that assert on traces, not just return values.
What you can validate
| Capability | Description |
|---|---|
| Agentic response | Did the agent produce the right kind of answer for a given input? |
| Agent invocation | Did the correct agent or sub-agent run, and delegate the right tasks? |
| Tool behavior | Were the intended tools called, with the expected parameters and outputs? |
| Inference quality & cost | Did responses match your schemas or rubrics, and stay within token/cost budgets? |
| E2E evaluations in CI/CD | Run eval-style tests as part of your pipeline using the same traces that power observability. |
Install
pip install monocle_test_tools
from monocle_test_tools import expected
def test_weather_agent():
result = expected(
input="What is the weather in London?",
expected_output="weather report for London"
)
result.called_agent("weather_agent")
result.called_tool("get_weather", agent_name="weather_agent")
result.under_token_limit(5000)
result.under_duration(10)
Pass a session_id so multiple turns roll up into one session, then evaluate at the agentic_sessions fact (role adherence, knowledge retention, conversation completeness across turns).
import pytest
from monocle_test_tools import MonocleValidator, TestCase
agent_test_cases = [
{"test_input": ["Book a flight from SFO to Mumbai on 26 Nov."]},
{"test_input": ["Now book a hotel near the airport for 4 nights."]},
]
@MonocleValidator().monocle_testcase(agent_test_cases)
async def test_multi_turn_session(test_case: TestCase):
# Same session_id ties both turns to the same agentic session
await MonocleValidator().test_agent_async(
root_agent, "strands", test_case, session_id="travel_session_1"
)
@pytest.mark.asyncio
async def test_session_quality(monocle_trace_asserter):
# After the two turns above, evaluate the session as a whole
monocle_trace_asserter.with_evaluation("okahu") \
.check_eval(fact_name="agentic_sessions", eval_name="role_adherence",
expected=["excellent_adherence", "good_adherence"]) \
.check_eval(fact_name="agentic_sessions", eval_name="knowledge_retention",
expected=["excellent_retention", "good_retention"]) \
.check_eval(fact_name="agentic_sessions", eval_name="correctness",
expected="correct")
See the full test assertions reference and test tools README for detailed usage.
Zero- and low-code tracing modes
Monocle supports both in-app initialization and wrapper-style execution so you can choose how invasive you want tracing to be.
- 🟢 In-code setup — call
setup_monocle_telemetry()once at startup and let Monocle auto-instrument supported frameworks. - 🟢 Wrapper / operator mode — use CLI-like entrypoints (e.g., running your script with a
monocle_apptracemodule) to trace apps without modifying the code, making it suitable for Lambda layers and platform-level integration.
This flexibility is especially useful when platform teams want to inject tracing without touching product code, or when you ship multi-tenant AI platforms.
Monocle can trace the major AI coding assistants. Install once, then register hooks for the CLIs you use:
# Install the Monocle package
uv tool install monocle_apptrace
# Register hooks for whichever assistants you use
monocle-apptrace claude-setup # Claude Code
monocle-apptrace codex-setup # OpenAI Codex CLI
monocle-apptrace copilot-setup # GitHub Copilot (CLI + VS Code Chat)
Each *-setup is interactive and asks two things:
-
Where to install — two options:
- Global (default) — hooks installed under your home directory (
~/.claude/,~/.codex/,~/.copilot/); applies to every session on the machine. - This project — hooks installed under the current repo (
.claude/,.codex/,.github/hooks/); only sessions started inside that project are traced. Useful for trying Monocle on one repo without affecting others.
You can also skip the prompt with
--globalor--project:monocle-apptrace claude-setup --project - Global (default) — hooks installed under your home directory (
-
How to authenticate — local storage or Okahu cloud:
- Sign in — opens a browser to sign in via GitHub (through Auth0); mints an Okahu API key so traces export to Okahu cloud in addition to local files.
- Paste an API key — if you already have one from the Okahu portal.
- Skip — local-file export only; inspect traces with the Okahu VS Code extension.
Start a new session — traces flow automatically to whatever exporter you've configured (file, console, or cloud), giving you full visibility into how these assistants interact with your codebase.
Supported frameworks and providers
| Category | Supported |
|---|---|
| Language | 🟢 Python · 🟢 Typescript |
| Agentic frameworks | 🟢 Langgraph · 🟢 LlamaIndex · 🟢 Google ADK · 🟢 OpenAI Agent SDK · 🟢 AWS Strands · 🟢 CrewAI · 🟢 Microsoft Agent Framework |
| MCP / A2A | 🟢 FastMCP · 🟢 MCP client · 🟢 A2A client |
| Web / App | 🟢 Flask · 🟢 AIO Http · 🟢 FastAPI · 🟢 Azure Function · 🟢 AWS Lambda · 🟢 Vercel (TS) · 🟢 Microsoft Teams AI SDK · 🟢 Web/REST client · 🔜 Google Function |
| LLM frameworks | 🟢 Langchain · 🟢 Llamaindex · 🟢 Haystack |
| Agent Runtime | 🟢 AWS Bedrock Agentcore · 🟢 Azure AI Foundry |
| LLM inference | 🟢 OpenAI · 🟢 Azure OpenAI · 🟢 Azure AI · 🟢 Azure AI Foundry · 🟢 Nvidia Triton · 🟢 AWS Bedrock · 🟢 AWS Sagemaker · 🟢 Google Vertex · 🟢 Google Gemini · 🟢 Hugging Face · 🟢 Deepseek · 🟢 Anthropic · 🟢 Mistral · 🟢 LiteLLM · 🔜 Azure ML |
| AI coding assistants | 🟢 Claude CLI · 🟢 OpenAI Codex CLI · 🟢 GitHub Copilot (CLI + VS Code Chat) |
| Vector stores | 🟢 FAISS · 🔜 OpenSearch · 🔜 Milvus |
| Exporters | 🟢 stdout · 🟢 file · 🟢 Memory · 🟢 Azure Blob Storage · 🟢 AWS S3 · 🟢 Okahu cloud · 🟢 OTEL collectors · 🟢 Google Cloud Storage · 🟢 PostgreSQL · 🟢 ClickHouse · 🟢 Paygentic |
IDEs, ADK, and ecosystem integrations
Monocle is designed to play nicely with the tools you already use.
VS Code extension
The Okahu Trace Visualizer extension reads Monocle JSON trace files and displays them in an interactive UI with timelines, JSON viewers, token counts, and error badges.
Google Agent Development Kit (ADK)
A dedicated integration automatically instruments ADK agents, tools, and runners after you call setup_monocle_telemetry, emitting spans for agent runs, tool calls, and LLM interactions. See the Google ADK docs for setup instructions.
Okahu cloud observability
Okahu uses Monocle traces as a primary signal source for debugging, evaluation, and SRE-style monitoring of agentic applications.
These integrations make it easy to go from local debug → CI/CD testing → production observability without switching tracing models.
Docs, examples, and learning resources
| Resource | Description |
|---|---|
| User Guide | Installation, configuration, and how traces are structured |
| Trace API | monocle_trace / amonocle_trace and low-level start_trace / stop_trace |
| Scope API | monocle_trace_scope helpers to attach scopes across spans |
| Test Assertions | Complete reference for all fluent API assertions in monocle-test-tools |
| Test Tools | Getting started with monocle-test-tools, conftest.py setup and examples |
| Evaluation API | LLM-based evaluation integration for test assertions |
| Contributing | Technical details for contributing to the project |
| Examples | Sample apps demonstrating Monocle with various frameworks |
Roadmap
Monocle's long-term goal is to support tracing and testing for GenAI apps built in any language, with any orchestration or agent framework, on any LLM or vector backend.
- First-class support for more languages (TypeScript and beyond).
- Deeper adapters for additional LLM hosting services and vector databases.
- Richer test assertions and evaluation hooks in
monocle-test-toolsfor complex, policy-driven AI systems.
You can track progress and proposals via the LF AI & Data Monocle project page and GitHub discussions.
Contributing & community
Monocle is a community-based open source project under the Apache 2.0 license.
- File bugs and feature requests via GitHub Issues.
- Open PRs for new framework integrations, exporters, or metamodel improvements.
- Join discussions on Discord or Slack.
Please see CONTRIBUTING, CODE_OF_CONDUCT, and SECURITY for detailed guidelines.