Send your first prompt
This guide takes you from an empty project to a working LLM call in each of the six SDKs. The shape is identical everywhere: construct a provider-bound client, chain the text builder with a model and a prompt, read the reply off the response.
Before you start
Set the API key for the provider you want to call. The keys are read from the environment:
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
export GOOGLE_API_KEY="..."
The examples below call Anthropic with claude-opus-4-7. Swap the
builder (anthropic -> openai, google, …) and the model string to
target a different provider — the call surface does not change.
Go
package main
import (
"context"
"fmt"
"log"
"os"
llmkit "github.com/aktagon/llmkit-go/v2"
)
func main() {
c := llmkit.New("anthropic", os.Getenv("ANTHROPIC_API_KEY"))
resp, err := c.Text.
Model("claude-opus-4-7").
Prompt(context.Background(), "Explain prompt caching in two sentences.")
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Text)
fmt.Printf("tokens: in=%d out=%d\n", resp.Usage.Input, resp.Usage.Output)
}c.Text is a field on *Client, not a method call. Chain methods clone
the prototype and return a fresh builder.
TypeScript
import { anthropic } from "@aktagon/llmkit-ts/builders";
const c = anthropic(process.env.ANTHROPIC_API_KEY!);
const resp = await c.text
.model("claude-opus-4-7")
.prompt("Explain prompt caching in two sentences.");
console.log(resp.text);
console.log(`tokens: in=${resp.usage.input} out=${resp.usage.output}`);Python
import os
import asyncio
from llmkit.builders import anthropic
async def main():
c = anthropic(os.environ["ANTHROPIC_API_KEY"])
resp = await (
c.text
.model("claude-opus-4-7")
.prompt("Explain prompt caching in two sentences.")
)
print(resp.text)
print(f"tokens: in={resp.usage.input} out={resp.usage.output}")
asyncio.run(main())Rust
use llmkit::builders::anthropic;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let c = anthropic(std::env::var("ANTHROPIC_API_KEY")?);
let resp = c
.text()
.model("claude-opus-4-7")
.prompt("Explain prompt caching in two sentences.")
.await?;
println!("{}", resp.text);
println!("tokens: in={} out={}", resp.usage.input, resp.usage.output);
Ok(())
}Swift
import Foundation
import LLMKit
let key = ProcessInfo.processInfo.environment["ANTHROPIC_API_KEY"] ?? ""
let client = Client(provider: .anthropic, apiKey: key)
let resp = try await client.text
.model("claude-opus-4-7")
.prompt("Explain prompt caching in two sentences.")
print(resp.text)
print("tokens: in=\(resp.usage.input) out=\(resp.usage.output)")Java
import com.aktagon.llmkit.Client;
import com.aktagon.llmkit.providers.generated.ProviderName;
import com.aktagon.llmkit.providers.generated.Response;
public class Quickstart {
public static void main(String[] args) {
Client client = new Client(ProviderName.ANTHROPIC, System.getenv("ANTHROPIC_API_KEY"));
Response resp = client.text()
.model("claude-opus-4-7")
.prompt("Explain prompt caching in two sentences.");
System.out.println(resp.text());
System.out.println("tokens: in=" + resp.usage().input() + " out=" + resp.usage().output());
}
}Note Rust and Java reach the text builder as a method (c.text() /
client.text()), where Go, TypeScript, Python, and Swift expose it as a
field or property. Swift and Java construct the client with a provider
value (Client(provider: .anthropic, apiKey: key) /
new Client(ProviderName.ANTHROPIC, key)) instead of a per-provider
builder function.
What to read next
- Each SDK’s
README.mddocuments the full call surface — streaming, tool-calling, caching, batches, and image/video/music generation. docs/runbooks/001-deploy-the-llmkit-site.md(RUN-001) covers cutting and publishing a release once your change lands.