-
Notifications
You must be signed in to change notification settings - Fork 36
Add LangChain invoke workflow and invoke agent span support #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
5986701
Add LangChain invoke workflow and invoke agent span support
wrisa 8db6f60
Merge branch 'main' into chains-langchain
wrisa ef5fc95
Added change log
wrisa 0fc417f
Merge branch 'chains-langchain' of github.com:wrisa/opentelemetry-pyt…
wrisa 4744437
fixed errors
wrisa c4fd6f9
updated changelog
wrisa 1d6d649
Merge branch 'main' into chains-langchain
wrisa 575fa0c
Merge branch 'main' into chains-langchain
MikeGoldsmith e8e2826
Addressed lzchen comments
wrisa d8a48f2
Merge branch 'chains-langchain' of github.com:wrisa/opentelemetry-pyt…
wrisa 1ba5ef2
updated uv
wrisa 4dea716
addressed
wrisa 255e3ef
fixed tests instrumentation-langchain-conformance
wrisa 7828ad5
Merge branch 'main' into chains-langchain
wrisa e67602d
fixed tests
wrisa 4186de7
fixed conflict
wrisa 23e3f20
fixed test
wrisa ca9a67b
fixed tests
wrisa 1b4638e
Generate updated CI workflows for langchain instrumentation
wrisa de5b081
Merge branch 'main' into chains-langchain
wrisa 638a82b
Merge branch 'chains-langchain' of github.com:wrisa/opentelemetry-pyt…
wrisa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
instrumentation/opentelemetry-instrumentation-langchain/.changelog/25.added
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add LangChain workflow and agent span support |
104 changes: 104 additions & 0 deletions
104
instrumentation/opentelemetry-instrumentation-langchain/examples/agent/main.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| # Copyright The OpenTelemetry Authors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """ | ||
| ReAct agent example built with LangGraph. | ||
|
|
||
| Uses LangGraph's prebuilt create_react_agent with simple calculator tools. | ||
| OpenTelemetry LangChain instrumentation traces the LLM calls made by the agent. | ||
| """ | ||
|
|
||
| from uuid import uuid4 | ||
|
|
||
| from langchain_core.messages import HumanMessage | ||
| from langchain_core.tools import tool | ||
| from langchain_openai import ChatOpenAI | ||
| from langgraph.prebuilt import create_react_agent | ||
|
|
||
| from opentelemetry import _logs, metrics, trace | ||
| from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( | ||
| OTLPLogExporter, | ||
| ) | ||
| from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( | ||
| OTLPMetricExporter, | ||
| ) | ||
| from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( | ||
| OTLPSpanExporter, | ||
| ) | ||
| from opentelemetry.instrumentation.langchain import LangChainInstrumentor | ||
| from opentelemetry.sdk._logs import LoggerProvider | ||
| from opentelemetry.sdk._logs.export import BatchLogRecordProcessor | ||
| from opentelemetry.sdk.metrics import MeterProvider | ||
| from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader | ||
| from opentelemetry.sdk.trace import TracerProvider | ||
| from opentelemetry.sdk.trace.export import BatchSpanProcessor | ||
|
|
||
| # Configure tracing | ||
| trace.set_tracer_provider(TracerProvider()) | ||
| span_processor = BatchSpanProcessor(OTLPSpanExporter()) | ||
| trace.get_tracer_provider().add_span_processor(span_processor) | ||
|
|
||
| # Configure logging | ||
| _logs.set_logger_provider(LoggerProvider()) | ||
| _logs.get_logger_provider().add_log_record_processor( | ||
| BatchLogRecordProcessor(OTLPLogExporter()) | ||
| ) | ||
|
|
||
| # Configure metrics | ||
| metrics.set_meter_provider( | ||
| MeterProvider( | ||
| metric_readers=[ | ||
| PeriodicExportingMetricReader( | ||
| OTLPMetricExporter(), | ||
| ), | ||
| ] | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| @tool | ||
| def multiply(a: float, b: float) -> float: | ||
| """Multiply two numbers together.""" | ||
| return a * b | ||
|
|
||
|
|
||
| @tool | ||
| def add(a: float, b: float) -> float: | ||
| """Add two numbers together.""" | ||
| return a + b | ||
|
|
||
|
|
||
| def main(): | ||
| LangChainInstrumentor().instrument() | ||
|
|
||
| llm = ChatOpenAI( | ||
| model="gpt-3.5-turbo", | ||
| temperature=0.1, | ||
| max_tokens=100, | ||
| top_p=0.9, | ||
| seed=100, | ||
| ) | ||
|
|
||
| session_id = str(uuid4()) | ||
| agent = create_react_agent(llm, tools=[multiply, add]).with_config( | ||
| { | ||
| "metadata": { | ||
| "agent_name": "coordinator", | ||
| "session_id": session_id, | ||
| }, | ||
| } | ||
| ) | ||
|
|
||
| result = agent.invoke( | ||
| {"messages": [HumanMessage(content="What is (3 * 4) + 7?")]} | ||
| ) | ||
|
|
||
| print("Agent output:") | ||
| for msg in result["messages"]: | ||
| print(f" {type(msg).__name__}: {msg.content}") | ||
|
|
||
| LangChainInstrumentor().uninstrument() | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
5 changes: 5 additions & 0 deletions
5
instrumentation/opentelemetry-instrumentation-langchain/examples/agent/requirements.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| langchain==0.3.21 | ||
| langchain_openai | ||
| langgraph | ||
| opentelemetry-sdk>=1.42.0 | ||
| opentelemetry-exporter-otlp-proto-grpc>=1.42.0 |
122 changes: 122 additions & 0 deletions
122
instrumentation/opentelemetry-instrumentation-langchain/examples/agent/single_node_agent.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # Copyright The OpenTelemetry Authors | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """ | ||
| Single-node agent example built with StateGraph. | ||
|
|
||
| A single ReAct agent answers arithmetic questions using calculator tools. | ||
| OpenTelemetry LangChain instrumentation traces all LLM calls. | ||
| """ | ||
|
|
||
| from uuid import uuid4 | ||
|
|
||
| from langchain_core.messages import HumanMessage | ||
| from langchain_core.tools import tool | ||
| from langchain_openai import ChatOpenAI | ||
| from langgraph.graph import END, START, MessagesState, StateGraph | ||
| from langgraph.prebuilt import create_react_agent | ||
|
|
||
| from opentelemetry import _logs, metrics, trace | ||
| from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( | ||
| OTLPLogExporter, | ||
| ) | ||
| from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( | ||
| OTLPMetricExporter, | ||
| ) | ||
| from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( | ||
| OTLPSpanExporter, | ||
| ) | ||
| from opentelemetry.instrumentation.langchain import LangChainInstrumentor | ||
| from opentelemetry.sdk._logs import LoggerProvider | ||
| from opentelemetry.sdk._logs.export import BatchLogRecordProcessor | ||
| from opentelemetry.sdk.metrics import MeterProvider | ||
| from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader | ||
| from opentelemetry.sdk.trace import TracerProvider | ||
| from opentelemetry.sdk.trace.export import BatchSpanProcessor | ||
|
|
||
| # Configure tracing | ||
| trace.set_tracer_provider(TracerProvider()) | ||
| trace.get_tracer_provider().add_span_processor( | ||
| BatchSpanProcessor(OTLPSpanExporter()) | ||
| ) | ||
|
|
||
| # Configure logging | ||
| _logs.set_logger_provider(LoggerProvider()) | ||
| _logs.get_logger_provider().add_log_record_processor( | ||
| BatchLogRecordProcessor(OTLPLogExporter()) | ||
| ) | ||
|
|
||
| # Configure metrics | ||
| metrics.set_meter_provider( | ||
| MeterProvider( | ||
| metric_readers=[PeriodicExportingMetricReader(OTLPMetricExporter())] | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| # --- Tools ---------------------------------------------------------------- | ||
|
|
||
|
|
||
| @tool | ||
| def multiply(a: float, b: float) -> float: | ||
| """Multiply two numbers.""" | ||
| return a * b | ||
|
|
||
|
|
||
| @tool | ||
| def add(a: float, b: float) -> float: | ||
| """Add two numbers.""" | ||
| return a + b | ||
|
|
||
|
|
||
| # --- Graph ---------------------------------------------------------------- | ||
|
|
||
|
|
||
| def build_single_node_graph(llm: ChatOpenAI): | ||
| session_id = str(uuid4()) | ||
|
|
||
| agent = create_react_agent( | ||
| llm, tools=[multiply, add], name="math_agent" | ||
| ).with_config( | ||
| { | ||
| "metadata": { | ||
| "agent_name": "math_agent", | ||
| "session_id": session_id, | ||
| }, | ||
| } | ||
| ) | ||
|
|
||
| def run_agent(state: MessagesState) -> dict: | ||
| result = agent.invoke({"messages": state["messages"]}) | ||
| return {"messages": result["messages"]} | ||
|
|
||
| builder = StateGraph(MessagesState) | ||
| builder.add_node("math_agent", run_agent) | ||
| builder.add_edge(START, "math_agent") | ||
| builder.add_edge("math_agent", END) | ||
|
|
||
| return builder.compile() | ||
|
|
||
|
|
||
| def main(): | ||
| LangChainInstrumentor().instrument() | ||
|
|
||
| llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.1, seed=100) | ||
| graph = build_single_node_graph(llm) | ||
|
|
||
| questions = [ | ||
| "What is 12 multiplied by 7?", | ||
| "What is 15 plus 27?", | ||
| ] | ||
|
|
||
| for question in questions: | ||
| print(f"\nQuestion: {question}") | ||
| result = graph.invoke({"messages": [HumanMessage(content=question)]}) | ||
| last = result["messages"][-1] | ||
| print(f" Answer: {last.content}") | ||
|
|
||
| LangChainInstrumentor().uninstrument() | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.