API用の関数スキーマを定義する
関数のJSON Schema定義を記述してtoolsパラメータに渡し、モデルが関数を呼び出すタイミングと方法をどのように判断するのかを理解します。
「API用の関数スキーマを定義する」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Engineering Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Engineering Academyコースには全4レッスンが含まれています。
Function Callingとは
OpenAIのfunction calling(現在はtool callingと呼ばれます)を使うと、Python関数を構造化されたJSON Schema形式でモデルに説明できます。関数を呼び出すべきだとモデルが判断すると、自由形式のテキストではなく、関数名と引数を含む構造化されたJSONオブジェクトを返します。コード側でこれを確実に実行できます。
toolsパラメーターの構造
関数定義は、オブジェクトのリストとしてAPIのtoolsパラメーターに渡します。各オブジェクトには'function'というtypeと、名前、説明、パラメーターを定義するJSON Schemaを含むfunctionキーがあります。
from openai import OpenAI
client = OpenAI()
tools = [
{
'type': 'function',
'function': {
'name': 'get_current_weather',
'description': 'Get the current weather in a given location.',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type': 'string',
'description': 'City and country, e.g. London, UK'
},
'unit': {
'type': 'string',
'enum': ['celsius', 'fahrenheit'],
'description': 'Temperature unit to use.'
}
},
'required': ['location']
}
}
}
]パラメーターのJSON Schema
parametersフィールドはJSON Schema仕様に従います。typeを使って、string、number、integer、boolean、array、objectのいずれかを指定します。各プロパティのdescriptionには、そのフィールドの意味をモデルに伝える説明を記載します。必須フィールドはrequired配列に列挙し、任意フィールドはrequiredから省略できます。
# A more complex schema with multiple types
create_event_tool = {
'type': 'function',
'function': {
'name': 'create_calendar_event',
'description': 'Create a new calendar event. Use when the user wants to schedule a meeting or appointment.',
'parameters': {
'type': 'object',
'properties': {
'title': {'type': 'string', 'description': 'Event title.'},
'start_time': {'type': 'string', 'description': 'ISO 8601 datetime, e.g. 2024-03-15T14:00:00.'},
'duration_minutes': {'type': 'integer', 'description': 'Duration in minutes.', 'minimum': 5},
'attendees': {
'type': 'array',
'items': {'type': 'string'},
'description': 'List of email addresses of attendees.'
},
'location': {'type': 'string', 'description': 'Physical or virtual meeting location.'}
},
'required': ['title', 'start_time', 'duration_minutes']
}
}
}toolsを使ったAPI呼び出し
toolsリストをchat.completions.createに直接渡します。モデルは、関数なしで回答できる場合は通常のテキストメッセージを返すこともあれば、関数の実行を指示するtool_callsオブジェクトを返すこともあります。どちらのケースかを判断するため、必ずfinish_reasonを確認してください。
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{'role': 'user', 'content': 'What is the weather in Tokyo?'}
],
tools=tools
)
print('Finish reason:', response.choices[0].finish_reason)
# 'tool_calls' means the model wants to call a function
# 'stop' means the model gave a regular text response
choice = response.choices[0].message
if response.choices[0].finish_reason == 'tool_calls':
print('Model wants to call:', choice.tool_calls[0].function.name)tool_choiceによるツール選択の制御
tool_choiceパラメーターは、モデルが関数を必ず呼び出す必要があるか、自由に選択できるかを制御します。'auto'に設定すると、モデルが判断します。'required'に設定すると、ツール呼び出しを強制します。特定の関数名を指定すると、その関数だけが呼び出されます。これは、常に構造化された出力が必要な抽出タスクに便利です。
# Force the model to always call extract_contact
response = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Hi, I am John Smith, john@example.com, +1-555-0100.'}],
tools=[extract_contact_tool],
tool_choice={'type': 'function', 'function': {'name': 'extract_contact'}}
)
# With tool_choice forced, finish_reason will always be 'tool_calls'選択肢を制限するEnumフィールド
パラメーターを固定された値の集合に制限する場合は、JSON Schemaでenumフィールドを使用してください。スキーマに許可される値が正確に一覧表示されていると、モデルが無効な選択肢を作り出す可能性が大幅に下がるため、信頼性が大きく向上します。
classify_sentiment_tool = {
'type': 'function',
'function': {
'name': 'classify_sentiment',
'description': 'Classify the sentiment of a customer review.',
'parameters': {
'type': 'object',
'properties': {
'sentiment': {
'type': 'string',
'enum': ['positive', 'negative', 'neutral', 'mixed'],
'description': 'The sentiment classification.'
},
'confidence': {
'type': 'number',
'minimum': 0.0,
'maximum': 1.0,
'description': 'Model confidence from 0 to 1.'
}
},
'required': ['sentiment', 'confidence']
}
}
}ネストされたオブジェクトスキーマ
JSON Schemaはネストされたオブジェクトをサポートしています。独自のpropertiesを持つ'type': 'object'を使用して、複雑な階層構造のデータを定義してください。メールやドキュメントなどの非構造化テキストから構造化データを抽出する場合に最適です。
extract_order_tool = {
'type': 'function',
'function': {
'name': 'extract_order',
'description': 'Extract order details from a customer email.',
'parameters': {
'type': 'object',
'properties': {
'customer': {
'type': 'object',
'properties': {
'name': {'type': 'string'},
'email': {'type': 'string', 'format': 'email'}
},
'required': ['name']
},
'items': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'product_id': {'type': 'string'},
'quantity': {'type': 'integer', 'minimum': 1}
},
'required': ['product_id', 'quantity']
}
}
},
'required': ['customer', 'items']
}
}
}Pydanticモデルからのスキーマ生成
JSON Schemaを手作業で記述するのは面倒で、エラーも起こりやすくなります。代わりに、データ構造をPydantic modelとして定義し、.schema()を使用してJSON Schemaを自動生成してください。これにより、モデルのレスポンスをデシリアライズする際に、Pythonレベルのバリデーションも実行できます。
from pydantic import BaseModel, Field
from typing import Optional, List
class ContactInfo(BaseModel):
name: str = Field(description='Full name of the person.')
email: Optional[str] = Field(None, description='Email address.')
phone: Optional[str] = Field(None, description='Phone number in E.164 format.')
company: Optional[str] = Field(None, description='Company or organization.')
# Auto-generate the JSON Schema
schema = ContactInfo.schema()
# Build the tool definition
extract_contact_tool = {
'type': 'function',
'function': {
'name': 'extract_contact',
'description': 'Extract contact information from text.',
'parameters': schema
}
}効果的な関数の説明を記述する
関数の説明は、モデルがツールを呼び出すタイミングを判断する際に使用する重要な手がかりです。適切な説明では、用途を具体的に示し、関数を呼び出すべき場合と呼び出すべきでない場合に触れ、出力内容を説明します。曖昧な説明では、モデルが誤った関数を呼び出したり、適切な関数を呼び出す機会を逃したりします。
- 曖昧: 'Get weather data.'
- 適切: 'Get the current weather conditions for a specific city. Use when the user explicitly asks about weather in a named location. Returns temperature, conditions, and humidity.'
スキーマへの準拠を保証するStrict Mode
構造化出力におけるOpenAIのstrict modeを使用すると、モデルがスキーマに正確に一致するJSONを生成することを保証できます。余分なフィールドや、必須フィールドの欠落もありません。関数定義で'strict': trueを設定して有効にしてください。注: strict modeを使用するには、すべてのスキーマオブジェクトでadditionalProperties: falseが必要です。
strict_tool = {
'type': 'function',
'function': {
'name': 'classify_ticket',
'description': 'Classify a support ticket into category and priority.',
'strict': True, # Enable strict schema adherence
'parameters': {
'type': 'object',
'additionalProperties': False, # Required for strict mode
'properties': {
'category': {
'type': 'string',
'enum': ['billing', 'technical', 'account', 'other']
},
'priority': {
'type': 'string',
'enum': ['low', 'medium', 'high', 'urgent']
}
},
'required': ['category', 'priority']
}
}
}関数スキーマをテストする
デプロイする前に、各関数スキーマを多様な入力でテストしてください。通常のケース、エッジケース、敵対的な入力を含めます。モデルが正しい関数を呼び出すこと、有効な引数の型を生成すること、オプションのフィールドを正しく処理すること、enumの制約を守ることを確認してください。本番コードを書く前に、OpenAI Playgroundを使ってすばやく試行を重ねるとよいでしょう。
クイックチェック
OpenAI API向けの関数スキーマの定義について、理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、関数スキーマではJSON Schemaを使用してパラメーターの型、説明、制約を定義すること、tool_choiceによってモデルが関数を必ず呼び出すか、自由に選択するかを制御できること、そしてPydanticモデルによってJSON Schemaを自動生成し、手作業でのスキーマ記述を減らせることを学びました。次は、ツール呼び出しを検出して実行し、結果を返すことで、アプリケーション内でツール呼び出しを処理する方法を学びます。
よくある質問
「API用の関数スキーマを定義する」レッスンは無料ですか?
はい。「API用の関数スキーマを定義する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。
「API用の関数スキーマを定義する」で何を学びますか?
関数のJSON Schema定義を記述してtoolsパラメータに渡し、モデルが関数を呼び出すタイミングと方法をどのように判断するのかを理解します。 ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Engineering Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「API用の関数スキーマを定義する」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Engineering Academyレッスンでコードを書いて実行できますか?
はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- API用の関数スキーマを定義する
- アプリケーションでツール呼び出しを処理する
- 関数の並列呼び出し
- 自然言語データベースインターフェースを構築する