ジャクソン 3 の使用LangChain4j は、交換するリクエストとレスポンスなど、さまざまな場所で JSON を読み書きします。
LLM プロバイダー、AI サービスが解析する構造化された出力、保持するチャット メモリなど。によって デフォルトでは Jackson 2 でこれを行います。 LangChain4j の使用方法 JSON と独自のマッパーをプラグインする方法については、JSON で説明されています。 アプリケーションが Jackson 3 上にある場合は、代わりに LangChain4j にそれを使用させることができます。
オンにする依存関係を 1 つ追加します。
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-jackson3</artifactId>
<version>1.23.0-beta33</version>
</dependency>
langchain4j-agentic を含むすべてのモジュールに ついて、これがすべてです。 LangChain4j は、
モジュールを ServiceLoader 経由で接続し、その JSON を Jackson 3 経由でルーティングします。
設定しても呼び出す API がなく、依存関係を削除するとすべてが Jackson 2 に戻ります。
サポートは 2 つのアーティファクトに分割されており、上記の langchain4j-jackson3 は両方を取り込むので、
追加しない理由がない限り、追加するものです。
| アーティファクト | カバー | によって異なります |
|---|---|---|
langchain4j-core-jackson3 | langchain4j-core のすべて: プロバイダーの要求と応答、構造化された出力、チャット メモリのシリアル化、エージェントの状態 | langchain4j-core |
langchain4j-jackson3 | 上記に加えて、langchain4j モジュールに存在する InMemoryEmbeddingStore 永続性。 langchain4j-core-jackson3 と langchain4j | |
アプリケーションが langchain4j-core と | ||
langchain4j モジュールのないプロバイダー - たとえば、モデルを構築するフレームワーク統合 | ||
直接的に。 langchain4j-jackson3 と一緒に追加することは不要ですが、害はありません。 |
変わらないものJSON ライブラリを切り替えることは、誤って動作を変更する良い方法であるため、モジュールはハードウェア的に動作します。
に。 Jackson 3 はいくつかのデフォルトを変更し、LangChain4j の読み取り内容を変更するほぼすべてのデフォルトを変更しました。 write は、Jackson 2 が行ったことに戻ります。意図的に保持されているいくつかのものが以下にリストされています What is deliberately different。
| 設定 | ジャクソン3のデフォルト | このモジュールの機能 |
|---|---|---|
ALLOW_FINAL_FIELDS_AS_MUTATORS | 無効 | 有効 |
USE_GETTERS_AS_SETTERS | 無効 | 有効 |
SORT_PROPERTIES_ALPHABETICALLY | 有効 | 無効 |
FAIL_ON_TRAILING_TOKENS | 有効 | 無効 |
FAIL_ON_NULL_FOR_PRIMITIVES | 有効 | 無効 |
READ_ENUMS_USING_TO_STRING | 有効 | 無効: enum は name() によって読み取られます |
WRITE_ENUMS_USING_TO_STRING | 有効 | 無効: 列挙型は name() |
DETECT_PARAMETER_NAMES | 有効 | 構造化出力とツール引数を除き、無効になります (以下を参照)。 |
FAIL_ON_UNKNOWN_PROPERTIES | 無効 | 有効: ターゲット タイプにないフィールドは、構造化出力、ツール引数、チャット メモリ、エージェント状態、および保存された埋め込みストアで失敗します。プロバイダーの応答は依然として不明なフィールドを無視します。 |
FAIL_ON_EMPTY_BEANS | 無効 | 有効: 書き込むものが何もないオブジェクト (たとえば、フィールドがプライベートでゲッターを持たないオブジェクト) は、{} |
| 最初の項目が最も重要です。これがないと、最終的なコレクション フィールドは空のままになります。 | ||
| 人口が多くても何もわかりません。 | ||
DETECT_PARAMETER_NAMES は、コードが Spring Boot として -parameters でコンパイルされている場合にのみ問題になります。 | ||
| Quarkus プロジェクトは通常そうです。構造化された出力およびツール引数の場合、コンストラクター パラメーター | ||
jackson-module-parameter-names がクラスパス上にある場合に Jackson 2 コーデックが行うように、名前が使用されます。 | ||
| これは Spring Boot と Quarkus にあります。引数を持つコンストラクターのみを持つクラスです。 | ||
ロンボク島@AllArgsConstructorクラス、読めます。チャット メモリ、エージェントの状態、その他のコーデックは影響を受けません。 | ||
| Jackson 2 と同様にパラメータ名を使用します。 | ||
| コ ンパイラの設定に関係なく、コンストラクターを明示的に選択するには、それにアノテーションを付けます。 |
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)を使用すると、"abc"などのプレーンな値を読み取ることができます。 引数が 1 つのコンストラクター。@JsonCreatorを使用し、@JsonProperty("name")を使用して各パラメータを使用すると、オブジェクトを介してオブジェクトを読み取ります。 引数付きのコンストラクター。 どちらもジャクソンのバージョンで動作します。
意図的に異なるものは何ですかいくつかの違いは、復元すると予想よりもコストがかかるため、意図的に残されています。
- 日付と時刻は ISO-8601 文字列として書き込まれます。
java.util.DateとCalendarは次のようになります。 エポックミリ秒の代わりに"1970-01-01T00:00:00.000Z"。jackson-datatype-jsr310を搭載 Spring Boot や Quarkus アプリケーションと同様に、Jackson 2 もクラスパスをInstantと書きます。OffsetDateTimeおよびDurationは数値として表されます。このモジュールはそれらを ISO-8601 文字列として書き込みます。 LLM ははるかに信頼性の高い読み取りを行います。Date、Instant、Durationの数字は引き続き読み取られます。 java.time.Monthは 1 から始まる数字として記述されます (1 月の場合は1)。とjackson-datatype-jsr310、ジャクソン 2 は"JANUARY"を書き込み、開始位置として数値を読み取ります。 0 の場合、1はFEBRUARYになります。どちらのバージョンも名前を読みます。""は、列挙型の場合はnullとして読み取られます。これは欠損値と同じです。これは必須に適用されます enum も同様です。欠落フィールドと同様に、""はエラーではなくnullを返します。代わりにジャクソン2は失敗しますが、 しかしプロバイダーはそれを送信します - ツール呼び出しに対して"type": ""を返す OpenAI 互換サーバーとは何ですか これが見つかりました - そして、LLM はオプションの列挙型に対して""と応答する可能性があります。""(オブジェクト、マップ、またはリスト) Jackson 2 と同様に、やはり失敗します。private1 引数コンストラクターは、プレーンな値の読み取りには使用されません。 Jackson 2 はこれを使用します。 Jackson 3 の場合は、@JsonCreator(mode = JsonCreator.Mode.DELEGATING)という注釈を付けます。- 構造化出力およびツール引数の場合、引数のないコンストラクターと
引数付きコンストラクターは、コンパイル時に引数付きコンストラクター を介して作成されます。
-parameters。 Jackson 2 は引数なしのコンストラクターを使用してフィールドを設定します。これだけ そのコンストラクターがフィールドを割り当てる以上のことを行うかどうかが重要です。 - ゲッター
getXValue()を含むxValueなどのフィールドは、"xValue"と記述されます。 Jackson 2 の導出 ゲッターからの"xvalue": 構造化出力、ツールの結果、およびエージェントの状態の両方を書き込みます。"xValue"および"xvalue"、プロバイダー要求の場合のみ"xvalue"。エージェント状態の書き込み者 このような重複キーを持つ Jackson 2 は、このモジュールでの読み取りに失敗します。
- 失敗すると LangChain4j タイプが取得されます。*
デフォルトでは、JSON エラーは、Jackson 2 独自の例外をラップする
RuntimeExceptionとして表面化します。 つまり、それに反応するコードは Jackson 2 を認識している必要があります。このモジュールを使用すると、JSON の読み取りまたは書き込みが可能になります。 失敗した場合は、代わりにJsonReadExceptionまたはJsonWriteException(両方ともLangChain4jException) がスローされます。 ライブラリの例外が原因として保持されます。 これは矛盾ではなく意図的なステップです。型指定された例外は、LangChain4j の場所にあります。 は次のメジャー バージョンで導入される予定ですが、Jackson 2 コーデックはそれまでそのままのままです。 既存のコードは引き続き機能します。 JSON エラーをその Jackson タイプで検出できれば、それが 1 つのことです このモジュールを追加するときに再度アクセスしてください:
- } catch (JsonParseException e) {
+ } catch (JsonReadException e) {
RuntimeException をキャッチすることはどちらの方法でも機能します。
2 か所は、catch ブロックが関与せずにアプリケーション コードに到達するため、価値があります。
切り替える前に確認してください:
- ツール引数エラー ハンドラー。* モデルが有効な JSON ではないツール引数を生成すると、
LangChain4j は、登録したハンドラーに失敗を渡します。
AiServices.toolArgumentsErrorHandler(...)。ジャクソン2では、失敗はジャクソン自身の責任であるJsonParseException;このモジュールではJsonReadExceptionになります。上で分岐するハンドラ type はマッチングを停止し、ハンドラーはまだ呼び出され、単純に そのもう一方のブランチ:
AiServices.builder(Assistant.class)
.toolArgumentsErrorHandler((error, context) -> {
- if (error instanceof JsonParseException) {
+ if (error instanceof JsonReadException) {
return ToolErrorHandlerResult.text("Please return valid JSON.");
}
throw error;
})
両方の下で動作するハンドラーが必要な場合は、メッセージまたは RuntimeException に一致します。
OutputParsingExceptionの原因* 構造化された出力を解析できない場合、LangChain4j どちらの場合でもOutputParsingExceptionをスローします - その型は変更されません。何が変わるかというと、 その下の例外、Jackson 2 のJsonProcessingExceptionから Jackson 3 までStreamReadException。getRootCause()を検査するコードも同じ処理が必要です。- すでに保存されているデータは引き続き読み取り可能です。* チャット メモリと
InMemoryEmbeddingStoreファイル Jackson 2 によって書き込まれた内容は Jackson 3 によって正しく読み取られ、Jackson 3 が書き込む内容はバイト単位で行われます。 ジャクソン2が書いたであろうもの。それはテストでカバーされているため、真実のままです。
Jackson 2 の削除モジュールを追加して も、それ自体では Jackson 2 は削除されません。通常の推移的なものとして到着します。
依存関係があり、この 2 つは無期限に共存できます。それをなくしたければ、通常はそうすることができますが、 このモジュールが存在すると、LangChain4j は Jackson 2 クラスをロードしなくなるためです。 実際に終了できるかどうかは、使用するモジュールによって異なります。
| モジュール | ジャクソン2は除外できるのか? |
|---|---|
langchain4j-core、langchain4j | はい - Jackson 2 コーデックが同梱されていますが、これらはフォールバックであり、このモジュールがクラスパス上にある間はロードされません。 |
| プロバイダー モジュール — OpenAI、Anthropic、Mistral、Ollama、Gemini、その他 | はい |
| 埋め込みストア、Web 検索、コード実行 | はい |
langchain4j-agentic | はい |
langchain4j-mcp | はい、1.23.0 以降 |
langchain4j-mcp-docker | いいえ、Docker と通信するために使用される docker-java は Jackson 2 に依存しています。 |
langchain4j-guardrails | いいえ - JsonExtractorOutputGuardrail は、ガードレールが以前と同じように厳格であるように、意図的に通常の Jackson 2 ObjectMapper で解析します。 |
langchain4j-vespa | いいえ - HTTP クライアントは Retrofit 独自の Jackson 2 コンバータを使用します。 |
| ベンダー SDK を使用するものすべて — AWS、Azure、Google | いいえ、SDK は Jackson 2 自体に依存しています。 |
| Maven の除外は、記述されている依存関係に適用されるため、すべての LangChain4j に適用されます。 | |
| 最初の依存関係だけでなく、宣言した依存関係: |
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>1.23.0</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- and the same on langchain4j-open-ai, and on any other LangChain4j module you use -->