blob: 85ae779cb5106303084c80d1c7bd5024806543bd [file] [log] [blame]
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Execute this cell to install dependencies\n",
"%pip install sf-hamilton[visualization]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Monitor Hamilton with OpenTelemetry, OpenLLMetry and Traceloop [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dagworks-inc/hamilton/blob/main/examples/LLM_Workflows/observability_openllmetry/notebook.ipynb) [![GitHub badge](https://img.shields.io/badge/github-view_source-2b3137?logo=github)](https://github.com/dagworks-inc/hamilton/blob/main/examples/LLM_Workflows/observability_openllmetry/notebook.ipynb)\n",
"\n",
"\n",
"\n",
"It will showcase how the [OpenTelemetry](https://opentelemetry.io/) plugin for Hamilton can trace node and using [OpenLLMetry](https://github.com/traceloop/openllmetry) allows to automatically trace popular LLM components. This example uses [Traceloop](https://www.traceloop.com/) as a destination for telemetry, but other [open-source options are available](https://opentelemetry.io/ecosystem/vendors/) (Jaeger, Elastic, Clickhouse, Grafana, etc.)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from hamilton import driver\n",
"from hamilton.plugins import h_opentelemetry\n",
"from traceloop.sdk import Traceloop\n",
"\n",
"%load_ext hamilton.plugins.jupyter_magic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define a dataflow\n",
"The next cell creates a Python module named `llm_dataflow` and defines a dataflow that creates an OpenAI client and queries the chat completions endpoint to center an HTML `<div>` tag.\n",
"\n",
"You'll notice that nothing special is added to enable tracing"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.43.0 (0)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"282pt\" height=\"167pt\"\n",
" viewBox=\"0.00 0.00 282.00 167.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 163)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-163 278,-163 278,4 -4,4\"/>\n",
"<g id=\"clust1\" class=\"cluster\">\n",
"<title>cluster__legend</title>\n",
"<polygon fill=\"#ffffff\" stroke=\"black\" points=\"8,-74 8,-151 104,-151 104,-74 8,-74\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-135.8\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">Legend</text>\n",
"</g>\n",
"<!-- universal_truth -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>universal_truth</title>\n",
"<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M262,-64C262,-64 145,-64 145,-64 139,-64 133,-58 133,-52 133,-52 133,-12 133,-12 133,-6 139,0 145,0 145,0 262,0 262,0 268,0 274,-6 274,-12 274,-12 274,-52 274,-52 274,-58 268,-64 262,-64\"/>\n",
"<text text-anchor=\"start\" x=\"144\" y=\"-42.8\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">universal_truth</text>\n",
"<text text-anchor=\"start\" x=\"194\" y=\"-14.8\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">str</text>\n",
"</g>\n",
"<!-- llm_client -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>llm_client</title>\n",
"<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M92,-64C92,-64 20,-64 20,-64 14,-64 8,-58 8,-52 8,-52 8,-12 8,-12 8,-6 14,0 20,0 20,0 92,0 92,0 98,0 104,-6 104,-12 104,-12 104,-52 104,-52 104,-58 98,-64 92,-64\"/>\n",
"<text text-anchor=\"start\" x=\"19\" y=\"-42.8\" font-family=\"Helvetica,sans-Serif\" font-weight=\"bold\" font-size=\"14.00\">llm_client</text>\n",
"<text text-anchor=\"start\" x=\"30\" y=\"-14.8\" font-family=\"Helvetica,sans-Serif\" font-style=\"italic\" font-size=\"14.00\">OpenAI</text>\n",
"</g>\n",
"<!-- llm_client&#45;&gt;universal_truth -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>llm_client&#45;&gt;universal_truth</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M104.24,-32C110.09,-32 116.19,-32 122.36,-32\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"122.78,-35.5 132.78,-32 122.78,-28.5 122.78,-35.5\"/>\n",
"</g>\n",
"<!-- function -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>function</title>\n",
"<path fill=\"#b4d8e4\" stroke=\"black\" d=\"M84,-119.5C84,-119.5 28,-119.5 28,-119.5 22,-119.5 16,-113.5 16,-107.5 16,-107.5 16,-94.5 16,-94.5 16,-88.5 22,-82.5 28,-82.5 28,-82.5 84,-82.5 84,-82.5 90,-82.5 96,-88.5 96,-94.5 96,-94.5 96,-107.5 96,-107.5 96,-113.5 90,-119.5 84,-119.5\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-97.3\" font-family=\"Helvetica,sans-Serif\" font-size=\"14.00\">function</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.graphs.Digraph at 0x7f78c554f050>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%cell_to_module llm_dataflow -d\n",
"import openai\n",
"\n",
"def llm_client() -> openai.OpenAI:\n",
" return openai.OpenAI()\n",
"\n",
"def universal_truth(llm_client: openai.OpenAI) -> str:\n",
" response = llm_client.chat.completions.create(\n",
" model=\"gpt-4o-mini\",\n",
" messages=[\n",
" {\"role\": \"system\", \"content\": \"You are a benevolent all-knowning being\"},\n",
" {\"role\": \"user\", \"content\": \"Please center my HTML <div> tag\"},\n",
" ],\n",
" )\n",
" return str(response.choices[0].message.content)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Build the dataflow\n",
"The Hamilton `Builder` object takes the previously defined dataflow via `.with_modules(llm_dataflow)`. Then, we pass the `OpenTelemetryTracer` object via `.with_adapters()` to trace dataflow execution. Make sure to call `Traceloop.init()` before creating the `OpenTelemetryTracer`.\n",
"\n",
"You'll need to set your `OPENAI_API_KEY` and your `TRACELOOP_API_KEY` to run the cell."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = ...\n",
"os.environ[\"TRACELOOP_API_KEY\"] = ..."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[32mTraceloop syncing configuration and prompts\u001b[39m\n",
"\u001b[32mTraceloop exporting traces to https://api.traceloop.com authenticating with bearer token\n",
"\u001b[39m\n"
]
}
],
"source": [
"Traceloop.init()\n",
"\n",
"dr = (\n",
" driver.Builder()\n",
" .with_modules(llm_dataflow)\n",
" .with_adapters(h_opentelemetry.OpenTelemetryTracer())\n",
" .build()\n",
")\n",
"\n",
"# If you wanted to use another OpenTelemetry destination such as the\n",
"# open-source Jaeger, setup the container locally and use the following code\n",
"\n",
"# from opentelemetry import trace\n",
"# from opentelemetry.sdk.trace import TracerProvider\n",
"# from opentelemetry.sdk.trace.export import SimpleSpanProcessor\n",
"# from opentelemetry.exporter.jaeger import JaegerExporter\n",
"\n",
"# jaeger_exporter = JaegerExporter(agent_host_name='localhost', agent_port=5775)\n",
"# span_processor = SimpleSpanProcessor(jaeger_exporter)\n",
"# provider = TracerProvider(active_span_processor=span_processor)\n",
"# trace.set_tracer_provider(provider)\n",
"\n",
"results = dr.execute([\"universal_truth\"])"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"To center an HTML `<div>` element, you can use CSS. There are several methods to achieve this, depending on whether you want to center it horizontally, vertically, or both. Here are a few common methods:\n",
"\n",
"### Centering Horizontally\n",
"\n",
"One of the simplest ways to center a `<div>` horizontally is to set its width, and then use `margin: auto;`. Here's an example:\n",
"\n",
"```html\n",
"<!DOCTYPE html>\n",
"<html lang=\"en\">\n",
"<head>\n",
" <meta charset=\"UTF-8\">\n",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n",
" <title>Center Div</title>\n",
" <style>\n",
" .centered-div {\n",
" width: 50%; /* Set a width */\n",
" margin: 0 auto; /* Center horizontally */\n",
" background-color: lightblue; /* Optional: Background color */\n",
" padding: 20px; /* Optional: Padding */\n",
" text-align: center; /* Optional: Center text */\n",
" }\n",
" </style>\n",
"</head>\n",
"<body>\n",
" <div class=\"centered-div\">\n",
" This div is centered horizontally!\n",
" </div>\n",
"</body>\n",
"</html>\n",
"```\n",
"\n",
"### Centering Vertically and Horizontally\n",
"\n",
"To center a `<div>` both vertically and horizontally, you can use Flexbox or CSS Grid. Here's an example using Flexbox:\n",
"\n",
"```html\n",
"<!DOCTYPE html>\n",
"<html lang=\"en\">\n",
"<head>\n",
" <meta charset=\"UTF-8\">\n",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n",
" <title>Center Div</title>\n",
" <style>\n",
" body {\n",
" display: flex;\n",
" justify-content: center; /* Center horizontally */\n",
" align-items: center; /* Center vertically */\n",
" height: 100vh; /* Full viewport height */\n",
" margin: 0; /* Remove default margin */\n",
" }\n",
"\n",
" .centered-div {\n",
" width: 50%; /* Set a width */\n",
" background-color: lightblue; /* Optional: Background color */\n",
" padding: 20px; /* Optional: Padding */\n",
" text-align: center; /* Optional: Center text */\n",
" }\n",
" </style>\n",
"</head>\n",
"<body>\n",
" <div class=\"centered-div\">\n",
" This div is centered both vertically and horizontally!\n",
" </div>\n",
"</body>\n",
"</html>\n",
"```\n",
"\n",
"### Centering with CSS Grid\n",
"\n",
"Here's another way to center using CSS Grid:\n",
"\n",
"```html\n",
"<!DOCTYPE html>\n",
"<html lang=\"en\">\n",
"<head>\n",
" <meta charset=\"UTF-8\">\n",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n",
" <title>Center Div</title>\n",
" <style>\n",
" body {\n",
" display: grid;\n",
" height: 100vh; /* Full viewport height */\n",
" place-items: center; /* Center both vertically and horizontally */\n",
" margin: 0; /* Remove default margin */\n",
" }\n",
"\n",
" .centered-div {\n",
" width: 50%; /* Set a width */\n",
" background-color: lightblue; /* Optional: Background color */\n",
" padding: 20px; /* Optional: Padding */\n",
" text-align: center; /* Optional: Center text */\n",
" }\n",
" </style>\n",
"</head>\n",
"<body>\n",
" <div class=\"centered-div\">\n",
" This div is centered using CSS Grid!\n",
" </div>\n",
"</body>\n",
"</html>\n",
"```\n",
"\n",
"Choose the method that best fits your layout needs!\n"
]
}
],
"source": [
"print(results[\"universal_truth\"])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv",
"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.11.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}