LLM統合

Goa-AIがプロバイダー非依存インターフェースとアダプターモジュールを通じてLLMプロバイダーと統合する方法。

Goa-AIプランナーはプロバイダー非依存インターフェースを通じて大規模言語モデル(LLM)と対話します。この設計により、プランナーコードを変更せずにプロバイダー(AWS Bedrock、OpenAI、またはカスタムエンドポイント)を交換できます。

model.Clientインターフェース

すべてのLLMインタラクションはgoa.design/goa-ai/runtime/agent/modelで定義されたmodel.Clientインターフェースを通じて行われます:

type Client interface {
    // Completeは非ストリーミングモデル呼び出しを実行します。
    Complete(ctx context.Context, req Request) (Response, error)

    // Streamはサポートされている場合、ストリーミングモデル呼び出しを実行します。
    Stream(ctx context.Context, req Request) (Streamer, error)
}

プランナーは同期補完にCompleteを、増分応答にStreamを呼び出します。ランタイムはアダプターを通じてツールエンコーディング、トランスクリプト管理、プロバイダー固有の癖を処理します。

プランナーでのモデルクライアントの使用

プランナーはランタイムのPlannerContextを通じてモデルクライアントを取得します:

func (p *MyPlanner) PlanStart(ctx context.Context, input *planner.PlanInput) (*planner.PlanResult, error) {
    // ランタイムからモデルクライアントを取得
    mc := input.Agent.ModelClient("anthropic.claude-3-5-sonnet-20241022-v2:0")
    
    req := model.Request{
        RunID:    input.Run.RunID,
        Messages: input.Messages,
        Tools:    input.Tools,
        Stream:   true,
    }
    
    streamer, err := mc.Stream(ctx, req)
    if err != nil {
        return nil, err
    }
    defer streamer.Close()
    
    // ストリームをドレインして応答を構築...
}

ランタイムは基礎となるmodel.Clientをイベントデコレートクライアントでラップし、ストリームから読み取るにつれてプランナーイベント(思考ブロック、アシスタントチャンク、使用状況)を発行します。

プロバイダーアダプター

Goa-AIには人気のLLMプロバイダー用アダプターが同梱されています。各アダプターはmodel.Clientを実装し、以下を処理します:

  • メッセージエンコーディング
  • ツールスキーマ
  • 名前サニタイズ
  • ストリーミング
  • 思考

AWS Bedrock

import (
    "github.com/aws/aws-sdk-go-v2/service/bedrockruntime"
    "goa.design/goa-ai/features/model/bedrock"
)

awsClient := bedrockruntime.NewFromConfig(cfg)
modelClient, err := bedrock.New(awsClient, bedrock.Options{
    DefaultModel: "anthropic.claude-3-5-sonnet-20241022-v2:0",
    HighModel:    "anthropic.claude-sonnet-4-20250514-v1:0",
    SmallModel:   "anthropic.claude-3-5-haiku-20241022-v1:0",
    MaxTokens:    4096,
    Temperature:  0.7,
}, ledger)

OpenAI

import "goa.design/goa-ai/features/model/openai"

// APIキーから
modelClient, err := openai.NewFromAPIKey(apiKey, "gpt-4o")

次のステップ