Metadata-Version: 2.5
Name: opentelemetry-instrumentation-genai-langchain
Version: 1.1b1
Summary: OpenTelemetry Official Langchain instrumentation
Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-genai/tree/main/instrumentation/opentelemetry-instrumentation-genai-langchain
Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-genai
Author-email: OpenTelemetry Authors <cncf-opentelemetry-contributors@lists.cncf.io>
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Dist: opentelemetry-instrumentation<1,>=0.64b0
Requires-Dist: opentelemetry-util-genai<2,>=1.1b0
Provides-Extra: instruments
Requires-Dist: langchain>=0.3.21; extra == 'instruments'
Description-Content-Type: text/x-rst

OpenTelemetry LangChain Instrumentation
=======================================

|pypi|

.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-genai-langchain.svg
   :target: https://pypi.org/project/opentelemetry-instrumentation-genai-langchain/

This library traces `LangChain <https://pypi.org/project/langchain/>`_ and
`LangGraph <https://pypi.org/project/langgraph/>`_ applications. It hooks into
LangChain's callback manager to emit spans that mirror the structure of your
application:

* **Workflow spans** for a graph or chain run — for example an invocation of a
  LangGraph ``StateGraph`` — capturing the overall input and output of the run.
* **Agent spans** for agent invocations nested inside a workflow, including the
  agent name, id, description, and conversation/session id when available.
* **Tool spans** for tool calls made during a run.

The spans nest to reflect the graph, so a single graph invocation produces a
workflow span with the agent, tool, and model calls it triggered as children.

Installation
------------

::

    pip install opentelemetry-instrumentation-genai-langchain

See the `examples <examples>`_ directory for runnable ``workflow``, ``agent``,
``tools``, and ``zero-code`` scenarios.

Usage
-----

Call ``LangChainInstrumentor().instrument()`` once during startup, then build
and invoke your graph as usual. The example below traces a simple two-node
LangGraph ``StateGraph`` (``START → researcher → summariser → END``); the
``graph.invoke(...)`` call is recorded as a workflow span with the node model
calls nested underneath.

.. code-block:: python

    from typing import Annotated, TypedDict

    from langchain_core.messages import HumanMessage, SystemMessage
    from langchain_openai import ChatOpenAI
    from langgraph.graph import END, START, StateGraph
    from langgraph.graph.message import add_messages

    from opentelemetry.instrumentation.genai.langchain import LangChainInstrumentor

    LangChainInstrumentor().instrument()

    llm = ChatOpenAI(model="<your-model>", temperature=0)


    class State(TypedDict):
        messages: Annotated[list, add_messages]
        research: str


    def researcher(state: State) -> dict:
        response = llm.invoke(
            [
                SystemMessage(content="Provide 2-3 factual sentences."),
                HumanMessage(content=state["messages"][-1].content),
            ]
        )
        return {"research": response.content, "messages": [response]}


    def summariser(state: State) -> dict:
        response = llm.invoke(
            [
                SystemMessage(content="Condense the text into one sentence."),
                HumanMessage(content=state["research"]),
            ]
        )
        return {"messages": [response]}


    builder = StateGraph(State)
    builder.add_node("researcher", researcher)
    builder.add_node("summariser", summariser)
    builder.add_edge(START, "researcher")
    builder.add_edge("researcher", "summariser")
    builder.add_edge("summariser", END)
    graph = builder.compile()

    # Recorded as a workflow span with the two node LLM calls nested underneath.
    graph.invoke(
        {
            "messages": [HumanMessage(content="What is the capital of France?")],
            "research": "",
        }
    )

Configuration
-------------

By default, prompts and completions are not captured. To capture message content, set the
environment variable ``OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`` to one of
``NO_CONTENT``, ``SPAN_ONLY``, ``EVENT_ONLY``, or ``SPAN_AND_EVENT``.

Prompts and completions can instead be uploaded to external storage via a completion hook: set
``OTEL_INSTRUMENTATION_GENAI_COMPLETION_HOOK=upload`` with
``OTEL_INSTRUMENTATION_GENAI_UPLOAD_BASE_PATH`` (install the ``upload`` extra:
``pip install opentelemetry-util-genai[upload]``), or pass a custom ``CompletionHook``
programmatically, which takes precedence over the environment variable::

    LangChainInstrumentor().instrument(completion_hook=my_hook)

References
----------

* `OpenTelemetry Project <https://opentelemetry.io/>`_
* `LangGraph <https://langchain-ai.github.io/langgraph/>`_
* `OpenTelemetry Python Examples <https://github.com/open-telemetry/opentelemetry-python/tree/main/docs/examples>`_
