Getting Started
Prerequisites
- Julia 1.12+ (as specified in
Project.toml) - An API key for your chosen provider (OpenAI, DeepSeek, Gemini, Mistral, etc.) — or none at all for local providers like Ollama
Installation
UniLM is registered in Julia's General registry:
using Pkg
Pkg.add("UniLM")Or from the Pkg REPL:
pkg> add UniLMTo track the latest unreleased changes, install from GitHub instead:
Pkg.add(url="https://github.com/algunion/UniLM.jl")Configuration
UniLM.jl reads API credentials from environment variables. Set them before making any requests:
OpenAI (default)
ENV["OPENAI_API_KEY"] = "sk-..."Or via your shell:
export OPENAI_API_KEY="sk-..."Azure OpenAI
export AZURE_OPENAI_BASE_URL="https://your-resource.openai.azure.com"
export AZURE_OPENAI_API_KEY="your-key"
export AZURE_OPENAI_API_VERSION="2024-02-01"
export AZURE_OPENAI_DEPLOY_NAME_GPT_5_2="your-gpt52-deployment"Google Gemini
Native generateContent API (default model gemini-3.8-flash):
export GEMINI_API_KEY="your-gemini-key"Anthropic (Claude)
Native Messages API (default model claude-opus-4-8):
export ANTHROPIC_API_KEY="sk-ant-..."DeepSeek
export DEEPSEEK_API_KEY="sk-..."Ollama (local — no key needed)
Just have the Ollama server running on localhost:11434. No API key required.
Hosted API calls cost money and need a funded key. To experiment with zero cost and no signup, run a local model with Ollama — set service=OllamaEndpoint() (no key required), as configured above.
Your First Request
Using the Responses API
The simplest way to get started — one function call:
result = respond("Explain Julia's type system in 3 bullet points", model="gpt-5.4-mini")
if result isa ResponseSuccess
println(output_text(result))
else
println("Request failed — ", output_text(result))
endRequest failed — Error: KeyError: key "OPENAI_API_KEY" not foundUsing Chat Completions
For stateful, multi-turn conversations:
chat = Chat(model="gpt-5.4-mini")
push!(chat, Message(Val(:system), "You are a concise Julia programming tutor."))
push!(chat, Message(Val(:user), "What is multiple dispatch? Answer in 2-3 sentences."))
result = chatrequest!(chat)
if result isa LLMSuccess
println(result.message.content)
println("\nFinish reason: ", result.message.finish_reason)
println("Conversation length: ", length(chat))
else
println("Request failed — see result for details")
endRequest failed — see result for detailsGenerating Images
result = generate_image(
"A watercolor painting of a friendly robot reading a Julia programming book",
size="1024x1024", quality="medium"
)
if result isa ImageSuccess
println("Success: true")
println("Images: ", length(image_data(result)))
else
println("Success: false")
println("Images: 0")
endUsing Keyword Arguments
For one-shot requests without managing Chat objects:
result = chatrequest!(
systemprompt="You are a calculator. Respond only with the number.",
userprompt="What is 42 * 17?",
model="gpt-5.4-mini",
temperature=0.0
)
if result isa LLMSuccess
println(result.message.content)
else
println("Request failed — see result for details")
endRequest failed — see result for detailsHandling Results
All API calls return subtypes of LLMRequestResponse. Use Julia's pattern matching:
using UniLM
using InteractiveUtils
# Construct a chat to show the result type hierarchy
chat = Chat(model="gpt-5.4-mini")
push!(chat, Message(Val(:system), "You are helpful."))
push!(chat, Message(Val(:user), "Hello!"))
# Show the type hierarchy:
println("LLMRequestResponse subtypes:")
for T in subtypes(UniLM.LLMRequestResponse)
println(" ", T)
endLLMRequestResponse subtypes:
AudioCallError
AudioFailure
BatchCallError
BatchFailure
BatchListSuccess
BatchSuccess
ContainerCallError
ContainerDeleteSuccess
ContainerFailure
ContainerListSuccess
ContainerSuccess
ConversationCallError
ConversationDeleteSuccess
ConversationFailure
ConversationItemListSuccess
ConversationItemSuccess
ConversationSuccess
EmbeddingCallError
EmbeddingFailure
EmbeddingSuccess
FIMCallError
FIMFailure
FIMSuccess
FileCallError
FileContentSuccess
FileDeleteSuccess
FileFailure
FileListSuccess
FileSuccess
FineTuningCallError
FineTuningFailure
FineTuningListSuccess
FineTuningSuccess
ImageCallError
ImageFailure
ImageSuccess
LLMCallError
LLMFailure
LLMSuccess
ModerationCallError
ModerationFailure
ModerationSuccess
RealtimeCallError
RealtimeFailure
RealtimeSecretSuccess
ResponseCallError
ResponseFailure
ResponseSuccess
SpeechSuccess
TranscriptionSuccess
UploadCallError
UploadFailure
UploadPartSuccess
UploadSuccess
VectorStoreBatchSuccess
VectorStoreCallError
VectorStoreDeleteSuccess
VectorStoreFailure
VectorStoreFileSuccess
VectorStoreListSuccess
VectorStoreSuccess
VideoCallError
VideoContentSuccess
VideoFailure
VideoListSuccess
VideoSuccessresult = chatrequest!(chat)
if result isa LLMSuccess
println("Assistant: ", result.message.content)
println("Finish reason: ", result.message.finish_reason)
elseif result isa LLMFailure
@warn "API returned HTTP $(result.status): $(result.response)"
elseif result isa LLMCallError
@error "Call failed: $(result.error)"
end┌ Error: Call failed: KeyError: key "OPENAI_API_KEY" not found
└ @ Main getting_started.md:187For the Responses API:
result = respond("Hello!", model="gpt-5.4-mini")
if result isa ResponseSuccess
println(output_text(result))
println("Status: ", result.response.status)
println("Model: ", result.response.model)
elseif result isa ResponseFailure
@warn "HTTP $(result.status)"
elseif result isa ResponseCallError
@error result.error
end┌ Error: KeyError: key "OPENAI_API_KEY" not found
└ @ Main getting_started.md:203What's Next?
| Want to... | Read... |
|---|---|
| Build multi-turn conversations | Chat Completions Guide |
| Use the newer Responses API | Responses API Guide |
| Generate images from prompts | Image Generation Guide |
| Call functions from the model | Tool Calling Guide |
| Stream tokens in real-time | Streaming Guide |
| Get structured JSON output | Structured Output Guide |
| Use any provider | Multi-Backend Guide |
| Track token usage & cost | Cost Tracking Guide |
| Ground answers in your files | Retrieval & File Search |
| Bound timeouts, retries, fan-out | Timeouts & Retries |