Log to Freeplay
To start logging data to Freeplay, integrate our logging into your code, providing key insights into how your LLM application is performing.
Logging Data to Freeplay (SDK)
1. Configure the Freeplay Client
from freeplay import Freeplay, RecordPayload, ResponseInfo, CallInfo
import os
from openai import OpenAI
# create a freeplay client object
fpClient = Freeplay(
freeplay_api_key=os.getenv("FREEPLAY_API_KEY"),
api_base=freeplay_api_base,
)
import Freeplay from "freeplay";
// create your freeplay client
const fpClient = new Freeplay({
freeplayApiKey: process.env["FREEPLAY_KEY"],
baseUrl: "https://acme.freeplay.ai/api",
});
import ai.freeplay.client.thin.Freeplay;
String projectId = System.getenv("FREEPLAY_PROJECT_ID");
String customerDomain = System.getenv("FREEPLAY_CUSTOMER_NAME");
Freeplay fpClient = new Freeplay(Config()
.freeplayAPIKey(freeplayApiKey)
.customerDomain(customerDomain)
);
// create the freeplay client
val fpClient = Freeplay(
Freeplay.Config()
.freeplayAPIKey(freeplayApiKey)
.customerDomain(customerDomain)
)
2. Retrieve and format your Prompt
Freeplay manages and versions your prompts for you and allows you to retrieve prompts formatted for your specified LLM provider.
from freeplay import Freeplay, RecordPayload, ResponseInfo
import os
from openai import OpenAI
from vectorSearch import vector_search
# retreive and format your prompt
user_question = "What is Freeplay?"
prompt_vars = {"question": user_question, "supporting_information": vector_search(user_question)}
formatted_prompt = fpClient.prompts.get_formatted(project_id=os.getenv("FREEPLAY_PROJECT_ID"),
template_name="rag-qa",
environment="latest",
variables=prompt_vars)
// set the prompt variables
let userQuestion = "What is freeplay?"
let promptVars = {"question": userQuestion, "supporting_information": vectorSearch(userQuestion)};
// fetch a formatted prompt template
let formattedPrompt = await fpClient.prompts.getFormatted({
projectId: projectID,
templateName: "rag-qa",
environment: "latest",
variables: promptVars,
});
// set the prompt variables
val promptVars = mapOf("question" to "What is Freeplay?")
/* PROMPT FETCH */
val formattedPrompt = fpClient.prompts().getFormatted<String>(
projectId,
"rag-qa",
"latest",
promptVars
).await()
3. Make an LLM request using your chosen provider
Freeplay allows you to execute your own LLM calls for optimal flexibility and minimized latency.
from freeplay import Freeplay, RecordPayload, ResponseInfo
import os
import time
from openai import OpenAI
# make your llm call
start = time.time() # used to keep track of latency
openaiClient = OpenAI(api_key=openai_key)
chat_response = openaiClient.chat.completions.create(
model=formatted_prompt.prompt_info.model, # model is specified in the freeplay prompt info
messages=formatted_prompt.messages, # formatted messages based on your inserted variables and specified provider
**formatted_prompt.prompt_info.model_parameters # model parameters assocated with your prompt (ie max_tokens, temperature)
)
end = time.time()
# add the LLM responses to your messages
all_messages = formatted_prompt.all_messages(
{'role': chat_response.choices[0].message.role,
'content': chat_response.choices[0].message.content}
)
import OpenAI from "openai";
const openai = new OpenAI(process.env["OPENAI_API_KEY"]);
let start = new Date();
const chatCompletion = await openai.chat.completions.create({
messages: formattedPrompt.messages,
model: formattedPrompt.promptInfo.model,
});
let end = new Date();
console.log(chatCompletion.choices[0].message);
// update the messages
let messages = formattedPrompt.allMessages({
role: chatCompletion.choices[0].message.role,
content: chatCompletion.choices[0].message.content,
});
/* LLM CALL */
// set timer to measure latency
val startTime = System.currentTimeMillis()
val llmResponse = callOpenAI(
objectMapper,
openaiApiKey,
formattedPrompt.promptInfo.model, // get the model name
formattedPrompt.promptInfo.modelParameters, // get the model params
formattedPrompt.getBoundMessages()
).await()
val endTime = System.currentTimeMillis()
// add the LLM response to the message set
val bodyNode = objectMapper.readTree(llmResponse.body())
val role = bodyNode.path("choices").path(0).path("message").path("role").asText()
val content = bodyNode.path("choices").path(0).path("message").path("content").asText()
println("Completion: " + content)
val allMessage: List<ChatMessage> = formattedPrompt.allMessages(
ChatMessage(role, content)
)
4. Log your LLM call with Freeplay
Freeplay allows you to asynchronously log your LLM call to minimize customer latency and remove ourselves from your critical path.
# create a Freeplay session
session = fpClient.sessions.create()
# record your LLM call with Freeplay
payload = RecordPayload(
project_id=project_id
all_messages=all_messages,
inputs=prompt_vars,
session_info=session,
prompt_version_info=formatted_prompt.prompt_info,
call_info=CallInfo.from_prompt_info(formatted_prompt.prompt_info, start_time=start, end_time=end),
response_info=ResponseInfo(
is_complete=chat_response.choices[0].finish_reason == 'stop'
)
)
fpClient.recordings.create(payload)
// create a session
let session = fpClient.sessions.create({});
// record the LLM interaction with Freeplay
await fpClient.recordings.create({
projectId,
allMessages: messages,
inputs: promptVars,
sessionInfo: getSessionInfo(session),
promptVersionInfo: formattedPrompt.promptInfo,
callInfo: getCallInfo(formattedPrompt.promptInfo, start, end),
responseInfo: {
isComplete: "stop_sequence" === chatCompletion.choices[0].stop
}
});
/* RECORD */
// construct the call info from the prompt object
val callInfo = CallInfo.from(
formattedPrompt.getPromptInfo(),
startTime,
endTime
)
// create the response info
val responseInfo = ResponseInfo("stop_sequence" == bodyNode.path("stop_reason").asText())
// create the session and get the session info
val sessionInfo = fpClient.sessions().create().sessionInfo
// build the final record payload
val recordResponse = fpClient.recordings().create(
new RecordInfo(
projectId,
allMessages
).inputs(variables)
.sessionInfo(sessionInfo)
.promptVersionInfo(formattedPrompt.getPromptInfo())
.callInfo(callInfo)
.responseInfo(responseInfo));
/* RECORD */
// construct the call info from the prompt object
val callInfo = CallInfo.from(
formattedPrompt.getPromptInfo(),
startTime,
endTime
)
// create the response info
val responseInfo = ResponseInfo("stop_sequence" == bodyNode.path("stop_reason").asText())
// create the session and get the session info
val sessionInfo = fpClient.sessions().create().sessionInfo
// build the final record payload
val recordResponse = fpClient.recordings().create(
RecordInfo(
projectId,
allMessages
).inputs(variables)
.sessionInfo(session.sessionInfo)
.promptVersionInfo(prompt.promptInfo)
.callInfo(callInfo)
.responseInfo(responseInfo)
.traceInfo(trace)
).await()
This is just the start of what the Freeplay SDK enables. See the full docs here
Updated about 24 hours ago