
この記事はラクス Advent Calendar 2025 1日目の記事です。
はじめに
こんにちは! エンジニア3年目のTKDSです! 今回はCodex CLI SDKの入門記事を書きました! Codex CLI SDKはChatGPTの有料プランに契約していれば、特に追加費用不要で使用可能です。 そのため、さくっとMy AIエージェントを作るのには非常におすすめです。 では早速本題に入っていきたいと思います。
Codex CLIの概要
Codex CLI is a coding agent from OpenAI that runs locally on your computer. 翻訳:OpenAIが提供するローカルコンピュータ上で動作するコーディングエージェント.
Codex CLIはOpenAIの提供するモデルが使えるコーディングエージェントです。
Codex CLI SDKについて
codex exec相当の処理をTypeScript(JavaScript)コード上から実行できるSDKです。
プログラムから使えるので、処理の流れを書きやすくなったり、TS(JS)ライブラリの使用・連携ができます。
今回このSDKを使ってエージェントを作ってみます。
環境情報
nodeは24.11.1を使いました。
$ node --version v24.11.1
codex、codex-sdkとmodelcontextprotocol/sdkを使いました。
細かいところはリポジトリみてください。
mise install node@24.11.1 mise use -g node@24.11.1 npm i -g @openai/codex npm install @openai/codex-sdk npm install @modelcontextprotocol/sdk
codexの設定は以下のようにしておきます。
今回用に余計なMCP設定は消してます。
[sandbox_workspace_write] network_access = true # 機能フラグ [features] web_search_request = true
事前にcodex loginしておいてください。
基本的な操作
// QuickStartにあるコード参考にしたコード import { Codex } from "@openai/codex-sdk"; const codex = new Codex(); const thread = codex.startThread(); const turn = await thread.run("東京の今日の天気は?"); console.log(turn.finalResponse); console.log(turn.items);
codexの操作関連について軽く解説します。
- Codexとのやり取りをするオブジェクトを作成します
new Codex()
- 1セッションを開始するのに相当する操作です
codex.startThread()
- メッセージの送信操作です、これを繰り返すと同じセッションにメッセージを送信し続けられます
thread.run()
逐次的にレスポンスを受け取りたい場合はこちらを使います。
codex.runStreamed()
runStreamedを使う場合、サンプルコードにあるようにawaitを使って非同期処理にすると良さそうです。
const { events } = await thread.runStreamed("Diagnose the test failure and propose a fix"); for await (const event of events) { switch (event.type) { case "item.completed": console.log("item", event.item); break; case "turn.completed": console.log("usage", event.usage); break; } }
お天気エージェントを題材にした解説
基本的な操作は説明したので、次にお天気エージェントを題材に実際にCodex CLI SDKを使ってみます。
追加のOpenAI API Keyの設定などは不要です。
codex loginだけできてるか確認しておいてください。
シンプルなエージェント
まずは単純にcodex cliをSDK経由で呼び出すエージェントを作ってみましょう。
シンプルにスレッドで天気を聞くだけです。
import { Codex } from "@openai/codex-sdk"; const codex = new Codex(); const thread = codex.startThread(); const turn = await thread.run("今日の東京の天気は?"); console.log(turn.finalResponse)
何回か呼んでみると回答はぶれるものの大体ほしい回答を返してくれます。
$ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts **東京の天気 (2025年11月23日)** - 現在: 快晴で約11 °C。冷え込む朝なので薄手のコートやニットが安心。 - 朝~昼: 07時頃10 °C→正午前後で17 °C近くまで上昇。日中は日差しがあり比較的穏やか。 - 夜: 深夜に向けて再び10 °C前後まで下がる見込み。帰宅が遅くなるなら上着を忘れずに。 $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts **東京の天気** - 現地時間2025年11月23日(日)の東京は晴れて気温11 °C前後。日中は次第に雲が増え、最高15 °C、最低9 °Cの予想です。 - 11月24日(月)は最高18 °C/最低9 °Cで晴れ間が広がり過ごしやすい見込み。 - 11月25日(火)は雲が多めで最高15 °C/最低9 °C、26日(水)は午後に風が強まるものの晴れて18 °Cまで上がる予報です。 $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts 2025年11月23日現在の東京は快晴で、気温はおよそ11°C(51°F)です。 未明から早朝にかけては晴天が続き、気温は9~11°C程度まで下がる見込みです。 午前になると晴れをキープしつつ徐々に気温が上がり、正午前後には16~17°C付近まで昇る予報です。
ただ回答形式がブレブレなので、適当にシステムプロンプト作って添付してみましょう。プロンプトはChatGPTでさくっと作ったのをベースに結構いじりました。
コツはoutput_templateを最後に持ってくることです。
user_inputが最後になると出力形式がどうしても安定せず思い通りの出力が得られないことが多いです(体感7割失敗)。
import { Codex } from "@openai/codex-sdk"; const codex = new Codex(); const thread = codex.startThread(); const system_prompt = ` <system-prompt> # システムプロンプト あなたは天気情報専用アシスタントです。 - 常に「いつ・どこ・どんな天気か」を明示して、簡潔な日本語で答えます。 - 最新かつ信頼できる情報に基づき、不確実な点はその旨を明示します。 - 危険な気象では、公式機関の情報確認と安全への注意を必ず促します。 - 天気と無関係な質問には、天気専門であることを伝えて簡潔に断ります。 # 調査内容 1. 詳細 * 降水: 降水確率 {{降水確率}}%、予想降水量 {{降水量}}mm(あれば) * 風: 風向 {{風向}}、風速 {{風速}}m/s(強風時はその旨) * 湿度・体感: 湿度 {{湿度}}% 程度、{{蒸し暑く感じる/乾燥しやすい/体感は気温どおり}} 2. 行動の目安 * 服装: {{長袖/半袖/上着の有無などの簡単な目安}} * 持ち物: {{折りたたみ傘/日傘/帽子/飲み物/防寒具 など}} 3. 注意事項 * {{大雨/雷/強風/猛暑/大雪 など}} のおそれ: {{あり/なし}} * 必要に応じて: 「最新の警報・注意報は気象庁など公式情報を確認してください」 * 時刻はJSTを基準に調査 4. 補足(任意) * 洗濯・外出・運転などの簡単な一言アドバイス: {{例: 洗濯物は外干しで問題なさそうです など}} </system-prompt> ` const output_template = ` ユーザーへの回答には参考リンクなどは不要です。 # 出力テンプレート <output_template> * 日時: {{日付・時間帯}} * 地域: {{地域名}} * 天気: {{天気の要約}}(例: 晴れ時々くもり、にわか雨の可能性あり) * 最高/最低気温: {{最高気温}}℃ / {{最低気温}}℃ * 服装等のアドバイス: {{行動のアドバイス}} </output_template> <output_template_error> 天気専門なので答えられません </output_template_error> # 作業手順 1. <user_input>が天気についてか判断し、違った場合<output_template_error>を出力して終了。天気についての場合2へ遷移 2. お天気エージェントとして動作。作業が完了したら3へ遷移 3. output_templateに従って回答 promptにしたがって、作業してください。 ` // const user_input = "今日の東京の天気を教えて" const user_input = "一発芸して" const prompt = [system_prompt, "<user-input>",user_input,"</user-input>",output_template] const turn = await thread.run(prompt.join()); console.log(turn.finalResponse)
何回か試してみます。
$ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts * 日時: 2025-11-23(日) 終日(JST) * 地域: 東京都心 * 天気: 日中は晴れて夕方以降ゆっくり雲が広がる見込み。降水確率や降水量の公式値は未取得ですが現状は雨要素なしと見られます。風は弱い北寄りと推定、湿度も大きく変化せず体感は気温どおり * 最高/最低気温: 15℃ / 9℃ * 服装等のアドバイス: 長袖+薄手の上着で快適、朝晩は冷え込むため軽いコートがあると安心。日中は乾きやすいので飲み物でこまめに保湿。大きな荒天リスクはありませんが最新の警報・注意報は気象庁などでご確認ください $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts * 日時: 2025年11月23日(日) 日中~夜(JST) * 地域: 東京都心 * 天気: 午前は穏やかな晴れ、午後は雲が増える見通しで大きな崩れは今のところ見込まれていません;降水確率・降水量、風向・風速、湿度の詳細は今回取得できなかったため、必要に応じて最新の公式情報を必ずご確認ください。 * 最高/最低気温: 15℃ / 9℃(日中も空気はひんやりで体感は気温どおり) * 服装等のアドバイス: 朝晩は冷えるので薄手ニット+コートなど長袖の重ね着が安心、日中も羽織り物を携帯すると快適;雨具は不要そうですが念のため折りたたみ傘の最新情報をチェックしてください。 $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts * 日時: 2025-11-23(日) 日中(JST) * 地域: 東京都心 * 天気: 午前は快晴、午後は次第に薄雲が広がる見込み。降水: 降水確率データは取得できず、現状では雨の兆候なし・降水量情報なし。風: 風向風速データ未取得(体感的には穏やかな北寄りの風程度)。湿度・体感: データ不足だが朝はひんやり、日中は気温どおりのさわやかな体感になりそう。大きな警報級の現象は見込まれていませんが、念のため最新の注意報は気象庁公式で確認してください。 * 最高/最低気温: 15℃ / 9℃ * 服装等のアドバイス: 朝晩は冷えるので長袖+薄手アウター、日中はカットソー+カーディガン程度が快適。乾燥が進みやすいのでリップやハンドクリームと飲み物を持つと安心、日中の強い日差し対策に帽子もあると良いでしょう。
回答形式も安定し、良くなりました。
コメントアウトしてる部分を外して実行してみましょう
// const user_input = "今日の東京の天気を教えて" const user_input = "一発芸して"
$ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts 天気専門なので答えられません $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts 天気専門なので答えられません
しっかり断りを伝えられました。
ただ、実は問題点が残っており、記事執筆時、11/24(月)1:20なのですが、11/23(日)なってしまってます。これを修正してみましょう。
日付を作成して追加します。ついでに次の日の情報を聞くようにしましょう。
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
// 現在時刻から 1 日後の日時
const tomorrow = new Date(Date.now() + ONE_DAY_MS);
// JST として日付部分だけを文字列にする
const time_pormpt = tomorrow.toLocaleDateString('ja-JP', {
timeZone: 'Asia/Tokyo',
year: 'numeric',
month: '2-digit',
day: '2-digit',
});
const prompt = [system_prompt, "<user-input>",time_pormpt,user_input,"</user-input>",output_template]
結果は以下のようになりました。
概ね思い通りの出力ができてます。
$ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts * 日時: 2025年11月25日(終日・JST) * 地域: 東京都心 * 天気: 明け方は9℃前後で晴れ、午前から午後はおおむねくもり、夕方以降は再び晴れ間が広がる見込み。提供データに降水確率・風向風速・湿度は含まれていませんが、雨要素は示されていません。 * 最高/最低気温: 15℃ / 9℃ * 服装等のアドバイス: 朝晩は冷えるので長袖+薄手アウターが安心、日中は薄手ニット程度で快適。折りたたみ傘は不要そうですが、公式の最新情報も念のためご確認ください。 $ npm run dev > codex-cli-sdk@1.0.0 dev > tsx src/index.ts * 日時: 2025/11/25(火) 0:00-24:00 JST * 地域: 東京都心 * 天気: 夜明けは晴れ、日中はくもり優勢で雨シグナルなし(降水確率データ未取得・不確実)/風は北寄りの弱風が中心で体感は気温どおり/湿度データ未取得 * 最高/最低気温: 15℃ / 9℃ * 服装等のアドバイス: 朝晩は薄手のコートやカーディガンがあると安心、日中は長袖シャツで十分/乾燥しやすいのでリップやハンドクリームと飲み物を 降水量の具体値や湿度は取得できませんでしたが、現状は大きな雨雲の兆候は見当たりません。強い気象リスクの情報はありませんが、最新の警報・注意報は気象庁など公式情報でご確認ください。
最終版
import { Codex } from "@openai/codex-sdk"; const codex = new Codex(); const thread = codex.startThread(); const system_prompt = ` <system-prompt> # システムプロンプト あなたは天気情報専用アシスタントです。 - 常に「いつ・どこ・どんな天気か」を明示して、簡潔な日本語で答えます。 - 最新かつ信頼できる情報に基づき、不確実な点はその旨を明示します。 - 危険な気象では、公式機関の情報確認と安全への注意を必ず促します。 - 天気と無関係な質問には、天気専門であることを伝えて簡潔に断ります。 # 調査内容 1. 詳細 * 降水: 降水確率 {{降水確率}}%、予想降水量 {{降水量}}mm(あれば) * 風: 風向 {{風向}}、風速 {{風速}}m/s(強風時はその旨) * 湿度・体感: 湿度 {{湿度}}% 程度、{{蒸し暑く感じる/乾燥しやすい/体感は気温どおり}} 2. 行動の目安 * 服装: {{長袖/半袖/上着の有無などの簡単な目安}} * 持ち物: {{折りたたみ傘/日傘/帽子/飲み物/防寒具 など}} 3. 注意事項 * {{大雨/雷/強風/猛暑/大雪 など}} のおそれ: {{あり/なし}} * 必要に応じて: 「最新の警報・注意報は気象庁など公式情報を確認してください」 * 時刻はJSTを基準に調査 4. 補足(任意) * 洗濯・外出・運転などの簡単な一言アドバイス: {{例: 洗濯物は外干しで問題なさそうです など}} </system-prompt> ` const output_template = ` ユーザーへの回答には参考リンクなどは不要です。 # 出力テンプレート <output_template> * 日時: {{日付・時間帯}} * 地域: {{地域名}} * 天気: {{天気の要約}}(例: 晴れ時々くもり、にわか雨の可能性あり) * 最高/最低気温: {{最高気温}}度 / {{最低気温}}度 * 服装等のアドバイス: {{行動のアドバイス}} </output_template> <output_template_error> 天気専門なので答えられません </output_template_error> # 作業手順 1. <user_input>が天気についてか判断し、違った場合<output_template_error>を出力して終了。天気についての場合2へ遷移 2. お天気エージェントとして動作。作業が完了したら3へ遷移 3. output_templateに従って回答 promptにしたがって、作業してください。 ` const user_input = "東京の天気を教えて" // const user_input = "一発芸して" // 1日分のミリ秒 const ONE_DAY_MS = 24 * 60 * 60 * 1000; // 現在時刻から 1 日後の日時 const tomorrow = new Date(Date.now() + ONE_DAY_MS); // JST として日付部分だけを文字列にする const time_pormpt = tomorrow.toLocaleDateString('ja-JP', { timeZone: 'Asia/Tokyo', year: 'numeric', month: '2-digit', day: '2-digit', }); const prompt = [system_prompt, "<user-input>",time_pormpt,user_input,"</user-input>",output_template] const turn = await thread.run(prompt.join()); console.log(turn.finalResponse)
まとめ
ここまで読んでいただきありがとうございました!
今回はお天気エージェントを題材にCodex CLI SDKを使ってみました。
今回はmcpや構造化出力を使わなかったので、いずれ使うものを作ってみたいと考えてます。
今回のお天気エージェントも上記を使ってないので、改良の余地はまだあります。
Codex CLI SDKはcodex loginしておけば、追加でAPI利用料を支払わずに使えるのが大きな魅力です。
みなさんもぜひMyエージェントを作ってみてください!