> ## Documentation Index
> Fetch the complete documentation index at: https://arize-ax.mintlify.site/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Anthropic

> Trace Anthropic Python, Node.js, and Go SDK calls with OpenInference and send spans to Arize AX for LLM observability.

[Anthropic](https://www.anthropic.com/) provides the Claude family of large language models. Arize AX captures every Anthropic SDK call — prompts, responses, tool calls, and token usage — via the OpenInference instrumentors for [Python](https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-anthropic), [JavaScript / TypeScript](https://github.com/Arize-ai/openinference/tree/main/js/packages/openinference-instrumentation-anthropic), and [Go](https://github.com/Arize-ai/openinference/tree/main/go/openinference-instrumentation-anthropic-sdk-go), so you can debug, evaluate, and monitor Claude-powered applications.

## Prerequisites

* Python 3.10+, Node.js 18+, or Go 1.25+
* An Arize AX account ([sign up](https://arize.com/sign-up/))
* An `ANTHROPIC_API_KEY` from the [Anthropic Console](https://console.anthropic.com/)

## Launch Arize AX

1. Sign in to your [Arize AX account](https://app.arize.com/).
2. From **Space Settings**, copy your **Space ID** and **API Key**. You will set them as `ARIZE_SPACE_ID` and `ARIZE_API_KEY` below.

## Install

<CodeGroup>
  ```bash Python theme={null}
  pip install arize-otel openinference-instrumentation-anthropic anthropic
  ```

  ```bash TypeScript theme={null}
  npm install @anthropic-ai/sdk \
    @arizeai/openinference-instrumentation-anthropic \
    @arizeai/openinference-semantic-conventions \
    @opentelemetry/api \
    @opentelemetry/exporter-trace-otlp-proto \
    @opentelemetry/instrumentation \
    @opentelemetry/resources \
    @opentelemetry/sdk-trace-base \
    @opentelemetry/sdk-trace-node \
    @opentelemetry/semantic-conventions
  ```

  ```bash Go theme={null}
  go get \
    github.com/Arize-ai/arize-otel-go \
    github.com/Arize-ai/openinference/go/openinference-instrumentation-anthropic-sdk-go \
    github.com/anthropics/anthropic-sdk-go
  ```
</CodeGroup>

## Configure credentials

```bash theme={null}
export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_PROJECT_NAME="anthropic-tracing-example"
export ANTHROPIC_API_KEY="<your-anthropic-api-key>"
```

## Setup tracing

<CodeGroup>
  ```python Python theme={null}
  # instrumentation.py
  import os

  from arize.otel import register
  from openinference.instrumentation.anthropic import AnthropicInstrumentor

  tracer_provider = register(
      space_id=os.environ["ARIZE_SPACE_ID"],
      api_key=os.environ["ARIZE_API_KEY"],
      project_name=os.environ["ARIZE_PROJECT_NAME"],
  )

  AnthropicInstrumentor().instrument(tracer_provider=tracer_provider)
  print("Arize AX tracing initialized for Anthropic.")
  ```

  ```typescript TypeScript theme={null}
  // instrumentation.ts
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
  import { resourceFromAttributes } from "@opentelemetry/resources";
  import { SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
  import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
  import {
    SEMRESATTRS_PROJECT_NAME,
  } from "@arizeai/openinference-semantic-conventions";
  import { registerInstrumentations } from "@opentelemetry/instrumentation";
  import {
    AnthropicInstrumentation,
  } from "@arizeai/openinference-instrumentation-anthropic";
  import Anthropic from "@anthropic-ai/sdk";

  const projectName =
    process.env.ARIZE_PROJECT_NAME ?? "anthropic-tracing-example";

  export const provider = new NodeTracerProvider({
    resource: resourceFromAttributes({
      [ATTR_SERVICE_NAME]: projectName,
      [SEMRESATTRS_PROJECT_NAME]: projectName,
    }),
    spanProcessors: [
      new SimpleSpanProcessor(
        new OTLPTraceExporter({
          url: "https://otlp.arize.com/v1/traces",
          headers: {
            "arize-space-id": process.env.ARIZE_SPACE_ID ?? "",
            "arize-api-key": process.env.ARIZE_API_KEY ?? "",
          },
        }),
      ),
    ],
  });

  provider.register();

  const instrumentation = new AnthropicInstrumentation();
  instrumentation.manuallyInstrument(Anthropic);

  registerInstrumentations({ instrumentations: [instrumentation] });

  console.log("Arize AX tracing initialized for Anthropic.");
  ```

  ```go Go theme={null}
  // main.go
  //
  // Go integrations live in a single file — the tracer setup, the
  // instrumented middleware, and the messages call all sit inside main().
  // The `Run Anthropic` step below is just `go run main.go`.
  package main

  import (
      "context"
      "fmt"
      "log"
      "os"
      "time"

      arizeotel "github.com/Arize-ai/arize-otel-go"
      anthropicotel "github.com/Arize-ai/openinference/go/openinference-instrumentation-anthropic-sdk-go"
      "github.com/anthropics/anthropic-sdk-go"
      "github.com/anthropics/anthropic-sdk-go/option"
      "go.opentelemetry.io/otel"
  )

  func main() {
      ctx := context.Background()

      projectName := os.Getenv("ARIZE_PROJECT_NAME")
      if projectName == "" {
          projectName = "anthropic-tracing-example"
      }

      // Register reads ARIZE_SPACE_ID / ARIZE_API_KEY from the environment.
      tp, err := arizeotel.Register(ctx, arizeotel.Options{
          ProjectName: projectName,
      })
      if err != nil {
          log.Printf("register tracer: %v", err)
          return
      }
      defer func() {
          shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
          defer cancel()
          _ = tp.Shutdown(shutdownCtx)
      }()

      fmt.Println("Arize AX tracing initialized for Anthropic.")

      // The middleware wraps every /v1/messages request in an
      // LLM-kind span. The SDK reads ANTHROPIC_API_KEY from the environment.
      client := anthropic.NewClient(
          option.WithMiddleware(anthropicotel.Middleware(otel.Tracer(projectName))),
      )

      resp, err := client.Messages.New(ctx, anthropic.MessageNewParams{
          Model:     "claude-sonnet-4-6",
          MaxTokens: 256,
          Messages: []anthropic.MessageParam{
              anthropic.NewUserMessage(anthropic.NewTextBlock(
                  "Why is the ocean salty? Answer in two sentences.",
              )),
          },
      })
      if err != nil {
          log.Printf("anthropic: %v", err)
          return
      }

      for _, block := range resp.Content {
          fmt.Println(block.Text)
      }
  }
  ```
</CodeGroup>

<Note>
  **Go SDK** Only `/v1/messages` is instrumented today. Streaming responses pass through unchanged, but `output.value` and token counts are not populated for streaming spans yet. `tool_use` content blocks in messages are not yet captured as `message.tool_calls` attributes — wrap your tool execution in manual TOOL spans, see [Manual instrumentation](/docs/ax/instrument/manual-instrumentation).
</Note>

## Run Anthropic

<CodeGroup>
  ```python Python theme={null}
  # example.py

  # Importing instrumentation first ensures tracing is set up
  # before `anthropic` is imported.
  from instrumentation import tracer_provider

  import anthropic

  # The client reads ANTHROPIC_API_KEY from the environment.
  client = anthropic.Anthropic()

  message = client.messages.create(
      model="claude-sonnet-4-6",
      max_tokens=256,
      messages=[
          {
              "role": "user",
              "content": "Why is the ocean salty? Answer in two sentences.",
          },
      ],
  )

  print(message.content[0].text)
  ```

  ```typescript TypeScript theme={null}
  // example.ts

  // Importing instrumentation first ensures tracing is set up
  // before the Anthropic client is used.
  import { provider } from "./instrumentation";
  import Anthropic from "@anthropic-ai/sdk";

  // The client reads ANTHROPIC_API_KEY from the environment.
  const client = new Anthropic();

  const message = await client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 256,
    messages: [
      {
        role: "user",
        content: "Why is the ocean salty? Answer in two sentences.",
      },
    ],
  });

  const block = message.content[0];
  if (block.type === "text") {
    console.log(block.text);
  }

  // Flush any pending spans before the process exits.
  await provider.forceFlush();
  ```

  ```bash Go theme={null}
  # The full example lives in main.go above.
  go run main.go
  ```
</CodeGroup>

### Expected output

```text wrap theme={null}
Arize AX tracing initialized for Anthropic.
The ocean is salty because rivers continuously dissolve mineral salts from rocks and soil and carry them to the sea, where they accumulate over millions of years. Water leaves the ocean through evaporation but the salts remain, steadily concentrating until reaching today's roughly 3.5% salinity.
```

## Verify in Arize AX

1. Open your Arize AX space and select project **`anthropic-tracing-example`**.
2. You should see a new trace within \~30 seconds containing an LLM span — `messages.create` for the Python SDK, `Anthropic Messages` for the Node.js SDK, or `anthropic.messages.create` for the Go SDK — with the prompt, response, and token usage attached.
3. If no traces appear, see [Troubleshooting](#troubleshooting).

### Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.

<Tabs>
  <Tab title="Arize skill (agent)">
    Install the [Arize Skills](https://github.com/Arize-ai/arize-skills) plugin and let your coding agent check for you:

    ```bash theme={null}
    npx skills add Arize-ai/arize-skills
    ```

    Then prompt your agent:

    > Use the `arize-trace` skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.
  </Tab>

  <Tab title="AX CLI">
    Export recent spans for your project — any rows mean traces are landing:

    ```bash theme={null}
    ax spans export "$ARIZE_PROJECT_NAME" --space "$ARIZE_SPACE_ID" \
      --limit 5 --stdout | jq 'length'
    ```

    A non-zero count confirms spans reached Arize AX. Run `ax auth login` first if you have not authenticated. See the [`ax spans` reference](/docs/api-clients/cli/spans).
  </Tab>

  <Tab title="SDK">
    Query the project's spans and check that at least one came back.

    <CodeGroup>
      ```python Python theme={null}
      import os
      from arize import ArizeClient

      client = ArizeClient(api_key=os.environ["ARIZE_API_KEY"])
      resp = client.spans.list(
          project=os.environ["ARIZE_PROJECT_NAME"],
          space=os.environ["ARIZE_SPACE_ID"],
          limit=5,
      )
      count = len(resp.spans)
      print(
          f"{count} span(s) found" if count else "No spans yet — recheck setup"
      )
      ```

      ```typescript TypeScript theme={null}
      // Reads ARIZE_API_KEY from the environment.
      import { listSpans } from "@arizeai/ax-client";

      const { data: spans } = await listSpans({
        project: process.env.ARIZE_PROJECT_NAME!,
        space: process.env.ARIZE_SPACE_ID!,
        limit: 5,
      });
      const count = spans.length;
      console.log(
        count ? `${count} span(s) found` : "No spans yet — recheck setup",
      );
      ```

      ```go Go theme={null}
      client, err := arize.NewClient(
          arize.Config{APIKey: os.Getenv("ARIZE_API_KEY")},
      )
      if err != nil {
          log.Fatal(err)
      }
      resp, err := client.Spans.List(ctx, spans.ListRequest{
          Project: os.Getenv("ARIZE_PROJECT_NAME"),
          Space:   os.Getenv("ARIZE_SPACE_ID"),
          Limit:   5,
      })
      if err != nil {
          log.Fatal(err)
      }
      fmt.Printf("%d span(s) found\n", len(resp.Spans))
      ```
    </CodeGroup>

    SDK span references: [Python](/docs/api-clients/python/version-8/client-resources/spans) · [TypeScript](/docs/api-clients/typescript/version-1/client-resources/spans) · [Go](/docs/api-clients/go/version-2/client-resources/spans).
  </Tab>
</Tabs>

## Trace tool usage

The instrumentor traces each `messages.create` call automatically, including the tool calls Claude requests. It does not trace your application *executing* those tools, or the loop that feeds results back to the model. To capture the full agent trace, wrap the loop in a manual chain span and each tool execution in a manual tool span with the [OpenTelemetry API](/docs/ax/instrument/manual-instrumentation) — the auto LLM spans nest under your chain span automatically. See [Combine auto and manual instrumentation](/docs/ax/instrument/combining-auto-and-manual) for the pattern.

<CodeGroup>
  ```python Python theme={null}
  # tools_example.py

  # Importing instrumentation first ensures tracing is set up
  # before `anthropic` is imported.
  from instrumentation import tracer_provider

  import anthropic
  from opentelemetry import trace
  from openinference.instrumentation import OITracer, TraceConfig

  # The client reads ANTHROPIC_API_KEY from the environment.
  client = anthropic.Anthropic()
  tracer = OITracer(trace.get_tracer(__name__), config=TraceConfig())


  # A trivial tool the model can call.
  @tracer.tool
  def get_weather(city: str) -> str:
      return f"It is 72°F and sunny in {city}."


  tools = [
      {
          "name": "get_weather",
          "description": "Get the current weather for a city.",
          "input_schema": {
              "type": "object",
              "properties": {"city": {"type": "string"}},
              "required": ["city"],
          },
      },
  ]


  @tracer.chain
  def weather_agent(question: str) -> str:
      messages = [{"role": "user", "content": question}]

      # First LLM call — auto-instrumented as an LLM span.
      response = client.messages.create(
          model="claude-sonnet-4-6",
          max_tokens=256,
          tools=tools,
          messages=messages,
      )
      messages.append({"role": "assistant", "content": response.content})

      # Execute each tool call inside a manual TOOL span.
      tool_results = []
      for block in response.content:
          if block.type == "tool_use":
              result = get_weather(**block.input)
              tool_results.append({
                  "type": "tool_result",
                  "tool_use_id": block.id,
                  "content": result,
              })

      messages.append({"role": "user", "content": tool_results})

      # Second LLM call — Claude answers using the tool result.
      final = client.messages.create(
          model="claude-sonnet-4-6",
          max_tokens=256,
          messages=messages,
      )
      answer = "".join(b.text for b in final.content if b.type == "text")
      return answer


  print(weather_agent("What is the weather in San Francisco?"))
  ```

  ```typescript TypeScript theme={null}
  // tools_example.ts

  // Importing instrumentation first ensures tracing is set up
  // before the Anthropic client is used.
  import { provider } from "./instrumentation";
  import Anthropic from "@anthropic-ai/sdk";
  import { SpanStatusCode, trace } from "@opentelemetry/api";
  import {
    OpenInferenceSpanKind,
    SemanticConventions,
  } from "@arizeai/openinference-semantic-conventions";

  // The client reads ANTHROPIC_API_KEY from the environment.
  const client = new Anthropic();
  const tracer = trace.getTracer("weather-agent");

  // A trivial tool the model can call.
  async function getWeather(city: string): Promise<string> {
    await new Promise((resolve) => setTimeout(resolve, 100)); // Simulate a network call
    return `It is 72°F and sunny in ${city}.`;
  }

  const tools: Anthropic.Tool[] = [
    {
      name: "get_weather",
      description: "Get the current weather for a city.",
      input_schema: {
        type: "object",
        properties: { city: { type: "string" } },
        required: ["city"],
      },
    },
  ];

  async function runAgent(question: string): Promise<string> {
    // Manual CHAIN span wraps the whole tool loop.
    return await tracer.startActiveSpan("weather-agent", async (chainSpan) => {
      chainSpan.setAttribute(
        SemanticConventions.OPENINFERENCE_SPAN_KIND,
        OpenInferenceSpanKind.CHAIN,
      );
      chainSpan.setAttribute(SemanticConventions.INPUT_VALUE, question);

      const messages: Anthropic.MessageParam[] = [
        { role: "user", content: question },
      ];

      // First LLM call — auto-instrumented as an LLM span.
      const response = await client.messages.create({
        model: "claude-sonnet-4-6",
        max_tokens: 256,
        tools,
        messages,
      });
      messages.push({ role: "assistant", content: response.content });

      // Execute each tool call inside a manual TOOL span.
      const toolResults: Anthropic.ToolResultBlockParam[] = [];
      for (const block of response.content) {
        if (block.type === "tool_use") {
          const args = block.input as { city: string };
          const result = await tracer.startActiveSpan(
            block.name,
            async (toolSpan) => {
              toolSpan.setAttribute(
                SemanticConventions.OPENINFERENCE_SPAN_KIND,
                OpenInferenceSpanKind.TOOL,
              );
              toolSpan.setAttribute(
                SemanticConventions.INPUT_VALUE,
                JSON.stringify(block.input),
              );
              const r = await getWeather(args.city);
              toolSpan.setAttribute(SemanticConventions.OUTPUT_VALUE, r);
              toolSpan.setStatus({ code: SpanStatusCode.OK });
              toolSpan.end();
              return r;
            },
          );
          toolResults.push({
            type: "tool_result",
            tool_use_id: block.id,
            content: result,
          });
        }
      }

      messages.push({ role: "user", content: toolResults });

      // Second LLM call — Claude answers using the tool result.
      const final = await client.messages.create({
        model: "claude-sonnet-4-6",
        max_tokens: 256,
        messages,
      });
      const answer = final.content
        .filter((b): b is Anthropic.TextBlock => b.type === "text")
        .map((b) => b.text)
        .join("");
      chainSpan.setAttribute(SemanticConventions.OUTPUT_VALUE, answer);
      chainSpan.setStatus({ code: SpanStatusCode.OK });
      chainSpan.end();

      // Flush any pending spans before the process exits.
      await provider.forceFlush();
      return answer;
    });
  }

  console.log(await runAgent("What is the weather in San Francisco?"));
  ```

  ```go Go theme={null}
  // main.go
  //
  // Self-contained tool loop: tracer setup, a manual CHAIN span, and a manual
  // TOOL span around the tool execution — all in one file. Run with
  // `go run main.go`.
  package main

  import (
      "context"
      "encoding/json"
      "fmt"
      "log"
      "os"
      "time"

      arizeotel "github.com/Arize-ai/arize-otel-go"
      anthropicotel "github.com/Arize-ai/openinference/go/openinference-instrumentation-anthropic-sdk-go"
      semconv "github.com/Arize-ai/openinference/go/openinference-semantic-conventions"
      "github.com/anthropics/anthropic-sdk-go"
      "github.com/anthropics/anthropic-sdk-go/option"
      "go.opentelemetry.io/otel"
      "go.opentelemetry.io/otel/attribute"
      "go.opentelemetry.io/otel/codes"
  )

  // A trivial tool the model can call.
  func getWeather(city string) string {
      return fmt.Sprintf("It is 72°F and sunny in %s.", city)
  }

  func main() {
      ctx := context.Background()

      projectName := os.Getenv("ARIZE_PROJECT_NAME")
      if projectName == "" {
          projectName = "anthropic-tracing-example"
      }

      tp, err := arizeotel.Register(ctx, arizeotel.Options{ProjectName: projectName})
      if err != nil {
          log.Printf("register tracer: %v", err)
          return
      }
      defer func() {
          shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
          defer cancel()
          _ = tp.Shutdown(shutdownCtx)
      }()

      fmt.Println("Arize AX tracing initialized for Anthropic.")

      tracer := otel.Tracer(projectName)
      client := anthropic.NewClient(
          option.WithMiddleware(anthropicotel.Middleware(tracer)),
      )

      tools := []anthropic.ToolUnionParam{
          {
              OfTool: &anthropic.ToolParam{
                  Name:        "get_weather",
                  Description: anthropic.String("Get the current weather for a city."),
                  InputSchema: anthropic.ToolInputSchemaParam{
                      Properties: map[string]any{
                          "city": map[string]any{"type": "string"},
                      },
                      Required: []string{"city"},
                  },
              },
          },
      }

      question := "What is the weather in San Francisco?"

      // Manual CHAIN span wraps the whole tool loop. Threading this ctx into the
      // client calls nests the auto LLM spans under it.
      ctx, chainSpan := tracer.Start(ctx, "weather-agent")
      chainSpan.SetAttributes(
          attribute.String(semconv.OpenInferenceSpanKind, semconv.SpanKindChain),
          attribute.String(semconv.InputValue, question),
      )

      messages := []anthropic.MessageParam{
          anthropic.NewUserMessage(anthropic.NewTextBlock(question)),
      }

      // First LLM call — auto-instrumented as an LLM span.
      resp, err := client.Messages.New(ctx, anthropic.MessageNewParams{
          Model:     "claude-sonnet-4-6",
          MaxTokens: 256,
          Tools:     tools,
          Messages:  messages,
      })
      if err != nil {
          log.Printf("anthropic: %v", err)
          return
      }
      messages = append(messages, resp.ToParam())

      // Execute each tool call inside a manual TOOL span.
      var toolResults []anthropic.ContentBlockParamUnion
      for _, block := range resp.Content {
          toolUse, ok := block.AsAny().(anthropic.ToolUseBlock)
          if !ok {
              continue
          }

          var input struct {
              City string `json:"city"`
          }
          _ = json.Unmarshal(toolUse.Input, &input)

          _, toolSpan := tracer.Start(ctx, toolUse.Name)
          toolSpan.SetAttributes(
              attribute.String(semconv.OpenInferenceSpanKind, semconv.SpanKindTool),
              attribute.String(semconv.InputValue, string(toolUse.Input)),
          )
          result := getWeather(input.City)
          toolSpan.SetAttributes(attribute.String(semconv.OutputValue, result))
          toolSpan.SetStatus(codes.Ok, "")
          toolSpan.End()

          toolResults = append(toolResults, anthropic.NewToolResultBlock(toolUse.ID, result, false))
      }
      messages = append(messages, anthropic.NewUserMessage(toolResults...))

      // Second LLM call — Claude answers using the tool result.
      final, err := client.Messages.New(ctx, anthropic.MessageNewParams{
          Model:     "claude-sonnet-4-6",
          MaxTokens: 256,
          Messages:  messages,
      })
      if err != nil {
          log.Printf("anthropic: %v", err)
          return
      }

      var answer string
      for _, block := range final.Content {
          answer += block.Text
      }
      chainSpan.SetAttributes(attribute.String(semconv.OutputValue, answer))
      chainSpan.SetStatus(codes.Ok, "")
      chainSpan.End()

      fmt.Println(answer)
  }
  ```
</CodeGroup>

### Expected output

```text wrap theme={null}
Arize AX tracing initialized for Anthropic.
The weather in San Francisco is currently 72°F and sunny.
```

The trace tree in Arize AX is **`weather-agent`** (chain span) → two LLM spans → one **`get_weather`** tool span.

<Note>
  **Go SDK** The auto middleware still emits an LLM span for each `Messages.New` call, but it does not populate `tool_use` blocks as attributes on that span. The chain and tool spans are created manually with the OpenTelemetry API — threading the chain span's `ctx` into each `Messages.New` call is what nests the auto LLM spans underneath it.
</Note>

## Troubleshooting

* **No traces in Arize AX.** Confirm `ARIZE_SPACE_ID` and `ARIZE_API_KEY` are set in the same shell that runs the example. Enable OpenTelemetry debug logs with `export OTEL_LOG_LEVEL=debug` and re-run.
* **Anthropic spans missing but other spans present (Python).** `AnthropicInstrumentor().instrument(...)` must run before any `import anthropic` in the application. Make sure `instrumentation.py` is the first import in your entry point.
* **`401` from Anthropic.** Verify `ANTHROPIC_API_KEY` is set and has access to the model in the example. Swap `claude-sonnet-4-6` for a model your key can call.
* **Go process exits before spans flush.** `arize-otel-go` uses a batched span processor by default. The `defer tp.Shutdown(...)` block in `main.go` is what flushes the batch — without it, short-lived programs lose their last spans. Pass `SimpleProcessor: true` to `arizeotel.Register` if you want synchronous export instead.

## Resources

<CardGroup>
  <Card icon="book-open" href="https://docs.anthropic.com/" title="Anthropic Documentation" horizontal />

  <Card icon="terminal" href="https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-anthropic" title="OpenInference Anthropic Instrumentor (Python)" horizontal />

  <Card icon="terminal" href="https://github.com/Arize-ai/openinference/tree/main/js/packages/openinference-instrumentation-anthropic" title="OpenInference Anthropic Instrumentor (JavaScript / TypeScript)" horizontal />

  <Card icon="github" href="https://github.com/Arize-ai/openinference/blob/main/python/instrumentation/openinference-instrumentation-anthropic/examples/messages_create.py" title="Anthropic Tracing Example (messages.create)" horizontal />

  <Card icon="github" href="https://github.com/Arize-ai/openinference/blob/main/python/instrumentation/openinference-instrumentation-anthropic/examples/multiple_tool_calling.py" title="Anthropic Tracing Example (tool calling)" horizontal />

  <Card icon="github" href="https://github.com/anthropics/anthropic-sdk-go" title="Anthropic Go SDK" horizontal />

  <Card icon="terminal" href="https://github.com/Arize-ai/openinference/tree/main/go/openinference-instrumentation-anthropic-sdk-go" title="OpenInference Anthropic Instrumentor (Go)" horizontal />
</CardGroup>
