ChatGPT APIをPythonで始める:環境構築と最初のリクエスト

- 1APIキーの取得と環境変数設定APIキーを取得し、.envファイルに保存。python-dotenvで読み込むことでコードに直書きを避ける。
- 2openaiライブラリのインストールpip install openai を実行。仮想環境(venv)の利用を推奨。
- 3OpenAIクライアントの作成from openai import OpenAI; client = OpenAI() でインスタンス化。APIキーは環境変数から自動読み取り。
- 4Chat Completions APIでテキスト生成client.chat.completions.create() にモデルとメッセージリストを指定して応答を取得。
APIキーの取得と環境変数への設定
室谷代表取締役まずAPIキーを取得して、環境変数に設定するのが定石なんですよね。MYUUUでも全プロジェクトで.envに切り出してます。
テキトー教師.AI認定講師最初に戸惑うのが「キーをコードに直接書いちゃう」パターン。GitHubにうっかり上げると大惨事になりますからね。
室谷代表取締役そこはpython-dotenv使って.envに入れる。ROIで言うと、5分の設定で将来的な漏洩リスクがほぼゼロになる。
時給換算で考えてもやる価値があります。
時給換算で考えてもやる価値があります。
openaiライブラリのインストール
テキトー教師.AI認定講師環境はpip一発です。
bash
pip install openai
室谷代表取締役仮想環境は必須ですね。プロジェクトごとに分けないと、後で依存地獄にハマる。
テキトー教師.AI認定講師現場でよく聞くのは「venv使ってなかった」という話。最初に作っておくだけで後の手戻りが減ります。
OpenAIクライアントの作成
室谷代表取締役クライアントは
OpenAI()でインスタンス化。APIキーは環境変数から自動で読むので、引数不要です。
テキトー教師.AI認定講師たしかに。明示的に
コード例はこんな感じ。
api_key=...と書くより、.envに書いておく方が安全です。コード例はこんな感じ。
python
from openai import OpenAI
client = OpenAI()
室谷代表取締役これで準備完了。コスト面で言うと、クライアントは使い回すのが普通。
リクエストのたびにインスタンス作るのは非効率です。
リクエストのたびにインスタンス作るのは非効率です。
Chat Completions APIでテキスト生成
テキトー教師.AI認定講師実際に呼び出すのは
chat.completions.create。メッセージをリストで渡します。python
completion = client.chat.completions.create(
model="gpt-4", # モデルは環境に合わせて
messages=[
{"role": "user", "content": "Hello!"}
]
)
print(completion.choices[0].message.content)
室谷代表取締役最初はシンプルなプロンプトから始めるのがいい。いきなり複雑にするより、まずは応答が返ってくるのを確認する。
テキトー教師.AI認定講師そうそう。最初が動けば、あとはメッセージの構造を変えていくだけです。
Responses APIとChat Completions API、どちらを使うべきか
Responses API
- 状態管理・ツール呼び出しが一貫
- instructionsとinputだけで開発容易
- 長期的な機能拡張に最適
- Function CallingやWeb検索が標準組み込み
- チーム開発で統一メリット大
- 新規開発の第一選択肢
Chat Completions API
- 既存コード資産を活かせる
- 細かい制御がしやすい
- シンプルなチャットボットに十分
- 初心者向け情報が豊富
- 一人で細かい制御したい人向け
- 短期リリースに向く
Responses APIの特徴とメリット
室谷代表取締役新しいResponses API、シリコンバレーのプロダクトチームはもう標準で使ってますね。従来のChat Completionsと比べて、会話の状態管理やツール呼び出しが一貫してて、開発コストがかなり下がるんですよ。
テキトー教師.AI認定講師たしかに。初めて触る人だと「messagesにいろんなroleを並べるのが面倒」ってよく聞きます。
Responses APIだとinstructionsとinputだけで済むので、そのハードルがなくなります。
Responses APIだとinstructionsとinputだけで済むので、そのハードルがなくなります。
室谷代表取締役そう。特にエージェント的な使い方をするなら、コンテキスト管理を自前で書かなくて済む。
ROIで考えると、1週間分の開発工数を節約できるケースもありますからね。
ROIで考えると、1週間分の開発工数を節約できるケースもありますからね。
テキトー教師.AI認定講師ただ、全部をResponses APIに乗り換えるのはまだ少し不安、という声もあります。後方互換性はどうなってるんでしょう?
Chat Completions APIの使いどころ
室谷代表取締役Chat Completionsは継続的にサポートされてますし、既存のコード資産があるなら無理に移行する必要はない。運用で細かいハンドリングが必要な部分は、Chat Completionsのほうが制御しやすいこともある。
テキトー教師.AI認定講師現場でよく聞くのは「シンプルなチャットボットならChat Completionsで十分」という意見ですね。コード例も豊富で、初心者が最初に触るにはこっちのほうが情報が多くて安心です。
室谷代表取締役ただ、長期的にはResponses APIに寄っていく流れでしょう。新しい機能はそっちに追加されていくし、今新規開発するなら最初からResponses APIを選ぶ判断は合理的です。
テキトー教師.AI認定講師そうそう。プロトタイプ段階で両方書いてみて、どちらが直感的か比較するのも手ですよ。
特にドキュメント読み比べると、Responses APIのほうが「これだけで動くんだ」という驚きがあります。
特にドキュメント読み比べると、Responses APIのほうが「これだけで動くんだ」という驚きがあります。
API選択の判断基準
室谷代表取締役判断基準はシンプルで、短期でリリースしたいならChat Completions、長期の機能拡張を見越すならResponses API。コスト面では大差ないですが、開発者の学習曲線を考慮すると、チームにエンジニアが複数いる場合はResponses APIの統一メリットが大きい。
テキトー教師.AI認定講師逆に、一人で細かい制御をしたい人や、既存のプロンプト設計の知識をそのまま使いたい人はChat Completionsのほうが楽ですね。両方ともPython SDKで同じように使えるので、まずは公式のクイックスタートを動かしてみるのがいいです。
室谷代表取締役あとは外部のツール連携。Responses APIはFunction CallingやWeb検索が標準で組み込めるので、APIの呼び出し回数が減るメリットは無視できない。
テキトー教師.AI認定講師結局は作りたいもの次第ですが、「とりあえず動かす」ならChat Completions、「これからも拡張する」ならResponses API、というのが現場感覚として定着してますね。
プロンプト設計の基本:ロールベースのメッセージ構造
systemロール
- 振る舞いや応答ルールを定義
- 品質とコスト(トークン数)に影響
- 簡潔な指示でAPI費用削減
userロール
- 具体的な入力を与える
- 構造化データや例示で精度向上
- few-shot exampleを活用
assistantロール
- 過去の応答を文脈として保持
- 会話履歴の管理に必須
- トークン消費に注意、要約や間引きが必要
systemロールで振る舞いを定義する
室谷代表取締役API 叩くとき、最初にハマるのが system ロールの使い方なんですよね。これ、文字通り「システム側の指示」で、アシスタントの性格や応答ルールを決めるんです。
テキトー教師.AI認定講師たしかに。最初のうち「とりあえず空でいいや」と飛ばす人が多いんですが、そこで品質が決まります。
室谷代表取締役コスト面でも大事で。system で「簡潔に答えろ」と入れておけばトークン数が減る。
ROI で考えると、この一文書き加えるだけで月のAPI費用が変わってくる。
ROI で考えると、この一文書き加えるだけで月のAPI費用が変わってくる。
テキトー教師.AI認定講師なるほど。現場でよく聞くのは「system と developer って何が違うんですか」という質問。
最近は developer ロールも使えますが、基本的な考え方は同じですよね。
最近は developer ロールも使えますが、基本的な考え方は同じですよね。
userロールで具体的な入力を与える
室谷代表取締役user はそのまんまユーザーからの入力。ここで気をつけたいのが、日本語の自然言語だけじゃなくて、構造化データや例示を混ぜると精度が上がるんです。
テキトー教師.AI認定講師そうそう。「こういうフォーマットで答えて」と user の中に例を入れるだけで、出力が安定します。
室谷代表取締役US の API ディベロッパーはよく「few-shot example を user メッセージに入れろ」と言います。Python のチュートリアル記事なんかでも、このテクニックはよく出てきますね。
テキトー教師.AI認定講師「chatgpt api python tutorial」で検索してくる人が、実はここでつまずくんです。入力を工夫するだけで結果が全然変わるので、一度試してみると良いですよ。
assistantロールで過去の応答を文脈として保持する
室谷代表取締役assistant ロールはモデルが過去に返した応答を明示的に入れるのに使います。特に会話の文脈を維持したいとき必須です。
テキトー教師.AI認定講師チャットボットを作るとき、毎回すべての履歴を messages 配列に突っ込むんですが、assistant のロールを間違えないようにしないと。
室谷代表取締役そうです。で、ここで気をつけるのはトークン消費。
過去の会話を全部突っ込むとすぐ上限に当たる。適度に要約して assistant に詰めるか、メッセージを間引くか。
過去の会話を全部突っ込むとすぐ上限に当たる。適度に要約して assistant に詰めるか、メッセージを間引くか。
テキトー教師.AI認定講師だからこそ、system で「これまでの会話を3行でまとめろ」と指示しておく手もある。これ、現場の常套手段です。
APIエラーへの備え:ハンドリングとリトライ戦略
よくあるHTTPエラーとその原因
テキトー教師.AI認定講師実際にAPI叩いてると、まず401(認証エラー)と429(レート制限)に遭遇しますね。キーの設定ミスか、リクエストが急に増えたときですね。
室谷代表取締役うちの現場でも、デプロイ直後にAPIキーを直書きしてて慌てるケース、よくあります。Pythonのコードで例外処理を入れておくだけで、原因特定がぐっと楽になりますよ。
テキトー教師.AI認定講師そうそう。最低限、status_codeで分岐するtry-exceptを入れておけば、エラー内容がすぐわかります。
リトライ処理の実装パターン
室谷代表取締役本番では、一時的なエラー(500番台)に対して自動リトライを仕込むのが定石です。Pythonだと簡単なループで実装できます。
テキトー教師.AI認定講師例えば、最初に1秒待って、失敗したら2秒、4秒と指数関数的に間隔を空けるexponential backoff。コード例を出すと、こんな感じです。
テキトー教師.AI認定講師```python
import time
for attempt in range(3):
try:
response = client.responses.create(...)
break
except Exception:
if attempt == 2:
raise
time.sleep(2 ** attempt)
code
**室谷**: このパターン、ChatGPT APIのPythonコードにはよく登場します。サードパーティのリトライライブラリ使うと、さらに簡潔に書けますね。
### レート制限への対策
**室谷**: 429エラーを食らうと、レスポンスヘッダーに`Retry-After`が返ってきます。それを読んで待つ処理を入れるのが確実です。
**テキトー教師**: 現場でよく聞くのは「制限にかからないようにリクエストを分散させる」工夫。バッチ処理ならあらかじめ間隔を開けて送るのも手です。
**室谷**: コスト管理の観点でも、429でリトライが増えると無駄なトークンが発生します。適切なレート制限対策は、結果的にコスト削減にもつながるんですよね。
**テキトー教師**: そういう意味でも、最初からリトライとレート制限のハンドリングを実装しておくのが大事ですね。
## リアルタイム応答を実現するストリーミング処理
### ストリーミングモードの有効化
**室谷**: ユーザ体験を考えると、ストリーミングは必須ですね。APIの応答を待たせると離脱率が跳ね上がるんで、初期から組み込んだ方がいいです。
**テキトー教師**: たしかに。`stream=True`を渡すだけで、レスポンスがチャンクで返ってくるようになります。最初に戸惑うのは、返ってくるのが通常のJSONじゃなくて、イベントストリームになる点ですね。
**室谷**: コードとしてはこんな感じです。
```python
import openai as oa
cl = oa.OpenAI()
cc = cl.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Hello"}],
stream=True
)
for chunk in cc:
content = chunk.choices[0].delta.content
if content:
print(content, end="")
テキトー教師.AI認定講師これで逐次的にトークンが届くので、ユーザは待たされてる感がなくなります。
逐次データのハンドリング方法
テキトー教師.AI認定講師チャンクからテキストを取り出すとき、
delta.contentがNoneのケースがあるので注意が必要です。最初のチャンクは空だったり、roleだけ含まれたりするんです。
室谷代表取締役アプリ側でバッファリングして、最終的に全文を組み立てる処理も必要ですね。コスト的にはストリーミングと非ストリーミングで変わらないので、迷わずストリーミングでいいと思います。
テキトー教師.AI認定講師処理の流れとしては、空文字を無視しながら随時追記していく。Flaskとかでチャットボットを作るときは、
Responseオブジェクトでジェネレータを返すと綺麗に書けます。
室谷代表取締役SDKを使えば内部でイテレートしてくれるんで、実装は簡単です。
チャットUIへのストリーミング統合
テキトー教師.AI認定講師Webアプリに組み込む場合、Pythonバックエンドで文字列を少しずつ生成して、Server-Sent Eventsでフロントに流すのが定番です。
室谷代表取締役ボトルネックはAPIの応答時間より、ネットワークのレイテンシになりますね。東京リージョンからUSのAPIを叩くと300msくらいかかるので、その辺を考慮してUI設計する必要があります。
テキトー教師.AI認定講師最初のチャンクが早く返ってくるほどユーザの体感速度は上がります。
max_tokensを制限するのも一手です。
室谷代表取締役リアルタイム性を追求するならWebSocketモードもありますが、まずはストリーミングで十分なケースが多いです。
コストを抑える:トークン管理とモデル選択
トークン管理
入力・出力両方課金。プロンプト短縮、systemメッセージ簡潔、max_tokens適切設定で節約。
モデル選択
タスクに合ったモデルを選ぶ。簡単なタスクは軽量モデル、必要ならアップグレード。ROIを考慮。
API呼び出し削減
キャッシュや結果保存、リクエストまとめ、バッチ処理。ストリーミング時はバッチ不向き。
トークン数と料金の関係
テキトー教師.AI認定講師よく「APIを呼ぶとどれくらいかかるのか」と聞かれます。トークン数と料金の関係を理解していないと、思わぬ請求になることもありますね。
室谷代表取締役そうですね。OpenAIのAPIは入力と出力の両方で課金されます。
プロンプトが長くなるとその分コストが跳ね上がる。時給換算でプロンプトを削る作業をやる価値があるかどうか、という判断になります。
プロンプトが長くなるとその分コストが跳ね上がる。時給換算でプロンプトを削る作業をやる価値があるかどうか、という判断になります。
テキトー教師.AI認定講師たしかに。プロンプトを短く書くだけでも節約になります。
systemメッセージを簡潔にするとか。
systemメッセージを簡潔にするとか。
室谷代表取締役あと、レスポンスのmax_tokensを適切に設定するのも大事。無駄に長い出力を許すと、結果としてコストがかさみます。
コスト効率の良いモデルの選び方
テキトー教師.AI認定講師コストを抑えるには、タスクに合ったモデル選びが重要です。簡単なタスクに高性能モデルを使うのはもったいない。
室谷代表取締役その通り。例えば、チャットボットの応答生成なら軽量モデルで十分なケースが多い。
逆にコード生成や複雑な推論は高性能モデルが必要。ROIで見てどこに投資すべきか、です。
逆にコード生成や複雑な推論は高性能モデルが必要。ROIで見てどこに投資すべきか、です。
テキトー教師.AI認定講師初めて触る人はつい最新モデルを選びがちですが、コスト対効果を考えましょう。
室谷代表取締役そうですね。価格差は意外と大きいので、まずは軽量モデルでプロトタイプを作り、必要に応じてアップグレードするのが現実的です。
API呼び出しを減らす工夫
テキトー教師.AI認定講師API呼び出しそのものを減らす工夫もコスト削減に効きます。よくあるのがプロンプトのキャッシュや結果の保存です。
室谷代表取締役特に同じような質問を何度も投げるケースでは、リクエストをまとめるか、事前に回答をキャッシュしておく方が効率的。時給換算で考えると、キャッシュの実装コストをAPI呼び出しの節約が上回るか、ですね。
テキトー教師.AI認定講師なるほど。バッチ処理も有効です。
室谷代表取締役ただし、レスポンスのストリーミングが必要な処理だとバッチは向かないので、ユースケースに応じて使い分けが大事ですね。
実践!Flaskを使ったチャットボットの構築
Flaskアプリのセットアップ
室谷代表取締役まずは最小構成のFlaskアプリから。現場でよく見るのは、単一ファイルで動かして後から分割するパターンですね。
テキトー教師.AI認定講師たしかに。最初に戸惑うのが環境変数です。
OPENAI_API_KEYを直接コードに書いてしまう人がいて。
OPENAI_API_KEYを直接コードに書いてしまう人がいて。
室谷代表取締役公式でもdotenv推奨してます。.envファイルに書いてpython-dotenvで読み込む。
時給換算すると、後で漏洩したときの対処コストを考えれば絶対やるべき。
時給換算すると、後で漏洩したときの対処コストを考えれば絶対やるべき。
テキトー教師.AI認定講師コードはこんな感じです。
python
from flask import Flask, request, jsonify
from openai import OpenAI
app = Flask(__name__)
client = OpenAI() # 環境変数から自動読み込み非同期API呼び出しの組み込み
室谷代表取締役問題はAPI呼び出しが同期的だと、リクエストごとにブロックされること。チュートリアルでは同期で済ませがちですけど。
テキトー教師.AI認定講師実際に動かすと、ユーザーが待ちますよね。非同期にするにはFlaskのasync対応ルートか、スレッド使うか。
室谷代表取締役公式SDKも非同期クライアントを提供してるので、async/awaitで書くのが素直。コスト的には待ち時間を減らせる分、サーバー台数減らせます。
python
import asyncio
@app.route('/chat', methods=['POST'])
async def chat():
data = request.json
response = await client.responses.create(
model="gpt-5.5",
input=data['message']
)
return jsonify({'reply': response.output_text})デプロイ時の注意点と環境設定
室谷代表取締役本番に上げるなら、APIキーは環境変数からしか読まない設計に。シークレットマネージャー使うのが王道です。
テキトー教師.AI認定講師よくあるのが、.envをそのままGitHubに上げてしまうケース。.gitignoreに追加するのは最初の設定で必ず。
室谷代表取締役あとCORS設定とレート制限。公開APIにするなら、同じキーで大量呼び出しされないように制限かけた方がいい。
テキトー教師.AI認定講師このチュートリアルを参考に自分のプロジェクトに組み込む人は、ここでつまずきやすいので、ドキュメントにも明記しておきたいですね。
APIキーを安全に管理する方法
環境変数による鍵の分離
- コードにAPIキーを直書きしない
- os.getenv()で環境変数から読み込み
- GitHubなどにプッシュするリスクがある
python-dotenv
- pip install python-dotenv
- load_dotenv()で.envを読み込み
- .envを.gitignoreに追加
- .env.exampleをリポジトリに配置
Workload Identity
- 長期鍵の代わりに短期トークン
- Kubernetesやクラウド向け
- 鍵のローテーション不要
- 初期設定は手間だが長期的運用コスト低下
環境変数による鍵の分離
室谷代表取締役APIキーをコードに直書きするのは、セキュリティ事故の定番パターンですよね。MYUUUでも過去にやらかしかけたことがあって、それ以来、環境変数で分離するのが基本ルールになりました。
テキトー教師.AI認定講師たしかに、最初に戸惑うのが「どこに書くのが正解か」というところですね。GitHubにうっかりプッシュしてしまうリスクを考えると、環境変数は必須の習慣だと思います。
室谷代表取締役特に個人開発だと「ひとまず直書き」で動かして、そのまま放置ってケースが多い。時給換算すると後で鍵を再発行する手間の方が割高なので、最初に.envを作るクセをつけるのがおすすめです。
テキトー教師.AI認定講師そうなんです。最初に.envを作って、そこに
ソースコードには
OPENAI_API_KEY=sk-... と書いておく。ソースコードには
os.getenv("OPENAI_API_KEY") だけ書く。このルールだけでだいぶ安心です。python-dotenvを使った設定
テキトー教師.AI認定講師環境変数を手動で設定するのは面倒なので、python-dotenvを使うのが現場の定番です。
pip install python-dotenv で入れて、起動時に load_dotenv() を呼ぶだけ。
室谷代表取締役これ、コードの可読性にも効くんですよね。どの変数を外部から注入しているかが一目で分かる。
特にチーム開発だと、新規メンバーが迷わずに済みます。
特にチーム開発だと、新規メンバーが迷わずに済みます。
テキトー教師.AI認定講師そう。
.env 自体は .gitignore に追加してリポジトリに含めない、代わりに .env.example を置いておくというのが定番の運用です。
室谷代表取締役コスト面でも、APIキーを間違えて公開→不正利用で想定外の課金、というリスクを避けられる。これだけで月数千円の差が出ることもあります。
Workload Identity認証のススメ
室谷代表取締役さらにセキュアにするなら、Workload Identityを使う手があります。長期鍵の代わりに、クラウドプロバイダから発行される短期トークンで認証する方式です。
テキトー教師.AI認定講師KubernetesやAzure、GCPで動かす場合に便利ですね。OpenAIのPython SDKが
workload_identity オプションをサポートしていて、トークンプロバイダを指定するだけで使えます。
室谷代表取締役鍵のローテーションを運用でカバーしなくてよくなる。ROIで見ると、初期設定の手間はあるけど、長期的な運用コストは下がるケースが多いです。
テキトー教師.AI認定講師最初は環境変数で十分ですが、サービスが大きくなってきたら検討する価値はありますね。具体的な実装は公式ドキュメントの該当セクションを参照するのが確実です。
よくある質問
Q1. 対話履歴を保持するにはどうすればいいですか?
テキトー教師.AI認定講師これ、現場でよく聞かれますね。APIはステートレスなので、毎回過去のやり取りをメッセージ配列に含めて送る必要があります。
室谷代表取締役そうです。実装としては、セッションごとにメッセージリストをDBやメモリに保存しておいて、リクエストのたびにそれまでのやり取りを全部投げる感じですね。
テキトー教師.AI認定講師ただ、トークン数が増えるとコストも遅延も増えるので、ある程度古い会話は要約してコンテキストに含める工夫もよくやります。
Q2. 商用利用のライセンスはどうなっていますか?
室谷代表取締役OpenAIの利用規約上、APIで生成したコンテンツは基本的に商用利用可能です。ただし、出力内容の責任は利用者側にあるので注意が必要です。
テキトー教師.AI認定講師特に注意点としては、倫理的に問題のある出力をそのまま使わないように、出力のフィルタリングや人間によるレビューを入れることをおすすめします。
Q3. レートリミットに達した場合の具体的な対処法は?
室谷代表取締役まずはHTTPステータスコード429をキャッチして、
Retry-Afterヘッダーを見て待機するのが基本です。エクスポネンシャルバックオフも併用すると安定します。
テキトー教師.AI認定講師あとは、APIキーを複数用意してラウンドロビンする方法もありますが、利用規約的にグレーゾーンなので注意が必要です。
Q4. APIの応答速度を改善するにはどうすればいいですか?
室谷代表取締役モデルの選択が一番効きますね。gpt-4よりgpt-3.5-turboのほうが圧倒的に速い。
あとはトークン数を制限するとレスポンスが早くなります。
あとはトークン数を制限するとレスポンスが早くなります。
テキトー教師.AI認定講師ストリーミングも体感的には速く感じますよ。待ち時間が減るので、ユーザー体験が良くなります。
Q5. 他のAI API(Anthropicなど)と併用する際の注意点は?
室谷代表取締役併用自体は問題ありませんが、APIキーごとに利用規約が異なるので、それぞれのドキュメントは確認したほうがいいです。
テキトー教師.AI認定講師それと、モデルによって得意なタスクが違うので、使い分けると効果的です。例えば、コード生成にはClaude、創造的な文章にはGPT、みたいな。
まとめ
室谷代表取締役この記事では、ChatGPT APIをPythonで使う一連の流れをざっと追いました。環境構築から実践的なチャットボット構築まで、結構網羅できたんじゃないですか。
テキトー教師.AI認定講師そうですね。個人的には、エラーハンドリングとリトライ戦略のところは最初から実装しておくことをおすすめします。
そうしないと、本番で痛い目を見ますから。
そうしないと、本番で痛い目を見ますから。
室谷代表取締役あとはコスト管理ですね。トークン数を意識しないと、知らないうちに請求が跳ね上がる。
モデル選びとプロンプト設計が節約のカギです。
モデル選びとプロンプト設計が節約のカギです。
テキトー教師.AI認定講師この記事を読んで実際に手を動かしてみると、APIの仕組みが理解できるはずです。次のステップとしては、関数呼び出しやRAGの実装に進むのも面白いですよ。
室谷代表取締役ぜひ、まずは小さなプロジェクトで試してみてください。そして、困ったときは公式ドキュメントを参照する習慣をつけると長く使えます。
