プラグインの作成¶
プラグインを利用すると、プロバイダーやフレームワークへの依存をコアパッケージの外に保てます。公開プロトコルはSource、Ranker、Policy、Renderer、PythonTokenizerです。
Ranker¶
import cognoxium as cx
class KeywordRanker:
fingerprint = "keyword-v1"
def score_batch(self, query, items):
query = query.casefold()
return [float(query in item.payload.text_value().casefold()) for item in items]
frame = cx.CognitionFrame.from_records([
{"id": "a", "payload": "release ready"},
{"id": "b", "payload": "work in progress"},
])
ranked = frame.rank("release", ranker=KeywordRanker())
print(ranked.explain())
Scan[context records] -> Rank[keyword-v1]
ランカーは、項目ごとに1つの数値スコアを返す必要があります。結果の件数が不正な場合や数値でない結果は、PluginErrorになります。
Policy(ポリシー)¶
class RejectUntrustedExternally:
id = "example.reject-untrusted.v1"
def evaluate(self, item, boundary):
if boundary.kind == "external" and item.trust is cx.Trust.UNTRUSTED:
return "untrusted_source"
return None
pack = frame.pack(
budget=100,
boundary=cx.Boundary.external("provider"),
policies=[RejectUntrustedExternally()],
)
ポリシーは項目ごとに1回呼び出され、安定した理由コードまたはNoneを返します。この項目単位のメソッドでネットワークを呼び出さないでください。認証とレコードへの情報追加は、パッキング前に済ませます。
Source(ソース)¶
Source.load()は、レコードマッピングのイテラブルを返します。完全なStaticSourceの例はCognitionFrameの構築を参照してください。Source IDはアダプターを識別しますが、返される各項目にも意味のあるsourcesフィールドが必要です。
Renderer(レンダラー)¶
class IdRenderer:
id = "ids-v1"
def render(self, pack):
return [item.id for item in pack.items]
ids = pack.render(IdRenderer())
レンダラーはイミュータブルなContextPackを受け取ります。未対応のペイロードを黙って文字列化せず、拒否しなければなりません。
Pythonトークナイザーによる代替処理¶
class WordTokenizer:
fingerprint = "words-v1"
thread_safe = True
def count_batch(self, values):
return [len(value.split()) for value in values]
profile = cx.profiles.huggingface(
WordTokenizer(),
profile_id="example:words-v1",
)
Pythonによるトークン化は低速な代替処理であるため、初回使用時にPerformanceWarningが通知されます。count_batch()は、各値につき1つの非負整数を返す必要があります。
再現性の契約¶
同じフィンガープリントを使うプラグインは、決定論的でなければなりません。コード、語彙、モデル、設定、エンベロープの計上方法、リモートサービスのバージョンによって結果が変わり得る場合は、必ずフィンガープリントも変更してください。フィンガープリントが外部状態を正しく識別しているかを、Cognoxiumが検証することはできません。