Model or dataset
Arize-ai/openinference avatar
Arize-ai/openinference

openinference ships its spec as markdown and versions every package alone

OpenTelemetry Instrumentation for AI Observability

1,247 stars339 forksPythonApache-2.0

At a glance

What is it?
A tracing convention set and a family of instrumentation plugins for AI applications, described as complementary to OpenTelemetry rather than a replacement. The repository holds four language directories while its build file wires two, two of the last three releases are different versions of the same package published sixteen hours apart, and the lint tool is pinned to one version invoked through a package runner.
Who is it for?
openinference is worth adopting if you want AI trace semantics that your existing OpenTelemetry pipeline will carry, rather than a second telemetry stack.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The specification is a directory of markdown files

The specification is not a schema file and not a wire format. It is edited as markdown files in a directory called `spec`, and that directory sits at the repository root next to the language directories.

The page is explicit about what the conventions are for: they are designed to provide insight into the invocation of a language model and the surrounding application context, with two examples named, retrieval from vector stores and the usage of external tools such as search engines or APIs.

The transport and file format line is the important one. The specification is agnostic to both, and is intended to be used in conjunction with other specifications, with three named, JSON, Protocol Buffers and data frames.

That is the design decision that makes it portable and the one that makes adoption a matter of convention rather than of infrastructure. A vendor's collector receives ordinary OpenTelemetry spans; what changes is the names and attributes on those spans. The cost of that choice is that nothing enforces it, so two applications emitting the same operation can produce different attribute sets and still both be conformant, and conformance is a reading exercise rather than a validation step.

The markdown directory is also the governance surface. Because the conventions live as prose files in the same repository as the code that emits them, a change to a convention and a change to an instrumentation package are the same pull request, which is the argument for the layout even though it means the specification has no separate release.

Four documentation roots sit at the repository root: this one, an internal documentation directory, and the two language trees.

Every package carries its own version line

The three most recent releases are three different artifacts, and two of them are the same artifact.

A semantic conventions package at one patch version was published on 2026-10-01 in the evening, a semantic conventions package one patch lower was published the same morning, and a vertex instrumentation package at its own patch version was published later that night.

So the conventions package released twice in about sixteen hours, and the vertex instrumentation on the same day, at a different number entirely.

That is the signature of a monorepo with independent per-package versioning rather than a lockstep release. The tag names carry the package name and the version as two separate components, which is what release automation does when it publishes one tag per package, and a manifest file plus a configuration file at the repository root drive it.

The practical consequence for a consumer is that there is no single version to pin. Depending on the semantics package and the instrumentation package for your framework means depending on two version lines that were published separately and may have been tested against different convention revisions. The page offers no compatibility matrix and no statement about which convention version each instrumentation targets.

The Python library table reinforces the shape. It lists a conventions package and a reusable instrumentation package with no framework of its own, and then one package per integration, and every row's version column is a badge pointing at a link on the package index.

Four language directories, two build targets

The repository root holds four language directories: Python, JavaScript, Java and Go.

The build file wires two of them. It declares a Python directory and a JavaScript directory as variables, and every recipe it defines operates on one of those two.

So the Java and Go trees have no make target, no format target, no lint target and no type check in the unified build. The page describes the instrumentations as being available in a variety of languages, and the visible library table shows only Python, with the last row cut off mid-description.

The repository is reported as Python first, which matches the table and the build file, and the two other directories are simply outside what the build covers. Whether they are maintained to the same standard is not something the page says.

The JavaScript half is the one with the most build machinery, and its configuration is explained in the file. A shell fragment sources the version manager, changes into the JavaScript directory and switches to the Node version pinned in that directory, falling back to the system Node if the version manager is not installed. Above it is a comment explaining why it has to be repeated: each recipe runs in its own subshell, so the environment does not carry between targets.

That is the kind of note that saves an afternoon, and it is the clearest sign in this file that the build was grown rather than designed.

The maintainer's own products are the first class backends

The relationship to OpenTelemetry is stated in one sentence and it is careful: OpenInference is a set of conventions and plugins that is complementary to OpenTelemetry, to enable tracing of AI applications.

The next sentence names the backends. It is natively supported by two products from the maintaining organisation, one open source and one commercial, and then it says it can be used with any OpenTelemetry-compatible backend as well.

The word natively is doing the work. For the maintainer's own products, these conventions are the supported path, which means the conventions were shaped with those collectors in mind and the attribute names will read well in them. For everything else, the same spans travel over the standard protocol, and whether your backend renders them usefully is a mapping exercise.

That is a normal and not unreasonable arrangement for a vendor to publish an open standard, and it is worth naming plainly because it affects where you look when a span is hard to interpret: the maintainer's own documentation is the reference implementation, and the markdown directory is the source of truth.

The badges at the top of the page point at the specification documentation and a chat channel, both hosted by the maintaining organisation, and neither link points at the OpenTelemetry specification itself.

Ten of the visible integrations are frameworks, four are providers

The Python library table is two base packages plus a long list of integrations, and the list is cut off partway through the last visible row.

The two base packages are the semantic conventions and a reusable instrumentation package described as utilities, decorators, configurations and helpers for instrumentation. That second one is the extension point: it is the only piece a user needs if their framework is not on the list.

The visible integrations divide cleanly. Four are named after model providers: one for a hosted provider SDK, one for a cloud provider's managed service, one for a European model provider, and one for a cloud platform's model service.

Ten are named after frameworks, agent runtimes and tooling: two agent frameworks, a hosted agent SDK, an agent SDK, a data framework, a prompt and program optimisation framework, a chain framework, the Model Context Protocol, a gateway, and a guardrails library.

So the coverage is weighted toward the orchestration layer rather than the inference layer, which is the opposite of what the specification's framing suggests, since the spec is about model invocation and retrieval. It is also the more useful direction, because a framework integration is where the convention actually has to be written, and a provider SDK integration is mostly a matter of which client method is being called.

The Model Context Protocol entry is the one to note. Instrumenting the protocol rather than a vendor's client means an agent's tool calls and retrievals get span names and attributes whether they went through a framework, a gateway or something written from scratch.

Three agreement files, two agent files, one lockfile for skills

The root listing shows the governance files of a project that has grown across several tools, and the naming is inconsistent in a way that is easy to see once you line the entries up.

There is a licence file, a code of conduct with a markdown extension, and then two contribution and security files with no extension at all.

There are four directories for coding agents at the root, for four different tools, and four instruction files beside them. Two of those four filenames appear to be the same document under two names, one with the full name and one with a shorter form, which is the kind of duplication that survives because each tool looks for its own.

There is a lockfile for skills at the root, sitting next to the agent directories, which is the first time in this set of projects that a skills lockfile has appeared in a package manifest rather than a tool's own configuration.

Two other entries explain themselves once you know what they are for. A spell-checker dictionary sits at the root, which a repository whose table contains a dozen product names spelled inconsistently almost certainly needs. And a YAML site configuration file, named with a leading low dash, is there to build the documentation pages from the same markdown that holds the specification.

There is no changelog at the root. With per-package automated releases, the expectation is a changelog per package inside each language tree rather than one for the project.

The linter is one pinned version reached through a package runner

The build file's tool section is four lines and every one of them is a choice.

The linter is not invoked from the environment. It is run through the Python package runner at an exact version, and the version is written as a variable so it appears once.

So a lint run downloads that specific linter version if it is not already present, which means every developer and every continuous integration job gets the same linter without a shared tool environment and without a virtualenv entry.

The test runner is handled the same way, with the runner and one plugin fetched together at invocation time.

The JavaScript side is not fetched at all. It uses the package manager found on the machine, and the node version comes from a version file inside the JavaScript directory, which is why the shell fragment that switches versions has to be repeated in every recipe.

There is a target that verifies the required tools are present before anything else runs, and the install targets are described in their own help text, which is unusually specific. The Python install is described as installing dependencies, adding symlinks and performing an editable install. Three steps, one of which is a symlink farm that no other project in this set has needed, and it is worth knowing about before you run it, because it means the local source tree is deliberately spliced into the environment.

The JavaScript install names its version floors in the same help line, requiring one of two specific releases rather than a range.

Editorial conclusion

openinference is worth adopting if you want AI trace semantics that your existing OpenTelemetry pipeline will carry, rather than a second telemetry stack. The framing on the page is explicitly complementary, the specification is transport and file format agnostic and is meant to compose with other specifications rather than replace them, and the instrumentation packages are thin by design: one reusable package of utilities, decorators, configurations and helpers, and then one small package per integration. Nothing in that arrangement locks you to a vendor's collector.

Two things to plan for. The release cadence is per package, not per project, so the semantic conventions package is well ahead of most of the integrations, and two releases of that one package can land in the same afternoon. If you pin, you are pinning sixteen or more independent artifacts rather than one, and the page gives you no guidance on which combination is tested together. And the vendor that maintains the conventions also ships two products that support them natively, so when a convention is ambiguous the resolution path runs through a commercial backend unless you read the markdown yourself.

For an evaluator, the two questions worth asking are whether the conventions cover the retrieval and tool-use spans you actually emit, since the spec's stated scope is the model invocation plus the surrounding context including vector store retrieval and external tool calls, and whether the instrumentation for your framework is one of the listed packages or something you would have to write against the reusable utilities yourself.

Frequently asked questions

What is OpenInference?

A set of conventions and plugins complementary to OpenTelemetry that enable tracing of AI applications. The conventions cover the invocation of a language model plus surrounding context such as retrieval from vector stores and the use of external tools, and the specification is transport and file format agnostic.

What are the differences between OpenTelemetry and OpenInference?

OpenTelemetry is the tracing transport and instrumentation framework; OpenInference adds a layer of naming and attribute conventions on top for AI applications. The OpenInference specification is transport and file format agnostic and is intended to be used in conjunction with other specifications such as JSON, Protocol Buffers and data frames.

Which backends support openinference?

Two products from the maintaining organisation are natively supported, one open source and one commercial, and the conventions can be used with any OpenTelemetry-compatible backend. The badges and chat channel on the readme are hosted by the maintaining organisation and do not link to the OpenTelemetry specification itself.

How does openinference version its packages?

Each package carries its own version line. The three most recent releases are two different patch versions of the semantic conventions package published about sixteen hours apart on the same day, plus a different patch version of a vertex instrumentation package published that night.

Which languages does openinference support?

The repository holds Python, JavaScript, Java and Go directories, and the readme describes instrumentations in a variety of languages. The unified build file defines targets for Python and JavaScript only, so the Java and Go trees have no format, lint or type check target.

What if my framework is not in the openinference instrumentation list?

There is a base package described as reusable utilities, decorators, configurations and helpers for instrumentation, separate from the per-framework packages. That is the extension point for emitting the conventions yourself. The visible list also covers agent frameworks and the Model Context Protocol, so tool calls may already be instrumented higher up the stack.

Official sources

  1. Arize-ai/openinference on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/arize-ai-openinference.svg)](https://hysenlabs.com/projects/arize-ai-openinference)