From 31fbb6d336ee61f72e8a7fac1560fa79a1579c8c Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 07:06:41 -0700 Subject: [PATCH 1/7] feat(sessions): getting started guide --- app/src/pages/project/PythonSessionsGuide.tsx | 30 ++++++++++++ app/src/pages/project/SessionsTableEmpty.tsx | 48 ++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 app/src/pages/project/PythonSessionsGuide.tsx diff --git a/app/src/pages/project/PythonSessionsGuide.tsx b/app/src/pages/project/PythonSessionsGuide.tsx new file mode 100644 index 0000000000..4559651ca4 --- /dev/null +++ b/app/src/pages/project/PythonSessionsGuide.tsx @@ -0,0 +1,30 @@ +import React from "react"; + +import { Heading, Text, View } from "@arizeai/components"; + +import { CodeWrap, PythonBlockWithCopy } from "@phoenix/components/code"; + +const INSTALL_OPENINFERENCE_INSTRUMENTATION_PYTHON = `pip install openinference-instrumentation`; +export function PythonSessionsGuide() { + return ( +
+ + + Install Dependencies + + + + + Sessions are tracked via the OpenTelemetry attribute session.id + . The easiest way to get started with sessions is to use the + OpenInference instrumentation package. + + + + + +
+ ); +} diff --git a/app/src/pages/project/SessionsTableEmpty.tsx b/app/src/pages/project/SessionsTableEmpty.tsx index a35e5cee5c..44a93eac45 100644 --- a/app/src/pages/project/SessionsTableEmpty.tsx +++ b/app/src/pages/project/SessionsTableEmpty.tsx @@ -1,9 +1,39 @@ -import React from "react"; +import React, { ReactNode, useState } from "react"; import { css } from "@emotion/react"; -import { Flex } from "@arizeai/components"; +import { + Button, + Dialog, + DialogContainer, + Flex, + Icon, + Icons, + View, +} from "@arizeai/components"; + +import { CodeLanguage, CodeLanguageRadioGroup } from "@phoenix/components/code"; + +import { PythonSessionsGuide } from "./PythonSessionsGuide"; export function SessionsTableEmpty() { + const [dialog, setDialog] = useState(null); + const [language, setLanguage] = useState("Python"); + const onGettingStartedClick = () => { + setDialog( + + + + + + {language === "Python" ? : "coming soon"} + + + ); + }; + return ( @@ -16,9 +46,23 @@ export function SessionsTableEmpty() { > No sessions found for this project + + setDialog(null)} + isDismissable + type="slideOver" + > + {dialog} + ); } From 6d318784f6fb91aa2446407bf737423231280d96 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 08:03:16 -0700 Subject: [PATCH 2/7] minimum working sessions example --- tutorials/tracing/openai_tracing_tutorial.ipynb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tutorials/tracing/openai_tracing_tutorial.ipynb b/tutorials/tracing/openai_tracing_tutorial.ipynb index 898724cead..f48522a1bf 100644 --- a/tutorials/tracing/openai_tracing_tutorial.ipynb +++ b/tutorials/tracing/openai_tracing_tutorial.ipynb @@ -389,8 +389,14 @@ } ], "metadata": { + "kernelspec": { + "display_name": "phoenix", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "name": "python", + "version": "3.12.7" } }, "nbformat": 4, From 01f5beddbd960a3b48aba4ff80f2fd3d705838fd Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 08:24:38 -0700 Subject: [PATCH 3/7] add python getting started guide --- app/src/pages/project/PythonSessionsGuide.tsx | 62 ++++ app/src/pages/project/SessionsTableEmpty.tsx | 2 +- .../tracing/openai_sessions_tutorial.ipynb | 340 ++++++++++++++++++ 3 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 tutorials/tracing/openai_sessions_tutorial.ipynb diff --git a/app/src/pages/project/PythonSessionsGuide.tsx b/app/src/pages/project/PythonSessionsGuide.tsx index 4559651ca4..f497f4c2dc 100644 --- a/app/src/pages/project/PythonSessionsGuide.tsx +++ b/app/src/pages/project/PythonSessionsGuide.tsx @@ -5,6 +5,54 @@ import { Heading, Text, View } from "@arizeai/components"; import { CodeWrap, PythonBlockWithCopy } from "@phoenix/components/code"; const INSTALL_OPENINFERENCE_INSTRUMENTATION_PYTHON = `pip install openinference-instrumentation`; +const ADD_SESSION_ID_PYTHON = `import uuid + +import openai +from openinference.instrumentation import using_session +from openinference.semconv.trace import SpanAttributes +from opentelemetry import trace + +client = openai.Client() +session_id = str(uuid.uuid4()) + +tracer = trace.get_tracer(__name__) + +@tracer.start_as_current_span(name="agent", attributes={SpanAttributes.OPENINFERENCE_SPAN_KIND: "agent"}) +def assistant( + messages: list[dict], + session_id: str = str, +): + current_span = trace.get_current_span() + current_span.set_attribute(SpanAttributes.SESSION_ID, session_id) + current_span.set_attribute(SpanAttributes.INPUT_VALUE, messages[-1].get('content')) + + # Propagate the session_id down to spans crated by the OpenAI instrumentation + # This is not strictly necessary, but it helps to correlate the spans to the same session + with using_session(session_id): + response = client.chat.completions.create( + model="gpt-3.5-turbo", + messages=[{"role": "system", "content": "You are a helpful assistant."}] + messages, + ).choices[0].message + + current_span.set_attribute(SpanAttributes.OUTPUT_VALUE, response.content) + return response + +messages = [ + {"role": "user", "content": "hi! im bob"} +] +response = assistant( + messages, + session_id=session_id, +) +messages = messages + [ + response, + {"role": "user", "content": "what's my name?"} +] +response = assistant( + messages, + session_id=session_id, +)`; + export function PythonSessionsGuide() { return (
@@ -25,6 +73,20 @@ export function PythonSessionsGuide() { value={INSTALL_OPENINFERENCE_INSTRUMENTATION_PYTHON} /> + + + Add Session ID to your Traces + + + + + Below is an example of how to add session IDs to a simple OpenAI + application. + + + + +
); } diff --git a/app/src/pages/project/SessionsTableEmpty.tsx b/app/src/pages/project/SessionsTableEmpty.tsx index 44a93eac45..38dcf7218a 100644 --- a/app/src/pages/project/SessionsTableEmpty.tsx +++ b/app/src/pages/project/SessionsTableEmpty.tsx @@ -20,7 +20,7 @@ export function SessionsTableEmpty() { const [language, setLanguage] = useState("Python"); const onGettingStartedClick = () => { setDialog( - + \n", + "

\n", + " \"phoenix\n", + "
\n", + " Docs\n", + " |\n", + " GitHub\n", + " |\n", + " Community\n", + "

\n", + "\n", + "

Setting up Sessions

\n", + "\n", + "A Session is a sequence of traces representing a single session (e.g. a session or a thread). Each response is represented as it's own trace, but these traces are linked together by being part of the same session.\n", + "To associate traces together, you need to pass in a special metadata key where the value is the unique identifier for that thread.\n", + "\n", + "In this tutorial we will setup sessions using OpenAI and OpenInference instrumentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Install Dependencies and Import Libraries\n", + "\n", + "Install dependencies." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n", + "I0000 00:00:1733237167.554913 1990701 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: openai>=1.0.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.55.1)\n", + "Requirement already satisfied: arize-phoenix in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (5.12.0)\n", + "Requirement already satisfied: jsonschema in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (4.23.0)\n", + "Requirement already satisfied: openinference-instrumentation-openai in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.18)\n", + "Requirement already satisfied: openinference-instrumentation in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.18)\n", + "Requirement already satisfied: opentelemetry-api in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.28.2)\n", + "Requirement already satisfied: opentelemetry-sdk in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.28.2)\n", + "Requirement already satisfied: openinference-semantic-conventions in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.12)\n", + "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.6.2.post1)\n", + "Requirement already satisfied: distro<2,>=1.7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (1.9.0)\n", + "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (0.27.2)\n", + "Requirement already satisfied: jiter<1,>=0.4.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (0.7.1)\n", + "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (2.9.2)\n", + "Requirement already satisfied: sniffio in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (1.3.1)\n", + "Requirement already satisfied: tqdm>4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.67.1)\n", + "Requirement already satisfied: typing-extensions<5,>=4.11 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.12.2)\n", + "Requirement already satisfied: aioitertools in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.12.0)\n", + "Requirement already satisfied: aiosqlite in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.20.0)\n", + "Requirement already satisfied: alembic<2,>=1.3.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.14.0)\n", + "Requirement already satisfied: arize-phoenix-evals>=0.13.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.17.5)\n", + "Requirement already satisfied: arize-phoenix-otel>=0.5.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.6.1)\n", + "Requirement already satisfied: authlib in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.3.2)\n", + "Requirement already satisfied: cachetools in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (5.5.0)\n", + "Requirement already satisfied: fastapi in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.115.5)\n", + "Requirement already satisfied: grpc-interceptor in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.15.4)\n", + "Requirement already satisfied: grpcio in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.68.0)\n", + "Requirement already satisfied: jinja2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (3.1.4)\n", + "Requirement already satisfied: numpy!=2.0.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.26.4)\n", + "Requirement already satisfied: opentelemetry-exporter-otlp in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.28.2)\n", + "Requirement already satisfied: opentelemetry-proto>=1.12.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.28.2)\n", + "Requirement already satisfied: opentelemetry-semantic-conventions in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.49b2)\n", + "Requirement already satisfied: pandas>=1.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (2.2.3)\n", + "Requirement already satisfied: protobuf<6.0,>=3.20.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (5.28.3)\n", + "Requirement already satisfied: psutil in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (6.1.0)\n", + "Requirement already satisfied: pyarrow in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (18.1.0)\n", + "Requirement already satisfied: python-multipart in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.0.17)\n", + "Requirement already satisfied: scikit-learn in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.5.2)\n", + "Requirement already satisfied: scipy in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.14.1)\n", + "Requirement already satisfied: sqlalchemy<3,>=2.0.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from sqlalchemy[asyncio]<3,>=2.0.4->arize-phoenix) (2.0.36)\n", + "Requirement already satisfied: sqlean-py>=3.45.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (3.47.0)\n", + "Requirement already satisfied: starlette in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.41.3)\n", + "Requirement already satisfied: strawberry-graphql==0.243.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.243.1)\n", + "Requirement already satisfied: uvicorn in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.32.1)\n", + "Requirement already satisfied: websockets in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (14.1)\n", + "Requirement already satisfied: wrapt in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.17.0)\n", + "Requirement already satisfied: graphql-core<3.4.0,>=3.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from strawberry-graphql==0.243.1->arize-phoenix) (3.2.5)\n", + "Requirement already satisfied: python-dateutil<3.0.0,>=2.7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from strawberry-graphql==0.243.1->arize-phoenix) (2.9.0.post0)\n", + "Requirement already satisfied: attrs>=22.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (24.2.0)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (2024.10.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (0.35.1)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (0.21.0)\n", + "Requirement already satisfied: opentelemetry-instrumentation in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openinference-instrumentation-openai) (0.49b2)\n", + "Requirement already satisfied: deprecated>=1.2.6 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-api) (1.2.15)\n", + "Requirement already satisfied: importlib-metadata<=8.5.0,>=6.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-api) (8.5.0)\n", + "Requirement already satisfied: Mako in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from alembic<2,>=1.3.0->arize-phoenix) (1.3.6)\n", + "Requirement already satisfied: idna>=2.8 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai>=1.0.0) (3.10)\n", + "Requirement already satisfied: certifi in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai>=1.0.0) (2024.8.30)\n", + "Requirement already satisfied: httpcore==1.* in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai>=1.0.0) (1.0.7)\n", + "Requirement already satisfied: h11<0.15,>=0.13 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai>=1.0.0) (0.14.0)\n", + "Requirement already satisfied: zipp>=3.20 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from importlib-metadata<=8.5.0,>=6.0->opentelemetry-api) (3.21.0)\n", + "Requirement already satisfied: pytz>=2020.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pandas>=1.0->arize-phoenix) (2024.2)\n", + "Requirement already satisfied: tzdata>=2022.7 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pandas>=1.0->arize-phoenix) (2024.2)\n", + "Requirement already satisfied: annotated-types>=0.6.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai>=1.0.0) (0.7.0)\n", + "Requirement already satisfied: pydantic-core==2.23.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai>=1.0.0) (2.23.4)\n", + "Requirement already satisfied: greenlet!=0.4.17 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from sqlalchemy[asyncio]<3,>=2.0.4->arize-phoenix) (3.1.1)\n", + "Requirement already satisfied: cryptography in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from authlib->arize-phoenix) (43.0.3)\n", + "Requirement already satisfied: MarkupSafe>=2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jinja2->arize-phoenix) (3.0.2)\n", + "Requirement already satisfied: opentelemetry-exporter-otlp-proto-grpc==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", + "Requirement already satisfied: opentelemetry-exporter-otlp-proto-http==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", + "Requirement already satisfied: googleapis-common-protos~=1.52 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-grpc==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (1.66.0)\n", + "Requirement already satisfied: opentelemetry-exporter-otlp-proto-common==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-grpc==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", + "Requirement already satisfied: requests~=2.7 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (2.32.3)\n", + "Requirement already satisfied: packaging>=18.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-instrumentation->openinference-instrumentation-openai) (24.2)\n", + "Requirement already satisfied: joblib>=1.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from scikit-learn->arize-phoenix) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=3.1.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from scikit-learn->arize-phoenix) (3.5.0)\n", + "Requirement already satisfied: click>=7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from uvicorn->arize-phoenix) (8.1.7)\n", + "Requirement already satisfied: six>=1.5 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from python-dateutil<3.0.0,>=2.7.0->strawberry-graphql==0.243.1->arize-phoenix) (1.16.0)\n", + "Requirement already satisfied: cffi>=1.12 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from cryptography->authlib->arize-phoenix) (1.17.1)\n", + "Requirement already satisfied: pycparser in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from cffi>=1.12->cryptography->authlib->arize-phoenix) (2.22)\n", + "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from requests~=2.7->opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (3.4.0)\n", + "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from requests~=2.7->opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (2.2.3)\n" + ] + } + ], + "source": [ + "!pip install \"openai>=1.0.0\" arize-phoenix jsonschema openinference-instrumentation-openai openinference-instrumentation opentelemetry-api opentelemetry-sdk openinference-semantic-conventions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure Your OpenAI API Key and Instantiate Your OpenAI Client\n", + "\n", + "Set your OpenAI API key if it is not already set as an environment variable." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from getpass import getpass\n", + "\n", + "from openai import OpenAI\n", + "\n", + "if not (openai_api_key := os.getenv(\"OPENAI_API_KEY\")):\n", + " openai_api_key = getpass(\"🔑 Enter your OpenAI API key: \")\n", + "client = OpenAI(api_key=openai_api_key)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Instrument Your OpenAI Client\n", + "\n", + "Instrument your OpenAI client with a tracer that emits telemetry data in OpenInference format. [OpenInference](https://arize-ai.github.io/open-inference-spec/trace/) is an open standard for capturing and storing LLM application traces that enables LLM applications to seamlessly integrate with LLM observability solutions such as Phoenix." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🔭 OpenTelemetry Tracing Details 🔭\n", + "| Phoenix Project: openai-sessions-example\n", + "| Span Processor: SimpleSpanProcessor\n", + "| Collector Endpoint: localhost:4317\n", + "| Transport: gRPC\n", + "| Transport Headers: {'user-agent': '****'}\n", + "| \n", + "| Using a default SpanProcessor. `add_span_processor` will overwrite this default.\n", + "| \n", + "| `register` has set this TracerProvider as the global OpenTelemetry default.\n", + "| To disable this behavior, call `register` with `set_global_tracer_provider=False`.\n", + "\n" + ] + } + ], + "source": [ + "from openinference.instrumentation.openai import OpenAIInstrumentor\n", + "\n", + "from phoenix.otel import register\n", + "\n", + "tracer_provider = register(project_name=\"openai-sessions-example\")\n", + "OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run Phoenix in the Background\n", + "\n", + "Launch Phoenix as a background session to collect the trace data emitted by your instrumented OpenAI client. Note that Phoenix should be run in a container in a production environment." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🌍 To view the Phoenix app in your browser, visit http://localhost:6006/\n", + "📖 For more information on how to use Phoenix, check out https://docs.arize.com/phoenix\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import phoenix as px\n", + "\n", + "px.launch_app()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a bare-bones Agent\n", + "\n", + "Let's create the outline of an agent that will leverage OpenAI." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "import uuid\n", + "\n", + "import openai\n", + "from openinference.instrumentation import using_session\n", + "from openinference.semconv.trace import SpanAttributes\n", + "from opentelemetry import trace\n", + "\n", + "client = openai.Client()\n", + "session_id = str(uuid.uuid4())\n", + "\n", + "tracer = trace.get_tracer(__name__)\n", + "\n", + "@tracer.start_as_current_span(name=\"agent\", attributes={SpanAttributes.OPENINFERENCE_SPAN_KIND: \"agent\"})\n", + "def assistant(\n", + " messages: list[dict],\n", + " session_id: str = str,\n", + "):\n", + " current_span = trace.get_current_span()\n", + " current_span.set_attribute(SpanAttributes.SESSION_ID, session_id)\n", + " current_span.set_attribute(SpanAttributes.INPUT_VALUE, messages[-1].get('content'))\n", + "\n", + " # Propagate the session_id down to spans crated by the OpenAI instrumentation\n", + " # This is not strictly necessary, but it helps to correlate the spans to the same session\n", + " with using_session(session_id):\n", + " response = client.chat.completions.create(\n", + " model=\"gpt-3.5-turbo\",\n", + " messages=[{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}] + messages,\n", + " ).choices[0].message\n", + "\n", + " current_span.set_attribute(SpanAttributes.OUTPUT_VALUE, response.content)\n", + " return response\n", + "\n", + "messages = [\n", + " {\"role\": \"user\", \"content\": \"hi! im bob\"}\n", + "]\n", + "response = assistant(\n", + " messages,\n", + " session_id=session_id,\n", + ")\n", + "messages = messages + [\n", + " response,\n", + " {\"role\": \"user\", \"content\": \"what's my name?\"}\n", + "]\n", + "response = assistant(\n", + " messages,\n", + " session_id=session_id,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "phoenix", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 190a5931e27f9fe816fc565bbc15aebaac8bad5e Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 10:54:52 -0700 Subject: [PATCH 4/7] add typescript guide --- app/src/pages/project/PythonSessionsGuide.tsx | 9 ++ app/src/pages/project/SessionsTableEmpty.tsx | 34 +++--- .../pages/project/TypeScriptSessionsGuide.tsx | 115 ++++++++++++++++++ cspell.json | 1 + .../tracing/openai_sessions_tutorial.ipynb | 7 -- 5 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 app/src/pages/project/TypeScriptSessionsGuide.tsx diff --git a/app/src/pages/project/PythonSessionsGuide.tsx b/app/src/pages/project/PythonSessionsGuide.tsx index f497f4c2dc..ed659bbefb 100644 --- a/app/src/pages/project/PythonSessionsGuide.tsx +++ b/app/src/pages/project/PythonSessionsGuide.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Heading, Text, View } from "@arizeai/components"; +import { ExternalLink } from "@phoenix/components"; import { CodeWrap, PythonBlockWithCopy } from "@phoenix/components/code"; const INSTALL_OPENINFERENCE_INSTRUMENTATION_PYTHON = `pip install openinference-instrumentation`; @@ -87,6 +88,14 @@ export function PythonSessionsGuide() { + + + For more information on how to use sessions, consult the{" "} + + documentation + + + ); } diff --git a/app/src/pages/project/SessionsTableEmpty.tsx b/app/src/pages/project/SessionsTableEmpty.tsx index 38dcf7218a..beb415ee67 100644 --- a/app/src/pages/project/SessionsTableEmpty.tsx +++ b/app/src/pages/project/SessionsTableEmpty.tsx @@ -14,24 +14,30 @@ import { import { CodeLanguage, CodeLanguageRadioGroup } from "@phoenix/components/code"; import { PythonSessionsGuide } from "./PythonSessionsGuide"; +import { TypeScriptSessionsGuide } from "./TypeScriptSessionsGuide"; +function SetupSessionsDialog() { + const [language, setLanguage] = useState("Python"); + return ( + + + + + + {language === "Python" ? ( + + ) : ( + + )} + + + ); +} export function SessionsTableEmpty() { const [dialog, setDialog] = useState(null); - const [language, setLanguage] = useState("Python"); + const onGettingStartedClick = () => { - setDialog( - - - - - - {language === "Python" ? : "coming soon"} - - - ); + setDialog(); }; return ( diff --git a/app/src/pages/project/TypeScriptSessionsGuide.tsx b/app/src/pages/project/TypeScriptSessionsGuide.tsx new file mode 100644 index 0000000000..66cc6bcb45 --- /dev/null +++ b/app/src/pages/project/TypeScriptSessionsGuide.tsx @@ -0,0 +1,115 @@ +import React from "react"; + +import { Heading, Text, View } from "@arizeai/components"; + +import { ExternalLink } from "@phoenix/components"; +import { CodeWrap, PythonBlockWithCopy } from "@phoenix/components/code"; +import { TypeScriptBlockWithCopy } from "@phoenix/components/code/TypeScriptBlockWithCopy"; + +const INSTALL_OPENINFERENCE_CORE_TYPESCRIPT = `npm install @arizeai/openinference-core --save`; + +const ADD_SESSION_ID_TYPESCRIPT = `import { trace } from "npm:@opentelemetry/api"; +import { SemanticConventions } from "npm:@arizeai/openinference-semantic-conventions"; +import { context } from "npm:@opentelemetry/api"; +import { setSession } from "npm:@arizeai/openinference-core"; + +const tracer = trace.getTracer("agent"); + +const client = new OpenAI({ + apiKey: process.env["OPENAI_API_KEY"], // This is the default and can be omitted +}); + +async function assistant(params: { + messages: { role: string; content: string }[]; + sessionId: string; +}) { + return tracer.startActiveSpan("agent", async (span: Span) => { + span.setAttribute(SemanticConventions.OPENINFERENCE_SPAN_KIND, "agent"); + span.setAttribute(SemanticConventions.SESSION_ID, params.sessionId); + span.setAttribute( + SemanticConventions.INPUT_VALUE, + messages[messages.length - 1].content, + ); + try { + // This is not strictly necessary but it helps propagate the session ID + // to all child spans + return context.with( + setSession(context.active(), { sessionId: params.sessionId }), + async () => { + // Calls within this block will generate spans with the session ID set + const chatCompletion = await client.chat.completions.create({ + messages: params.messages, + model: "gpt-3.5-turbo", + }); + const response = chatCompletion.choices[0].message; + span.setAttribute(SemanticConventions.OUTPUT_VALUE, response.content); + span.end(); + return response; + }, + ); + } catch (e) { + span.error(e); + } + }); +} + +const sessionId = crypto.randomUUID(); + +let messages = [{ role: "user", content: "hi! im Tim" }]; + +const res = await assistant({ + messages, + sessionId: sessionId, +}); + +messages = [res, { role: "assistant", content: "What is my name?" }]; + +await assistant({ + messages, + sessionId: sessionId, +}); +`; + +export function TypeScriptSessionsGuide() { + return ( +
+ + + Install Dependencies + + + + + Sessions are tracked via the OpenTelemetry attribute session.id + . The easiest way to get started with sessions is to use the + OpenInference instrumentation package. + + + + + + + + Add Session ID to your Traces + + + + + Below is an example of how to add session IDs to a simple OpenAI + application. + + + + + + + + For more information on how to use sessions, consult the{" "} + + documentation + + + +
+ ); +} diff --git a/cspell.json b/cspell.json index 0ac8a3cc89..f880d8fb7d 100644 --- a/cspell.json +++ b/cspell.json @@ -56,6 +56,7 @@ "rgba", "rowid", "seafoam", + "SEMRESATTRS", "sqlalchemy", "Starlette", "tanstack", diff --git a/tutorials/tracing/openai_sessions_tutorial.ipynb b/tutorials/tracing/openai_sessions_tutorial.ipynb index 8468cf469f..82b8e6c4a3 100644 --- a/tutorials/tracing/openai_sessions_tutorial.ipynb +++ b/tutorials/tracing/openai_sessions_tutorial.ipynb @@ -307,13 +307,6 @@ " session_id=session_id,\n", ")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 2008cce3d9d542f7df48c56e7338789c642c3018 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 11:01:43 -0700 Subject: [PATCH 5/7] add tutorials --- app/src/pages/project/SessionsTableEmpty.tsx | 2 +- .../tracing/openai_sessions_tutorial.ipynb | 150 +----------------- 2 files changed, 9 insertions(+), 143 deletions(-) diff --git a/app/src/pages/project/SessionsTableEmpty.tsx b/app/src/pages/project/SessionsTableEmpty.tsx index beb415ee67..a6162ff1d2 100644 --- a/app/src/pages/project/SessionsTableEmpty.tsx +++ b/app/src/pages/project/SessionsTableEmpty.tsx @@ -37,7 +37,7 @@ export function SessionsTableEmpty() { const [dialog, setDialog] = useState(null); const onGettingStartedClick = () => { - setDialog(); + setDialog(); }; return ( diff --git a/tutorials/tracing/openai_sessions_tutorial.ipynb b/tutorials/tracing/openai_sessions_tutorial.ipynb index 82b8e6c4a3..701f6ffbb4 100644 --- a/tutorials/tracing/openai_sessions_tutorial.ipynb +++ b/tutorials/tracing/openai_sessions_tutorial.ipynb @@ -34,105 +34,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n", - "I0000 00:00:1733237167.554913 1990701 fork_posix.cc:75] Other threads are currently calling into gRPC, skipping fork() handlers\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: openai>=1.0.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.55.1)\n", - "Requirement already satisfied: arize-phoenix in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (5.12.0)\n", - "Requirement already satisfied: jsonschema in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (4.23.0)\n", - "Requirement already satisfied: openinference-instrumentation-openai in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.18)\n", - "Requirement already satisfied: openinference-instrumentation in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.18)\n", - "Requirement already satisfied: opentelemetry-api in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.28.2)\n", - "Requirement already satisfied: opentelemetry-sdk in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (1.28.2)\n", - "Requirement already satisfied: openinference-semantic-conventions in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (0.1.12)\n", - "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.6.2.post1)\n", - "Requirement already satisfied: distro<2,>=1.7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (1.9.0)\n", - "Requirement already satisfied: httpx<1,>=0.23.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (0.27.2)\n", - "Requirement already satisfied: jiter<1,>=0.4.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (0.7.1)\n", - "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (2.9.2)\n", - "Requirement already satisfied: sniffio in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (1.3.1)\n", - "Requirement already satisfied: tqdm>4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.67.1)\n", - "Requirement already satisfied: typing-extensions<5,>=4.11 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openai>=1.0.0) (4.12.2)\n", - "Requirement already satisfied: aioitertools in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.12.0)\n", - "Requirement already satisfied: aiosqlite in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.20.0)\n", - "Requirement already satisfied: alembic<2,>=1.3.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.14.0)\n", - "Requirement already satisfied: arize-phoenix-evals>=0.13.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.17.5)\n", - "Requirement already satisfied: arize-phoenix-otel>=0.5.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.6.1)\n", - "Requirement already satisfied: authlib in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.3.2)\n", - "Requirement already satisfied: cachetools in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (5.5.0)\n", - "Requirement already satisfied: fastapi in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.115.5)\n", - "Requirement already satisfied: grpc-interceptor in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.15.4)\n", - "Requirement already satisfied: grpcio in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.68.0)\n", - "Requirement already satisfied: jinja2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (3.1.4)\n", - "Requirement already satisfied: numpy!=2.0.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.26.4)\n", - "Requirement already satisfied: opentelemetry-exporter-otlp in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.28.2)\n", - "Requirement already satisfied: opentelemetry-proto>=1.12.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.28.2)\n", - "Requirement already satisfied: opentelemetry-semantic-conventions in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.49b2)\n", - "Requirement already satisfied: pandas>=1.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (2.2.3)\n", - "Requirement already satisfied: protobuf<6.0,>=3.20.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (5.28.3)\n", - "Requirement already satisfied: psutil in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (6.1.0)\n", - "Requirement already satisfied: pyarrow in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (18.1.0)\n", - "Requirement already satisfied: python-multipart in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.0.17)\n", - "Requirement already satisfied: scikit-learn in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.5.2)\n", - "Requirement already satisfied: scipy in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.14.1)\n", - "Requirement already satisfied: sqlalchemy<3,>=2.0.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from sqlalchemy[asyncio]<3,>=2.0.4->arize-phoenix) (2.0.36)\n", - "Requirement already satisfied: sqlean-py>=3.45.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (3.47.0)\n", - "Requirement already satisfied: starlette in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.41.3)\n", - "Requirement already satisfied: strawberry-graphql==0.243.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.243.1)\n", - "Requirement already satisfied: uvicorn in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (0.32.1)\n", - "Requirement already satisfied: websockets in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (14.1)\n", - "Requirement already satisfied: wrapt in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from arize-phoenix) (1.17.0)\n", - "Requirement already satisfied: graphql-core<3.4.0,>=3.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from strawberry-graphql==0.243.1->arize-phoenix) (3.2.5)\n", - "Requirement already satisfied: python-dateutil<3.0.0,>=2.7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from strawberry-graphql==0.243.1->arize-phoenix) (2.9.0.post0)\n", - "Requirement already satisfied: attrs>=22.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (24.2.0)\n", - "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (2024.10.1)\n", - "Requirement already satisfied: referencing>=0.28.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (0.35.1)\n", - "Requirement already satisfied: rpds-py>=0.7.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jsonschema) (0.21.0)\n", - "Requirement already satisfied: opentelemetry-instrumentation in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from openinference-instrumentation-openai) (0.49b2)\n", - "Requirement already satisfied: deprecated>=1.2.6 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-api) (1.2.15)\n", - "Requirement already satisfied: importlib-metadata<=8.5.0,>=6.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-api) (8.5.0)\n", - "Requirement already satisfied: Mako in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from alembic<2,>=1.3.0->arize-phoenix) (1.3.6)\n", - "Requirement already satisfied: idna>=2.8 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from anyio<5,>=3.5.0->openai>=1.0.0) (3.10)\n", - "Requirement already satisfied: certifi in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai>=1.0.0) (2024.8.30)\n", - "Requirement already satisfied: httpcore==1.* in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpx<1,>=0.23.0->openai>=1.0.0) (1.0.7)\n", - "Requirement already satisfied: h11<0.15,>=0.13 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai>=1.0.0) (0.14.0)\n", - "Requirement already satisfied: zipp>=3.20 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from importlib-metadata<=8.5.0,>=6.0->opentelemetry-api) (3.21.0)\n", - "Requirement already satisfied: pytz>=2020.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pandas>=1.0->arize-phoenix) (2024.2)\n", - "Requirement already satisfied: tzdata>=2022.7 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pandas>=1.0->arize-phoenix) (2024.2)\n", - "Requirement already satisfied: annotated-types>=0.6.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai>=1.0.0) (0.7.0)\n", - "Requirement already satisfied: pydantic-core==2.23.4 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from pydantic<3,>=1.9.0->openai>=1.0.0) (2.23.4)\n", - "Requirement already satisfied: greenlet!=0.4.17 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from sqlalchemy[asyncio]<3,>=2.0.4->arize-phoenix) (3.1.1)\n", - "Requirement already satisfied: cryptography in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from authlib->arize-phoenix) (43.0.3)\n", - "Requirement already satisfied: MarkupSafe>=2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from jinja2->arize-phoenix) (3.0.2)\n", - "Requirement already satisfied: opentelemetry-exporter-otlp-proto-grpc==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", - "Requirement already satisfied: opentelemetry-exporter-otlp-proto-http==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", - "Requirement already satisfied: googleapis-common-protos~=1.52 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-grpc==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (1.66.0)\n", - "Requirement already satisfied: opentelemetry-exporter-otlp-proto-common==1.28.2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-grpc==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (1.28.2)\n", - "Requirement already satisfied: requests~=2.7 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (2.32.3)\n", - "Requirement already satisfied: packaging>=18.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from opentelemetry-instrumentation->openinference-instrumentation-openai) (24.2)\n", - "Requirement already satisfied: joblib>=1.2.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from scikit-learn->arize-phoenix) (1.4.2)\n", - "Requirement already satisfied: threadpoolctl>=3.1.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from scikit-learn->arize-phoenix) (3.5.0)\n", - "Requirement already satisfied: click>=7.0 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from uvicorn->arize-phoenix) (8.1.7)\n", - "Requirement already satisfied: six>=1.5 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from python-dateutil<3.0.0,>=2.7.0->strawberry-graphql==0.243.1->arize-phoenix) (1.16.0)\n", - "Requirement already satisfied: cffi>=1.12 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from cryptography->authlib->arize-phoenix) (1.17.1)\n", - "Requirement already satisfied: pycparser in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from cffi>=1.12->cryptography->authlib->arize-phoenix) (2.22)\n", - "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from requests~=2.7->opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (3.4.0)\n", - "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/mikeldking/anaconda3/envs/phoenix/lib/python3.12/site-packages (from requests~=2.7->opentelemetry-exporter-otlp-proto-http==1.28.2->opentelemetry-exporter-otlp->arize-phoenix) (2.2.3)\n" - ] - } - ], + "outputs": [], "source": [ "!pip install \"openai>=1.0.0\" arize-phoenix jsonschema openinference-instrumentation-openai openinference-instrumentation opentelemetry-api opentelemetry-sdk openinference-semantic-conventions" ] @@ -148,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -173,28 +77,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "🔭 OpenTelemetry Tracing Details 🔭\n", - "| Phoenix Project: openai-sessions-example\n", - "| Span Processor: SimpleSpanProcessor\n", - "| Collector Endpoint: localhost:4317\n", - "| Transport: gRPC\n", - "| Transport Headers: {'user-agent': '****'}\n", - "| \n", - "| Using a default SpanProcessor. `add_span_processor` will overwrite this default.\n", - "| \n", - "| `register` has set this TracerProvider as the global OpenTelemetry default.\n", - "| To disable this behavior, call `register` with `set_global_tracer_provider=False`.\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "from openinference.instrumentation.openai import OpenAIInstrumentor\n", "\n", @@ -215,28 +100,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "🌍 To view the Phoenix app in your browser, visit http://localhost:6006/\n", - "📖 For more information on how to use Phoenix, check out https://docs.arize.com/phoenix\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "import phoenix as px\n", "\n", @@ -254,7 +120,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ From 74c896593ac52df180fea65768237911464ea46a Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 11:06:17 -0700 Subject: [PATCH 6/7] cleanup --- .../tracing_openai_sessions_tutorial.ipynb | 196 ++++++++++++++++++ .../tracing/openai_sessions_tutorial.ipynb | 16 +- .../tracing/openai_tracing_tutorial.ipynb | 8 +- 3 files changed, 198 insertions(+), 22 deletions(-) create mode 100644 js/examples/notebooks/tracing_openai_sessions_tutorial.ipynb diff --git a/js/examples/notebooks/tracing_openai_sessions_tutorial.ipynb b/js/examples/notebooks/tracing_openai_sessions_tutorial.ipynb new file mode 100644 index 0000000000..8e6e65a890 --- /dev/null +++ b/js/examples/notebooks/tracing_openai_sessions_tutorial.ipynb @@ -0,0 +1,196 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + "

\n", + " \"phoenix\n", + "
\n", + "
\n", + " Docs\n", + " |\n", + " GitHub\n", + " |\n", + " Community\n", + "

\n", + "
\n", + "

Setting Up Sessions

\n", + "\n", + "A Session is a sequence of traces representing a single session (e.g. a session or a thread). Each response is represented as it's own trace, but these traces are linked together by being part of the same session.\n", + "To associate traces together, you need to pass in a special metadata key where the value is the unique identifier for that thread.\n", + "\n", + "In this tutorial we will setup sessions using OpenAI and OpenInference instrumentation.\n", + "\n", + "> Note: that this example requires the OPENAI_API_KEY environment variable to be set and assumes you are running the Phoenix server on localhost:6006." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "👀 OpenInference initialized\n" + ] + } + ], + "source": [ + "import {\n", + " NodeTracerProvider,\n", + " SimpleSpanProcessor,\n", + "} from \"npm:@opentelemetry/sdk-trace-node\";\n", + "import { Resource } from \"npm:@opentelemetry/resources\";\n", + "import { OTLPTraceExporter } from \"npm:@opentelemetry/exporter-trace-otlp-proto\";\n", + "import { SEMRESATTRS_PROJECT_NAME } from \"npm:@arizeai/openinference-semantic-conventions\";\n", + "import { diag, DiagConsoleLogger, DiagLogLevel } from \"npm:@opentelemetry/api\";\n", + "\n", + "// For troubleshooting, set the log level to DiagLogLevel.DEBUG\n", + "diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);\n", + "\n", + "const provider = new NodeTracerProvider({\n", + " resource: new Resource({\n", + " [SEMRESATTRS_PROJECT_NAME]: \"openai-node-sessions-example\",\n", + " }),\n", + "});\n", + "\n", + "provider.addSpanProcessor(\n", + " new SimpleSpanProcessor(\n", + " new OTLPTraceExporter({\n", + " url: \"http://localhost:6006/v1/traces\",\n", + " }),\n", + " ),\n", + ");\n", + "\n", + "provider.register();\n", + "\n", + "console.log(\"👀 OpenInference initialized\");" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import OpenAI from 'npm:openai';\n", + "import { OpenAIInstrumentation } from \"npm:@arizeai/openinference-instrumentation-openai\";\n", + "\n", + "const oaiInstrumentor = new OpenAIInstrumentation();\n", + "oaiInstrumentor.manuallyInstrument(OpenAI);" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{\n", + " role: \u001b[32m\"assistant\"\u001b[39m,\n", + " content: \u001b[32m\"Your name is Tim. How can I assist you further today?\"\u001b[39m,\n", + " refusal: \u001b[1mnull\u001b[22m\n", + "}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import { trace } from \"npm:@opentelemetry/api\";\n", + "import { SemanticConventions } from \"npm:@arizeai/openinference-semantic-conventions\";\n", + "import { context } from \"npm:@opentelemetry/api\";\n", + "import { setSession } from \"npm:@arizeai/openinference-core\";\n", + "\n", + "const tracer = trace.getTracer(\"agent\");\n", + "\n", + "const client = new OpenAI({\n", + " apiKey: process.env[\"OPENAI_API_KEY\"], // This is the default and can be omitted\n", + "});\n", + "\n", + "async function assistant(params: {\n", + " messages: { role: string; content: string }[];\n", + " sessionId: string;\n", + "}) {\n", + " return tracer.startActiveSpan(\"agent\", async (span: Span) => {\n", + " span.setAttribute(SemanticConventions.OPENINFERENCE_SPAN_KIND, \"agent\");\n", + " span.setAttribute(SemanticConventions.SESSION_ID, params.sessionId);\n", + " span.setAttribute(\n", + " SemanticConventions.INPUT_VALUE,\n", + " messages[messages.length - 1].content,\n", + " );\n", + " try {\n", + " // This is not strictly necessary but it helps propagate the session ID\n", + " // to all child spans\n", + " return context.with(\n", + " setSession(context.active(), { sessionId: params.sessionId }),\n", + " async () => {\n", + " // Calls within this block will generate spans with the session ID set\n", + " const chatCompletion = await client.chat.completions.create({\n", + " messages: params.messages,\n", + " model: \"gpt-3.5-turbo\",\n", + " });\n", + " const response = chatCompletion.choices[0].message;\n", + " span.setAttribute(SemanticConventions.OUTPUT_VALUE, response.content);\n", + " span.end();\n", + " return response;\n", + " },\n", + " );\n", + " } catch (e) {\n", + " span.error(e);\n", + " }\n", + " });\n", + "}\n", + "\n", + "const sessionId = crypto.randomUUID();\n", + "\n", + "let messages = [{ role: \"user\", content: \"hi! im Tim\" }];\n", + "\n", + "const res = await assistant({\n", + " messages,\n", + " sessionId: sessionId,\n", + "});\n", + "\n", + "messages = [res, { role: \"assistant\", content: \"What is my name?\" }];\n", + "\n", + "await assistant({\n", + " messages,\n", + " sessionId: sessionId,\n", + "});\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Deno", + "language": "typescript", + "name": "deno" + }, + "language_info": { + "codemirror_mode": "typescript", + "file_extension": ".ts", + "mimetype": "text/x.typescript", + "name": "typescript", + "nbconvert_exporter": "script", + "pygments_lexer": "typescript", + "version": "5.6.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tutorials/tracing/openai_sessions_tutorial.ipynb b/tutorials/tracing/openai_sessions_tutorial.ipynb index 701f6ffbb4..304a8669b8 100644 --- a/tutorials/tracing/openai_sessions_tutorial.ipynb +++ b/tutorials/tracing/openai_sessions_tutorial.ipynb @@ -176,22 +176,8 @@ } ], "metadata": { - "kernelspec": { - "display_name": "phoenix", - "language": "python", - "name": "python3" - }, "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.7" + "name": "python" } }, "nbformat": 4, diff --git a/tutorials/tracing/openai_tracing_tutorial.ipynb b/tutorials/tracing/openai_tracing_tutorial.ipynb index f48522a1bf..898724cead 100644 --- a/tutorials/tracing/openai_tracing_tutorial.ipynb +++ b/tutorials/tracing/openai_tracing_tutorial.ipynb @@ -389,14 +389,8 @@ } ], "metadata": { - "kernelspec": { - "display_name": "phoenix", - "language": "python", - "name": "python3" - }, "language_info": { - "name": "python", - "version": "3.12.7" + "name": "python" } }, "nbformat": 4, From a35263115f6e4e896ee38bb336889d3c24a02f32 Mon Sep 17 00:00:00 2001 From: Mikyo King Date: Tue, 3 Dec 2024 11:57:58 -0700 Subject: [PATCH 7/7] fix format --- .../tracing/openai_sessions_tutorial.ipynb | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/tutorials/tracing/openai_sessions_tutorial.ipynb b/tutorials/tracing/openai_sessions_tutorial.ipynb index 304a8669b8..d12c607922 100644 --- a/tutorials/tracing/openai_sessions_tutorial.ipynb +++ b/tutorials/tracing/openai_sessions_tutorial.ipynb @@ -124,7 +124,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "import uuid\n", "\n", "import openai\n", @@ -137,40 +136,43 @@ "\n", "tracer = trace.get_tracer(__name__)\n", "\n", - "@tracer.start_as_current_span(name=\"agent\", attributes={SpanAttributes.OPENINFERENCE_SPAN_KIND: \"agent\"})\n", + "\n", + "@tracer.start_as_current_span(\n", + " name=\"agent\", attributes={SpanAttributes.OPENINFERENCE_SPAN_KIND: \"agent\"}\n", + ")\n", "def assistant(\n", - " messages: list[dict],\n", - " session_id: str = str,\n", + " messages: list[dict],\n", + " session_id: str = str,\n", "):\n", - " current_span = trace.get_current_span()\n", - " current_span.set_attribute(SpanAttributes.SESSION_ID, session_id)\n", - " current_span.set_attribute(SpanAttributes.INPUT_VALUE, messages[-1].get('content'))\n", - "\n", - " # Propagate the session_id down to spans crated by the OpenAI instrumentation\n", - " # This is not strictly necessary, but it helps to correlate the spans to the same session\n", - " with using_session(session_id):\n", - " response = client.chat.completions.create(\n", - " model=\"gpt-3.5-turbo\",\n", - " messages=[{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}] + messages,\n", - " ).choices[0].message\n", - "\n", - " current_span.set_attribute(SpanAttributes.OUTPUT_VALUE, response.content)\n", - " return response\n", - "\n", - "messages = [\n", - " {\"role\": \"user\", \"content\": \"hi! im bob\"}\n", - "]\n", + " current_span = trace.get_current_span()\n", + " current_span.set_attribute(SpanAttributes.SESSION_ID, session_id)\n", + " current_span.set_attribute(SpanAttributes.INPUT_VALUE, messages[-1].get(\"content\"))\n", + "\n", + " # Propagate the session_id down to spans crated by the OpenAI instrumentation\n", + " # This is not strictly necessary, but it helps to correlate the spans to the same session\n", + " with using_session(session_id):\n", + " response = (\n", + " client.chat.completions.create(\n", + " model=\"gpt-3.5-turbo\",\n", + " messages=[{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}] + messages,\n", + " )\n", + " .choices[0]\n", + " .message\n", + " )\n", + "\n", + " current_span.set_attribute(SpanAttributes.OUTPUT_VALUE, response.content)\n", + " return response\n", + "\n", + "\n", + "messages = [{\"role\": \"user\", \"content\": \"hi! im bob\"}]\n", "response = assistant(\n", - " messages,\n", - " session_id=session_id,\n", + " messages,\n", + " session_id=session_id,\n", ")\n", - "messages = messages + [\n", - " response,\n", - " {\"role\": \"user\", \"content\": \"what's my name?\"}\n", - "]\n", + "messages = messages + [response, {\"role\": \"user\", \"content\": \"what's my name?\"}]\n", "response = assistant(\n", - " messages,\n", - " session_id=session_id,\n", + " messages,\n", + " session_id=session_id,\n", ")" ] }