How to call Open AI's API with F# (GPT-4o)
Date: 2024-08-07 | create | tech | fsharp | ai | open-ai |
AI is becoming an increasingly versatile tool in a developer's toolbelt. I'm currently looking to add some AI-powered features in my own projects I'm building with F# so here I'll share a simple example of integrating an F# script with Open AI's API - targeting the GPT-4o model.
Overview
For this example I'm building a very simple CLI tool. You run it, it makes the call, and outputs its results.
- Program: F# CLI Script
- Runtime: Dotnet 8 in a Docker container
I'm using a very simple prompt to prove this works - asking the AI to output a haiku about F#.
- Prompt: Write a haiku about F#.
- Example Response: Functional whispers, Type safety in gentle breeze, Code flows, clear and free.
Related:
Call Open AI API from F#
We'll be using the Open AI chat completions API (official docs) to give us a response. This is similar to a typical AI chatbot workflow - you give it a prompt, it returns a response.
The script itself is very simple:
- Create an http client with an Auth Bearer token containing our API key
- Build up our request / response data model
- Create and send the request
- Parse the response
Want the full project source code? HAMINIONs members get access to the project's repo including full source code / files.
Code:
open System
open System.Net.Http
open System.Text
open System.Text.Json
printfn "Hello from F#"
let apiKey = "YOUR_API_KEY_HERE"
let apiUrl = "https://api.openai.com/v1/chat/completions"
let client = new HttpClient()
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}")
let prompt = "Write a haiku about F#."
type ChatMessageApiDto =
{
role: string
content: string
}
type ChatRequestApiDto =
{
model: string
messages: ChatMessageApiDto list
}
type ChatResponseChoiceApiDto =
{
message: ChatMessageApiDto
}
type ChatResponseApiDto =
{
choices: ChatResponseChoiceApiDto list
}
let request =
{
model = "gpt-4o-mini"
messages = [
{
role = "user"
content = prompt
}
]
}
(* # Make Request *)
let requestJson =
JsonSerializer.Serialize(request)
printfn "Request: %A" requestJson
let requestContent = new StringContent(requestJson, Encoding.UTF8, "application/json")
let response =
client.PostAsync(apiUrl, requestContent)
|> Async.AwaitTask
|> Async.RunSynchronously
let responseBody =
response.Content.ReadAsStringAsync()
|> Async.AwaitTask
|> Async.RunSynchronously
printfn "ResponseBody: %A" responseBody
let chatResponse = JsonSerializer.Deserialize<ChatResponseApiDto>(responseBody)
printfn "ChatResponse: %A" chatResponse
let generatedText = chatResponse.choices.[0].message.content
printfn "Final response: %s" generatedText
Example Outputs
Here I'll paste some example outputs to give you an idea of what it looks like when it's run:
Request:
{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Write a haiku about F#."}]}
Response:
{
"id": "chatcmpl-9nng4bclVFjOZlKnwQWBDPx8MP4gU",
"object": "chat.completion",
"created": 1721656060,
"model": "gpt-4o-mini-2024-07-18",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Functional whispers, \nTypes and expressions entwined, \nCode flows like clear streams."
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 17,
"total_tokens": 31
},
"system_fingerprint": "fp_661538dc1f"
}
FinalResponse - the F# haiku:
Functional whispers,
Types and expressions entwined,
Code flows like clear streams.
Next
I haven't experimented too much with available AI APIs and what they're capable of but I think there are some fun applications for adding some dynamism to software projects. I'll be doing more experiments in the coming weeks to see what I can build with them so stay tuned if you're interested in that.
Q: What are you using AI for in your dev workflow / projects?
If you liked this post you might also be interested in:
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.