1. 何を作るのか?
本記事では、Claude と OpenAI のチャット API をコマンドラインから呼び出す、シンプルな TypeScript 製ミニ CLI を作ります。
-
node your-cli.ts "質問内容"のように実行すれば、返答が標準出力に表示されます。
初心者でも npm パッケージをインストールし、数行のコードを書くだけで完成します。
2. 必要なツール
| ツール | 用途 |
|---|---|
| Node.js (v18 以上) | 実行環境 |
| npm / yarn | パッケージ管理 |
typescript |
コンパイル |
commander |
CLI パーサ |
node-fetch (or axios) |
HTTP リクエスト |
dotenv |
環境変数管理 |
3. プロジェクトの作り方
# ディレクトリ作成 → 初期化
mkdir ai-cli && cd ai-cli
npm init -y
# 必要パッケージをインストール
npm i commander node-fetch dotenv
npm i -D typescript @types/node @types/commander @types/node-fetch
npx tsc --init
src ディレクトリを作り、index.ts に以下を保存します。
4. コード例
// src/index.ts
import { Command } from "commander";
import fetch from "node-fetch";
import * as dotenv from "dotenv";
dotenv.config();
const program = new Command();
program
.argument("<prompt>", "AI に投げる質問")
.option("-m, --model <model>", "使用するモデル (claude-2 / gpt-4o)", "gpt-4o")
.action(async (prompt, options) => {
const apiKey = process.env.OPENAI_API_KEY || "";
const url =
options.model.startsWith("claude")
? "https://api.anthropic.com/v1/messages"
: "https://api.openai.com/v1/chat/completions";
const body =
options.model.startsWith("claude")
? {
model: options.model,
max_tokens: 1024,
messages: [{ role: "user", content: prompt }],
}
: {
model: options.model,
messages: [{ role: "user", content: prompt }],
max_tokens: 1024,
};
try {
const res = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
...(options.model.startsWith("claude") && {
"x-api-key": apiKey,
"anthropic-version": "2023-06-01",
}),
},
body: JSON.stringify(body),
});
const data = await res.json();
const reply =
options.model.startsWith("claude")
? data.content?.[0]?.text
: data.choices?.[0]?.message?.content;
console.log("\n=== AI の返答 ===\n");
console.log(reply ?? "取得できませんでした");
} catch (e) {
console.error("Error:", e);
}
});
program.parse(process.argv);
ポイント解説
-
モデル選択
-mオプションで Claude か OpenAI のどちらかを指定できます。デフォルトは最新のgpt-4o。 -
環境変数
.envにOPENAI_API_KEY=YOUR_KEYを書くだけで、Claude でも同じキー名で利用できます。 -
リクエスト構造の違い
Claude と OpenAI では JSON の形が若干異なるため、options.modelで分岐しています。
5. ビルドと実行
# TypeScript をコンパイル
npx tsc
# 実行例
node dist/index.js "日本の首都はどこですか?" -m claude-2
6. 次に挑戦したいこと
- ストリーミング応答を取り入れ、リアルタイムで表示する。
- プロンプトテンプレートをファイル化し、複数コマンドで使い回す。
- Docker 化して、どの環境でも同じ CLI が動くようにする。