Skip to content

Commit fe4f92a

Browse files
committed
Instrument Langchain4j AI Services
1 parent 8f864d3 commit fe4f92a

13 files changed

Lines changed: 550 additions & 565 deletions

File tree

build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ dependencies {
9595
testImplementation "dev.langchain4j:langchain4j:${langchainVersion}"
9696
testImplementation "dev.langchain4j:langchain4j-http-client:${langchainVersion}"
9797
testImplementation "dev.langchain4j:langchain4j-open-ai:${langchainVersion}"
98-
99-
implementation 'net.bytebuddy:byte-buddy:1.14.11' // ByteBuddy for LangChain4j tool wrapping
10098
}
10199

102100
/**

examples/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ task runRemoteEval(type: JavaExec) {
159159
}
160160
}
161161

162-
task runLangchain(type: JavaExec) {
162+
task runLangchainSimple(type: JavaExec) {
163163
group = 'Braintrust SDK Examples'
164164
description = 'Run the LangChain4j instrumentation example. NOTE: this requires OPENAI_API_KEY to be exported and will make a small call to openai, using your tokens'
165165
classpath = sourceSets.main.runtimeClasspath
166-
mainClass = 'dev.braintrust.examples.LangchainExample'
166+
mainClass = 'dev.braintrust.examples.LangchainSimpleExample'
167167
systemProperty 'org.slf4j.simpleLogger.log.dev.braintrust', braintrustLogLevel
168168
debugOptions {
169169
enabled = true
@@ -173,11 +173,11 @@ task runLangchain(type: JavaExec) {
173173
}
174174
}
175175

176-
task runLangchainToolWrapping(type: JavaExec) {
176+
task runLangchainAIServices(type: JavaExec) {
177177
group = 'Braintrust SDK Examples'
178-
description = 'Run the LangChain4j tool wrapping example. NOTE: this requires OPENAI_API_KEY to be exported and will make a small call to openai, using your tokens'
178+
description = 'Run the LangChain4j AI Services example. NOTE: this requires OPENAI_API_KEY to be exported and will make a small call to openai, using your tokens'
179179
classpath = sourceSets.main.runtimeClasspath
180-
mainClass = 'dev.braintrust.examples.LangchainToolWrappingExample'
180+
mainClass = 'dev.braintrust.examples.LangchainAIServicesExample'
181181
systemProperty 'org.slf4j.simpleLogger.log.dev.braintrust', braintrustLogLevel
182182
debugOptions {
183183
enabled = true
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package dev.braintrust.examples;
2+
3+
import dev.braintrust.Braintrust;
4+
import dev.braintrust.instrumentation.langchain.BraintrustLangchain;
5+
import dev.langchain4j.agent.tool.Tool;
6+
import dev.langchain4j.model.openai.OpenAiChatModel;
7+
import dev.langchain4j.service.AiServices;
8+
9+
public class LangchainAIServicesExample {
10+
11+
public static void main(String[] args) throws Exception {
12+
var braintrust = Braintrust.get();
13+
var openTelemetry = braintrust.openTelemetryCreate();
14+
15+
Assistant assistant =
16+
BraintrustLangchain.wrap(
17+
openTelemetry,
18+
AiServices.builder(Assistant.class)
19+
.chatModel(
20+
OpenAiChatModel.builder()
21+
.apiKey(System.getenv("OPENAI_API_KEY"))
22+
.modelName("gpt-4o-mini")
23+
.temperature(0.0)
24+
.build())
25+
.tools(new WeatherTools())
26+
.executeToolsConcurrently());
27+
28+
var rootSpan =
29+
openTelemetry
30+
.getTracer("my-instrumentation")
31+
.spanBuilder("langchain4j-ai-services-example")
32+
.startSpan();
33+
try (var ignored = rootSpan.makeCurrent()) {
34+
// response 1 should do a concurrent tool call
35+
var response1 = assistant.chat("is it hotter in Paris or New York right now?");
36+
System.out.println("response1: " + response1);
37+
var response2 = assistant.chat("what's the five day forecast for San Francisco?");
38+
System.out.println("response2: " + response2);
39+
} finally {
40+
rootSpan.end();
41+
}
42+
var url =
43+
braintrust.projectUri()
44+
+ "/logs?r=%s&s=%s"
45+
.formatted(
46+
rootSpan.getSpanContext().getTraceId(),
47+
rootSpan.getSpanContext().getSpanId());
48+
System.out.println(
49+
"\n\n Example complete! View your data in Braintrust: %s\n".formatted(url));
50+
}
51+
52+
/** AI Service interface for the assistant */
53+
interface Assistant {
54+
String chat(String userMessage);
55+
}
56+
57+
/** Example tool class with weather-related methods */
58+
public static class WeatherTools {
59+
@Tool("Get current weather for a location")
60+
public String getWeather(String location) {
61+
return String.format("The weather in %s is sunny with 72°F temperature.", location);
62+
}
63+
64+
@Tool("Get weather forecast for next N days")
65+
public String getForecast(String location, int days) {
66+
return String.format(
67+
"The %d-day forecast for %s: Mostly sunny with temperatures between 65-75°F.",
68+
days, location);
69+
}
70+
}
71+
}

examples/src/main/java/dev/braintrust/examples/LangchainExample.java renamed to examples/src/main/java/dev/braintrust/examples/LangchainSimpleExample.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import dev.braintrust.Braintrust;
44
import dev.braintrust.instrumentation.langchain.BraintrustLangchain;
5+
import dev.langchain4j.agent.tool.Tool;
56
import dev.langchain4j.data.message.UserMessage;
67
import dev.langchain4j.model.chat.ChatModel;
78
import dev.langchain4j.model.openai.OpenAiChatModel;
89

910
/** Basic OTel + LangChain4j instrumentation example */
10-
public class LangchainExample {
11+
public class LangchainSimpleExample {
1112

1213
public static void main(String[] args) throws Exception {
1314
if (null == System.getenv("OPENAI_API_KEY")) {
@@ -31,7 +32,7 @@ public static void main(String[] args) throws Exception {
3132
.spanBuilder("langchain4j-instrumentation-example")
3233
.startSpan();
3334
try (var ignored = rootSpan.makeCurrent()) {
34-
chatExample(model);
35+
simpleChatExample(model);
3536
} finally {
3637
rootSpan.end();
3738
}
@@ -45,10 +46,23 @@ public static void main(String[] args) throws Exception {
4546
"\n\n Example complete! View your data in Braintrust: %s\n".formatted(url));
4647
}
4748

48-
private static void chatExample(ChatModel model) {
49-
var message = UserMessage.from("What is the capital of France?");
50-
var response = model.chat(message);
49+
private static void simpleChatExample(ChatModel model) {
50+
var response = model.chat(UserMessage.from("What is the capital of France?"));
5151
System.out.println(
5252
"\n~~~ LANGCHAIN4J CHAT RESPONSE: %s\n".formatted(response.aiMessage().text()));
5353
}
54+
55+
public static class WeatherTools {
56+
@Tool("Get current weather for a location")
57+
public String getWeather(String location) {
58+
return String.format("The weather in %s is sunny with 72°F temperature.", location);
59+
}
60+
61+
@Tool("Get weather forecast for next N days")
62+
public String getForecast(String location, int days) {
63+
return String.format(
64+
"The %d-day forecast for %s: Mostly sunny with temperatures between 65-75°F.",
65+
days, location);
66+
}
67+
}
5468
}

examples/src/main/java/dev/braintrust/examples/LangchainToolWrappingExample.java

Lines changed: 0 additions & 158 deletions
This file was deleted.

0 commit comments

Comments
 (0)