원클릭으로
add-infrastructure-adapter
新しい外部サービス接続を追加する際に使用する。LLMプロバイダ、キャッシュバックエンド、外部APIなどのinfrastructure層実装の追加手順に従う。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
新しい外部サービス接続を追加する際に使用する。LLMプロバイダ、キャッシュバックエンド、外部APIなどのinfrastructure層実装の追加手順に従う。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Skillsやプロンプトの再現性を改善する際に使用する。固定シナリオ、別AI実行、両面評価、1反復1テーマ、hold-out検証、停止条件に基づいて反復する。
このプロジェクトでテストコードを作成する際に使用する。テーブル駆動テスト、モック作成、検証観点のパターンに従う。
新機能や変更の設計判断について相談する際に使用する。どの層に配置すべきか、インターフェースの分割、既存サービスの拡張か新規作成かなどの判断を支援する。
このプロジェクトに新機能を実装する際に使用する。クリーンアーキテクチャの層構造に沿ったファイル配置、命名規則、実装パターンに従う。
| name | add-infrastructure-adapter |
| description | 新しい外部サービス接続を追加する際に使用する。LLMプロバイダ、キャッシュバックエンド、外部APIなどのinfrastructure層実装の追加手順に従う。 |
外部サービスとの接続を追加する際のパターンを示す。既存の実装として、LLMプロバイダ(gemini/noop)、キャッシュ(SQLite/メモリ)、Misskey API、RSS取得がある。
LLMプロバイダを追加する場合、ファクトリパターンに従う。
事前に次を確定する。
プロバイダ名はLLM_PROVIDERに設定する小文字値を使う(例: gemini, bedrock)。
上記3点が未確定なら実装を開始しない。特に必須設定項目は「変数名」「必須/任意」「default値」を表で先に決める。
実装開始ゲート:
プロバイダ名必須/任意/デフォルト表失敗時の扱いこの3点がそろうまでコード変更しない。
このプロジェクトでは分岐キーにLLM_PROVIDERを使う。値はcfg.GetLLMConfig().Providerを経由してllm.Config.Providerに渡され、internal/infrastructure/llm/summarizer.goのswitch cfg.Providerで選択される。
このプロジェクトではLLM関連設定をinternal/interfaces/config/config.goで一元管理する。LLM_REGIONのような項目をconfigに置くことは本プロジェクトの規約上許容する。
このSkillの対象は「単一の有効プロバイダ選択」のみ。複数プロバイダ同時初期化や実行時切り替えは対象外。
実装するメソッドシグネチャ:
Summarize(ctx context.Context, url, title string) (string, error)IsEnabled() boolcase追加の最小例:
switch cfg.Provider {
case "gemini":
return newGeminiSummarizer(ctx, cfg)
case "bedrock":
return newBedrockSummarizer(ctx, cfg)
case "myprovider":
return newMyproviderSummarizer(ctx, cfg)
case "noop", "":
return newNoopSummarizer(), nil
default:
return nil, fmt.Errorf("unknown LLM provider: %s", cfg.Provider)
}
llm.Configの対象フィールド:
Provider stringAPIKey stringModel stringRegion stringMaxTokens intSystemInstruction stringTimeout time.Durationllm.Configはinternal/infrastructure/llm/summarizer.goに既存定義があるため、新規に重複定義しない。
環境変数名は既存規約のLLM_*を使う。
config.goの追加例:
LLMProvider string `envconfig:"LLM_PROVIDER" default:""`
LLMAPIKey string `envconfig:"LLM_API_KEY"`
LLMModel string `envconfig:"LLM_MODEL"`
LLMRegion string `envconfig:"LLM_REGION" default:""`
LLMTimeout int `envconfig:"LLM_TIMEOUT" default:"30"`
必須/任意の判定手順:
requiredとしてconfig.goに追加するGetLLMConfig()に全項目を追加するエラーはfmt.Errorf("...: %w", err)でラップして返す。
required判定はenvconfigのrequiredタグではなく、プロバイダごとにコンストラクタ内で行う。
required判定の最小例:
if cfg.Model == "" {
return nil, fmt.Errorf("myprovider model is required")
}
main.goでは次の順で配線する。
llmCfg := cfg.GetLLMConfig()llm.NewSummarizerRepository(ctx, llm.Config{...})にllmCfgの各フィールドを明示的にマッピングnoopへフォールバックnoopフォールバックも失敗した場合は警告を出力し、要約機能なしで継続するllmCfg.TimeoutはGetLLMConfig()で秒からtime.Durationへ変換済みの値をそのまま渡す。
配線の最小例:
llmCfg := cfg.GetLLMConfig()
summarizerRepo, err := llm.NewSummarizerRepository(ctx, llm.Config{
Provider: llmCfg.Provider,
APIKey: llmCfg.APIKey,
Model: llmCfg.Model,
Region: llmCfg.Region,
MaxTokens: llmCfg.MaxTokens,
Timeout: llmCfg.Timeout,
SystemInstruction: llmCfg.SystemInstruction,
})
if err != nil {
log.Printf("Warning: LLM initialization failed: %v", err)
log.Println("Attempting fallback to noop summarizer...")
summarizerRepo, err = llm.NewSummarizerRepository(ctx, llm.Config{Provider: "noop"})
if err != nil {
log.Printf("Warning: noop summarizer initialization failed: %v", err)
log.Println("Continuing without summarization feature")
}
}
コンストラクタはエクスポートせず先頭小文字で定義する。Configから必要なフィールドを取得し、不足する場合はエラーを返す。タイムアウトはcontext.WithTimeoutで制御する。
context.WithTimeoutはSummarizeメソッド内で適用する。
タイムアウトのデフォルト値は各アダプタのコンストラクタで適用する。既存実装に合わせてcfg.Timeout == 0の場合は30 * time.Secondを設定し、Summarize内で固定値を再定義しない。
最小例:
func (s *myProviderSummarizer) Summarize(ctx context.Context, url, title string) (string, error) {
ctx, cancel := context.WithTimeout(ctx, s.timeout)
defer cancel()
return "", nil
}
IsEnabled()は有効な要約器でtrueを返し、無効化用実装(noop)でfalseを返す。
IsEnabled()はinternal/application/rss_feed_service.goから参照される。
noopフォールバック失敗時の扱い:
LLMプロバイダ初期化はmain.goで起動時に行われる。第一選択プロバイダが失敗した場合、noopサマライザーへフォールバックする。noopフォールバックも失敗した場合は警告を出力し、要約機能なしで継続する。
llm.Configへのマッピングに追加の一時Config構造体は作らない。
repository.SummarizerRepositoryは既存インターフェースを使い、新規定義しない。
タイムアウト値はinternal/interfaces/config/config.goのLLM_TIMEOUT(default 30秒)をGetLLMConfig()経由で渡す。新しいアダプタ実装では、Summarize内で固定値を新規定義しない。既存プロバイダ実装にあるcfg.Timeout == 0時の30秒フォールバックは互換性維持の防御策として許容する。
既存プロバイダの必須項目例:
LLM_API_KEY, LLM_MODELLLM_MODEL, LLM_REGIONテストは{プロバイダ名}_summarizer_test.goを追加し、最低限次を検証する。
テスト時の外部API呼び出しはhttptestまたは差し替え可能なクライアントインターフェースでモックし、実ネットワークに依存しない。
モック方式はhttptestを第一選択とし、SDKの都合で難しい場合のみクライアントインターフェース差し替えを使う。
テストはテーブル駆動で記述する。
io.Closerの実装が必要な場合はClose() errorメソッドも追加する。CleanupOldGUIDsのようなバックエンド固有のメソッドはmain.goで型アサーションして使用する。
接続先やAPIキーなどの実装固有の設定は、infrastructure層内にConfig構造体を定義する。LLMプロバイダに限ってはinternal/interfaces/config/config.goで一元管理する。internal/interfaces/config/config.goの設定からinfrastructure層のConfigへの変換はmain.goで行う。