Skip to content

Commit 4de0227

Browse files
author
ykriger-newrelic
authored
Add langchain including vectordb instrumentation (newrelic#21)
Add LangChain Instrumentation In this Pull Request, we have added a new callback handler, NewRelicCallbackHandler, that extends the BaseCallbackHandler from the LangChain package. This new handler integrates the New Relic monitoring service with the LangChain application to provide detailed insights and observations during the lifecycle of various processes like Language Model (LLM) start/end, Chat Model start, token generation, tool start/end, chain start/end, agent action, and agent finish. The NewRelicCallbackHandler includes methods to handle different events in the lifecycle, each associated with creating, updating, and finishing spans which help in tracing the operations in the New Relic dashboard. For example, on_llm_start method is triggered when the LLM starts running, and on_llm_end method when the LLM ends running, each creating and finishing a span respectively.
1 parent 2bb4d96 commit 4de0227

11 files changed

+1294
-32
lines changed

Diff for: .gitignore

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.DS_store
2+
.vscode/
3+
dependencies/
4+
15
# Byte-compiled / optimized / DLL files
26
__pycache__/
37
*.py[cod]
@@ -20,6 +24,7 @@ parts/
2024
sdist/
2125
var/
2226
wheels/
27+
pip-wheel-metadata/
2328
share/python-wheels/
2429
*.egg-info/
2530
.installed.cfg
@@ -83,9 +88,7 @@ profile_default/
8388
ipython_config.py
8489

8590
# pyenv
86-
# For a library or package, you might want to ignore these files since the code is
87-
# intended to run in multiple environments; otherwise, check them in:
88-
# .python-version
91+
.python-version
8992

9093
# pipenv
9194
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
@@ -148,3 +151,5 @@ poetry.lock
148151

149152
#git
150153
*.patch
154+
# poetry
155+
poetry.lock

Diff for: download-dependencies.sh

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
echo "(Re)-creating directory"
6+
rm -rf ./dependencies
7+
mkdir ./dependencies
8+
cd ./dependencies
9+
echo "Downloading dependencies"
10+
curl -sS https://d2eo22ngex1n9g.cloudfront.net/Documentation/SDK/bedrock-python-sdk.zip > sdk.zip
11+
echo "Unpacking dependencies"
12+
# (SageMaker Studio system terminals don't have `unzip` utility installed)
13+
if command -v unzip &> /dev/null
14+
then
15+
unzip sdk.zip && rm sdk.zip && echo "Done"
16+
else
17+
echo "'unzip' command not found: Trying to unzip via Python"
18+
python -m zipfile -e sdk.zip . && rm sdk.zip && echo "Done"
19+
fi

Diff for: examples/example.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import os
22

33
import openai
4+
45
from nr_openai_observability import monitor
56

67
monitor.initialization(
7-
metadata={"environment": "development"}
8+
application_name="OpenAI observability example",
9+
metadata={"environment": "development"},
810
)
911

1012
openai.api_key = os.getenv("OPENAI_API_KEY")
1113
openai.Completion.create(
1214
model="text-davinci-003",
1315
prompt="What is Observability?",
1416
max_tokens=20,
15-
temperature=0
17+
temperature=0,
1618
)

Diff for: examples/langchain_example.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from typing import Any, Dict, List
2+
3+
import boto3
4+
from langchain.agents import AgentType, initialize_agent
5+
from langchain.chat_models import ChatOpenAI
6+
from langchain.llms.base import LLM
7+
from langchain.llms.bedrock import Bedrock
8+
from langchain.tools import Tool
9+
10+
from nr_openai_observability.langchain_callback import NewRelicCallbackHandler
11+
12+
13+
def metadata_callback(ocj: Any) -> Dict[str, Any]:
14+
return {"conversation_id": 123}
15+
16+
17+
new_relic_monitor = NewRelicCallbackHandler(
18+
"LangChain observability trace", metadata_callback=metadata_callback
19+
)
20+
21+
22+
def math(x):
23+
return 4
24+
25+
26+
tools = []
27+
tools.append(
28+
Tool(
29+
func=math,
30+
name="Calculator",
31+
description="useful for when you need to answer questions about math",
32+
)
33+
)
34+
35+
36+
openai_llm = ChatOpenAI(temperature=0)
37+
38+
39+
boto_client = boto3.client("bedrock", "us-east-1")
40+
bedrock_llm = Bedrock(
41+
model_id="anthropic.claude-v2", # "amazon.titan-tg1-large"
42+
client=boto_client,
43+
)
44+
45+
46+
def get_agent(llm: LLM, tools: List[Tool]):
47+
return initialize_agent(
48+
tools,
49+
llm,
50+
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
51+
)
52+
53+
54+
openai_agent = get_agent(openai_llm, tools)
55+
openai_agent.run("What is 2 + 2?", callbacks=[new_relic_monitor])
56+
57+
bedrock_agent = get_agent(bedrock_llm, tools)
58+
bedrock_agent.run("What is 2 + 2?", callbacks=[new_relic_monitor])
59+
60+
61+
print("Agent run successfully!")

Diff for: examples/langchain_vectordb_example.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from langchain.document_loaders import TextLoader
2+
from langchain.embeddings.openai import OpenAIEmbeddings
3+
from langchain.text_splitter import CharacterTextSplitter
4+
from langchain.vectorstores import Chroma
5+
6+
from nr_openai_observability.langchain_callback import NewRelicCallbackHandler
7+
8+
new_relic_monitor = NewRelicCallbackHandler("LangChain observability trace")
9+
10+
raw_documents = TextLoader("./examples/state_of_the_union.txt").load()
11+
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
12+
documents = text_splitter.split_documents(raw_documents)
13+
db = Chroma.from_documents(documents, OpenAIEmbeddings())
14+
15+
query = "What did the president say about Ketanji Brown Jackson"
16+
docs = db.similarity_search(query)
17+
print(docs[0].page_content)

0 commit comments

Comments
 (0)