FessのAI検索モードを利用した検索が、検索ログ上ではどのモデルで処理されたのか区別できなかった。そこで、AI検索モードのエンドポイントの検索ログにLLMモデル名をアクセスタイプとして記録するようにした。
背景
Fessの検索ログには、検索がどのインターフェースから行われたかを示す「アクセスタイプ」が記録される。従来は以下の定義済みタイプのみが使われていた。
WEB— Web画面からの検索JSON— JSON APIからの検索XML— XML(GSA互換)APIからの検索ADMIN— 管理画面からの検索OTHER— その他
AI検索モード経由の検索もこの仕組みで記録されるが、これまではアクセスタイプが設定されていなかったため、デフォルトのWEBとして扱われていた。これでは、通常のWeb検索とAI検索モード経由の検索を検索ログから区別できない。
変更内容
ChatApiManagerでアクセスタイプを設定
ChatApiManagerのprocessChat()とprocessChatStream()の両メソッドで、リクエスト属性にLLMモデル名をアクセスタイプとして設定するようにした。
request.setAttribute(Constants.SEARCH_LOG_ACCESS_TYPE,
ComponentUtil.getFessConfig().getSystemProperty("rag.llm.name", "ollama"));
モデル名はシステムプロパティrag.llm.nameから取得する。未設定の場合は"ollama"がデフォルト値となる。
SearchLogHelperでカスタムアクセスタイプに対応
従来のSearchLogHelperでは、アクセスタイプの判定が定義済み定数との一致チェックのみだったため、LLMモデル名のような任意の文字列を扱えなかった。今回、定義済みタイプに一致しない場合でも、空でない文字列であればそのままアクセスタイプとして記録するように変更した。
protected String determineAccessType(final Object accessType) {
if (Constants.SEARCH_LOG_ACCESS_TYPE_JSON.equals(accessType)) {
return Constants.SEARCH_LOG_ACCESS_TYPE_JSON;
} else if (Constants.SEARCH_LOG_ACCESS_TYPE_GSA.equals(accessType)) {
return Constants.SEARCH_LOG_ACCESS_TYPE_GSA;
} else if (Constants.SEARCH_LOG_ACCESS_TYPE_OTHER.equals(accessType)) {
return Constants.SEARCH_LOG_ACCESS_TYPE_OTHER;
} else if (Constants.SEARCH_LOG_ACCESS_TYPE_ADMIN.equals(accessType)) {
return Constants.SEARCH_LOG_ACCESS_TYPE_ADMIN;
} else if (accessType instanceof String && StringUtil.isNotBlank((String) accessType)) {
return (String) accessType;
}
return Constants.SEARCH_LOG_ACCESS_TYPE_WEB;
}
SearchLogHelperのリファクタリング
あわせて、SearchLogHelperのaddSearchLog()メソッドをテストしやすい構造にリファクタリングした。
SearchLogContext内部クラスを導入し、ComponentUtilへの依存を分離addSearchLog()をcreateSearchLogContext()とcreateSearchLog()に分割determineAccessType()をprotectedメソッドとして抽出
これにより、モックコンポーネントの登録なしにアクセスタイプ判定のユニットテストが書けるようになった。
使い方
AI検索モードで使用するLLMのモデル名をrag.llm.nameシステムプロパティに設定する。
rag.llm.name=openai
この設定で、AI検索モード経由の検索ログのアクセスタイプがopenaiとして記録される。検索ログの分析時に、どのLLMモデルが使われた検索なのかを簡単に識別できるようになる。