So you want to query an LLM directly
Say you have an app and you want it to make simple queries to an LLM — without spinning up a full-blown agent framework like Claude Code or Gemini CLI. Agents are great, but they can turn a single question into many round-trips, and with token-based pricing that adds up fast.
Below are minimal, self-contained examples for querying Claude, OpenAI, and Gemini across four approaches: raw HTTP (Python and Bash), the provider SDKs (Python and TypeScript), and LangChain for a unified interface across all three.
All examples take the query as a quoted command-line argument and read API keys from the
environment (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY).
Many apps that host local LLM's support the OpenAI REST and SDK interfaces, including Ollama and LM Studio among others.
Python REST
Each example posts directly to the provider's HTTP endpoint using the requests library —
no SDK required.
CLAUDE
import sys
import os
import requests
response = requests.post(
"https://api.anthropic.com/v1/messages",
headers={
"x-api-key": os.environ["ANTHROPIC_API_KEY"],
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
json={
"model": "claude-haiku-4-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": sys.argv[1]}],
},
)
print(response.json()["content"][0]["text"])
OPENAI
import sys
import os
import requests
query = sys.argv[1]
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers={
"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
"Content-Type": "application/json",
},
json={
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": query}],
},
)
print(response.json()["choices"][0]["message"]["content"])
GEMINI
Gemini exposes an OpenAI-compatible endpoint, so you can point the OpenAI client at Gemini's base URL:
import sys
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["GEMINI_API_KEY"],
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
)
# uses the OpenAI-compatible Gemini endpoint
response = client.chat.completions.create(
model="gemini-3.1-flash-lite",
messages=[{"role": "user", "content": sys.argv[1]}],
)
print(response.choices[0].message.content)
Bash REST
The same REST calls via curl, with JSON constructed inline using Python. Useful for shell
scripts that need a quick LLM call with no Python dependencies to install.
CLAUDE
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 \"prompt\"" >&2
exit 1
fi
response=$(curl -sS https://api.anthropic.com/v1/messages \
-H "x-api-key: ${ANTHROPIC_API_KEY:?ANTHROPIC_API_KEY is required}" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d "$(printf '%s' \"$1\" | python -c 'import json,sys; print(json.dumps({"model":"claude-haiku-4-5","max_tokens":1024,"messages":[{"role":"user","content":sys.stdin.read()}]}))')")
printf '%s' "$response" | python -c 'import json,sys; print(json.load(sys.stdin)["content"][0]["text"])'
OPENAI
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 \"prompt\"" >&2
exit 1
fi
response=$(curl -sS https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer ${OPENAI_API_KEY:?OPENAI_API_KEY is required}" \
-H "Content-Type: application/json" \
-d "$(printf '%s' "$1" | python -c 'import json,sys; print(json.dumps({"model":"gpt-4o-mini","messages":[{"role":"user","content":sys.stdin.read()}]}))')")
printf '%s' "$response" | python -c 'import json,sys; print(json.load(sys.stdin)["choices"][0]["message"]["content"])'
GEMINI
Gemini's OpenAI-compatible endpoint works here too — just swap the URL and key.
#!/usr/bin/env bash
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 \"prompt\"" >&2
exit 1
fi
response=$(curl -sS https://generativelanguage.googleapis.com/v1beta/openai/chat/completions \
-H "Authorization: Bearer ${GEMINI_API_KEY:?GEMINI_API_KEY is required}" \
-H "Content-Type: application/json" \
-d "$(printf '%s' \"$1\" | python -c 'import json,sys; print(json.dumps({"model":"gemini-3.1-flash-lite","messages":[{"role":"user","content":sys.stdin.read()}]}))')")
printf '%s' "$response" | python -c 'import json,sys; print(json.load(sys.stdin)["choices"][0]["message"]["content"])'
Python SDK
Using the official provider SDKs gives you typed responses, automatic retries, and cleaner error handling compared to raw HTTP.
CLAUDE
import sys
import os
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
message = client.messages.create(
model="claude-haiku-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": sys.argv[1]}],
)
print(message.content[0].text)
OPENAI
import sys
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": sys.argv[1]}],
)
print(response.choices[0].message.content)
GEMINI
import sys
import os
from google import genai
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
response = client.models.generate_content(
model="gemini-3.1-flash-lite",
contents=sys.argv[1],
)
print(response.text)
LANGCHAIN
LangChain provides a unified interface across all three providers:
import sys
import os
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage
def format_content(content):
if isinstance(content, str):
return content
if isinstance(content, list):
parts = []
for part in content:
if isinstance(part, str):
parts.append(part)
elif isinstance(part, dict) and "text" in part:
parts.append(part["text"])
return "".join(parts)
return str(content)
query = sys.argv[1]
models = [
("OpenAI", ChatOpenAI(model="gpt-4o-mini", api_key=os.environ["OPENAI_API_KEY"])),
("Claude", ChatAnthropic(model="claude-haiku-4-5", api_key=os.environ["ANTHROPIC_API_KEY"])),
("Gemini", ChatGoogleGenerativeAI(model="gemini-3.1-flash-lite", google_api_key=os.environ["GEMINI_API_KEY"])),
]
for name, model in models:
response = model.invoke([HumanMessage(content=query)])
print(f"=== {name} ===")
print(format_content(response.content))
print()
TypeScript SDK
The same SDK calls in TypeScript. Run directly with npx tsx <file>.ts "your query" — no
separate compile step needed.
CLAUDE
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({ apiKey: process.env["ANTHROPIC_API_KEY"] });
async function main(): Promise<void> {
const query = process.argv[2];
if (!query) {
throw new Error('Pass the query as a quoted string, for example: "hello"');
}
const message = await client.messages.create({
model: "claude-haiku-4-5",
max_tokens: 1024,
messages: [{ role: "user", content: query }],
});
const text = message.content
.filter((block) => block.type === "text")
.map((block) => block.text)
.join("\n");
console.log(text);
}
void main();
OPENAI
import OpenAI from "openai";
const client = new OpenAI({ apiKey: process.env["OPENAI_API_KEY"] });
async function main(): Promise<void> {
const query = process.argv[2];
if (!query) {
throw new Error('Pass the query as a quoted string, for example: "hello"');
}
const response = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: query }],
});
console.log(response.choices[0]?.message?.content ?? "");
}
void main();
GEMINI
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({ apiKey: process.env["GEMINI_API_KEY"] });
async function main(): Promise<void> {
const query = process.argv[2];
if (!query) {
throw new Error('Pass the query as a quoted string, for example: "hello"');
}
const response = await client.models.generateContent({
model: "gemini-3.1-flash-lite",
contents: query,
});
console.log(response.text);
}
void main();
LANGCHAIN
LangChain provides a unified interface across all three providers:
import { HumanMessage } from "@langchain/core/messages";
import { ChatAnthropic } from "@langchain/anthropic";
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import { ChatOpenAI } from "@langchain/openai";
function formatContent(content: unknown): string {
if (typeof content === "string") {
return content;
}
if (!Array.isArray(content)) {
return String(content ?? "");
}
return content
.map((part) => {
if (typeof part === "string") {
return part;
}
if (part && typeof part === "object" && "text" in part) {
const text = part.text;
return typeof text === "string" ? text : "";
}
return "";
})
.join("");
}
async function main(): Promise<void> {
const query = process.argv[2];
if (!query) {
throw new Error('Pass the query as a quoted string, for example: "hello"');
}
const models = [
["OpenAI", new ChatOpenAI({ model: "gpt-4o-mini", apiKey: process.env["OPENAI_API_KEY"] })],
["Claude", new ChatAnthropic({ model: "claude-haiku-4-5", apiKey: process.env["ANTHROPIC_API_KEY"] })],
[
"Gemini",
new ChatGoogleGenerativeAI({
model: "gemini-3.1-flash-lite",
apiKey: process.env["GEMINI_API_KEY"],
}),
],
] as const;
for (const [name, model] of models) {
const response = await model.invoke([new HumanMessage(query)]);
console.log(`=== ${name} ===`);
console.log(formatContent(response.content));
console.log();
}
}
void main();