LlmTornado 소개 - 100개 이상의 LLM API를 사용하여 AI 시스템을 구축하는 .NET 라이브러리


LlmTornado: .NET AI 시스템 구축을 위한 통합 라이브러리

개요

LlmTornado는 .NET 환경에서 AI 에이전트와 멀티 에이전트 시스템을 빠르게 구축할 수 있는 통합 도구킷입니다. 50,000+ NuGet 설치 수를 기록하며, 상업적 프로젝트에서 월 1,000억 개 이상의 토큰을 처리하는 검증된 라이브러리입니다.

핵심 특징

1. 광범위한 프로바이더 지원

  • 지원 프로바이더: Anthropic, Azure, Cohere, DeepInfra, DeepSeek, Google, Groq, Mistral, Ollama, OpenAI, OpenRouter, Perplexity, Voyage, xAI
  • 통합 인터페이스: 모델명만 알면 모든 프로바이더 사용 가능
  • 자동 프로바이더 매핑: 모델에 따라 적절한 API 키 자동 선택

2. 로컬 배포 지원

  • vLLM, Ollama, LocalAI 완전 지원
  • 요청 변환 통합 지원
  • 커스텀 프로바이더 구성 가능

3. 멀티모달 기능

  • 지원 형식: 텍스트, 이미지, 비디오, 문서, URL, 오디오
  • 통합 처리: 모든 입력 형식에 대한 단일 인터페이스
  • 스트리밍 지원: 실시간 처리 가능

4. 엔터프라이즈 준비

  • 요청 미리보기: 커밋 전 요청 내용 확인
  • 자동 비밀 삭제: 출력에서 민감 정보 자동 제거
  • 안정적 API: 일관된 인터페이스 제공

설치 및 설정

기본 설치

dotnet add package LlmTornado.Toolkit

선택적 애드온

# Model Context Protocol 통합
dotnet add package LlmTornado.Mcp

# 생산성 향상 도구
dotnet add package LlmTornado.Contrib

기본 구성

TornadoApi api = new TornadoApi([
    new (LLmProviders.OpenAi, "OPEN_AI_KEY"),
    new (LLmProviders.Anthropic, "ANTHROPIC_KEY"),
    new (LLmProviders.Cohere, "COHERE_KEY"),
    new (LLmProviders.Google, "GOOGLE_KEY"),
    new (LLmProviders.Groq, "GROQ_KEY"),
    new (LLmProviders.DeepSeek, "DEEP_SEEK_KEY"),
    new (LLmProviders.Mistral, "MISTRAL_KEY"),
    new (LLmProviders.XAi, "XAI_KEY"),
    new (LLmProviders.Perplexity, "PERPLEXITY_KEY"),
    new (LLmProviders.Voyage, "VOYAGE_KEY"),
    new (LLmProviders.DeepInfra, "DEEP_INFRA_KEY"),
    new (LLmProviders.OpenRouter, "OPEN_ROUTER_KEY")
]);

사용법

1. 기본 추론

string response = await api.Chat.CreateConversation("gpt-4o")
    .AppendSystemMessage("You are a fortune teller.")
    .AppendUserInput("What will my future bring?")
    .GetResponse();

2. 다중 모델 활용

List<ChatModel> models = [
    ChatModel.OpenAi.O3.Mini, 
    ChatModel.Anthropic.Claude37.Sonnet,
    ChatModel.Cohere.Command.RPlus, 
    ChatModel.Google.Gemini.Gemini2Flash001
];

foreach (ChatModel model in models)
{
    string response = await api.Chat.CreateConversation(model)
        .AppendSystemMessage("You are a fortune teller.")
        .AppendUserInput("What will my future bring?")
        .GetResponse();
}

3. 벤더 확장 기능

Anthropic Claude 3.7 추론 예산 설정:

Conversation chat = Program.Connect(LLmProviders.Anthropic).Chat.CreateConversation(new ChatRequest
{
    Model = ChatModel.Anthropic.Claude37.Sonnet,
    VendorExtensions = new ChatRequestVendorExtensions(new ChatRequestVendorAnthropicExtensions
    {
        Thinking = new AnthropicThinkingSettings
        {
            BudgetTokens = 2_000,
            Enabled = true
        }
    })
});

4. 셀프 호스팅/커스텀 프로바이더

Ollama 스트리밍 예제:

TornadoApi api = new TornadoApi(new Uri("http://localhost:11434"));

await api.Chat.CreateConversation(new ChatModel("falcon3:1b"))
    .AppendUserInput("Why is the sky blue?")
    .StreamResponse(Console.Write);

커스텀 헤더 구성:

TornadoApi tornadoApi = new TornadoApi(new AnthropicEndpointProvider
{
    Auth = new ProviderAuthentication("ANTHROPIC_API_KEY"),
    UrlResolver = (endpoint, url, ctx) => "https://api.anthropic.com/v1/{0}{1}",
    RequestResolver = (request, data, streaming) => { /* 커스텀 로직 */ },
    RequestSerializer = (data, ctx) => { /* 데이터 변환 로직 */ }
});

고급 기능

스트리밍 지원

1. 기본 스트리밍

await api.Chat.CreateConversation(ChatModel.Anthropic.Claude3.Sonnet)
    .AppendSystemMessage("You are a fortune teller.")
    .AppendUserInput("What will my future bring?")
    .StreamResponse(Console.Write);

2. 리치 콘텐츠 스트리밍

await chat.StreamResponseRich(new ChatStreamEventHandler
{
    MessagePartHandler = async (part) =>
    {
        if (part.Text is not null)
            Console.Write(part.Text);
        if (part.Image is not null)
            await DisplayImage(part.Image.Url);
    },
    OnUsageReceived = (usage) => Console.WriteLine(usage)
});

도구(Tools) 활용

1. 즉시 해결 도구

ChatStreamEventHandler handler = new ChatStreamEventHandler
{
    MessageTokenHandler = (x) => Console.Write(x),
    FunctionCallHandler = (calls) =>
    {
        calls.ForEach(x => x.Result = new FunctionResult(x, "A mild rain is expected around noon.", null));
    },
    AfterFunctionCallsResolvedHandler = async (results, handler) => 
    { 
        await chat.StreamResponseRich(handler); 
    }
};

2. 지연 해결 도구

Conversation chat = api.Chat.CreateConversation(new ChatRequest
{
    Model = ChatModel.OpenAi.Gpt4.Turbo,
    Tools = new List<Tool> { new Tool { Function = new ToolFunction("get_weather", "gets the current weather") } },
    ToolChoice = new OutboundToolChoice(OutboundToolChoiceModes.Required)
});

ChatRichResponse response = await chat.GetResponseRich();

Model Context Protocol (MCP) 통합

MCP 서버 도구 정의

[McpServerToolType]
public sealed class WeatherTools
{
    [McpServerTool, Description("Get weather forecast for a location.")]
    public static async Task<string> GetForecast(
        HttpClient client,
        [Description("Latitude of the location.")] double latitude,
        [Description("Longitude of the location.")] double longitude)
    {
        // 날씨 API 호출 로직
    }
}

MCP 클라이언트 사용법

// 1. MCP 클라이언트 생성
await using IMcpClient mcpClient = await McpClientFactory.CreateAsync(clientTransport);

// 2. 도구 목록 가져오기
List<Tool> tools = await mcpClient.ListTornadoToolsAsync();

// 3. 대화 생성 및 도구 사용
Conversation conversation = api.Chat.CreateConversation(new ChatRequest
{
    Model = ChatModel.OpenAi.Gpt41.V41,
    Tools = tools,
    ToolChoice = OutboundToolChoice.Required
});

// 4. 모델이 도구를 호출하고 결과 처리
await conversation
    .AddSystemMessage("You are a helpful assistant")
    .AddUserMessage("What is the weather like in Dallas?")
    .GetResponseRich(async calls =>
    {
        foreach (FunctionCall call in calls)
        {
            await call.ResolveRemote(new { latitude = 32.7767, longitude = -96.7970 });
        }
    });

툴킷 기능

ToolkitChat

그래프 기반 워크플로우 지원:

class DemoAggregatedItem
{
    public string Name { get; set; }
    public string KnownName { get; set; }
    public int Quantity { get; set; }
}

await ToolkitChat.GetSingleResponse(
    Program.Connect(), 
    ChatModel.Google.Gemini.Gemini25Flash, 
    ChatModel.OpenAi.Gpt41.V41Mini, 
    "aggregate items by type",
    new ChatFunction([
        new ToolParam("items", new ToolParamList("aggregated items", [
            new ToolParam("name", "name of the item", ToolParamAtomicTypes.String),
            new ToolParam("quantity", "aggregated quantity", ToolParamAtomicTypes.Int),
            new ToolParam("known_name", new ToolParamEnum("known name of the item", 
                [ "apple", "cherry", "orange", "other" ]))
        ]))
    ]), 
    userPrompt
);

실용적인 활용 사례

1. 문서와 대화

  • PDF, 워드 문서 등과 자연어 대화
  • 문서 내용 검색 및 요약

2. 다중 화자 팟캐스트 생성

  • AI를 활용한 자동 팟캐스트 콘텐츠 생성
  • 다양한 목소리와 톤 구현

3. 음성 통화

  • 마이크를 통한 실시간 AI와 음성 대화
  • 음성 인식 및 합성 통합

4. 어시스턴트 오케스트레이션

  • 여러 전문 AI 어시스턴트 협업
  • 작업 분배 및 결과 통합

5. 이미지 생성 및 처리

  • 텍스트로부터 이미지 생성
  • 이미지 분석 및 편집

6. 비디오 요약

  • 로컬 파일 및 YouTube 비디오 자동 요약
  • 핵심 내용 추출 및 정리

7. 고품질 임베딩

  • 텍스트와 이미지를 벡터로 변환
  • 의미 기반 검색 구현

8. 실시간 음성 인식

  • 실시간 오디오 전사
  • 다국어 지원

성능 및 안정성

검증된 성능

  • 50,000+ NuGet 설치
  • 월 1,000억+ 토큰 처리
  • 250+ 테스트 커버리지
  • 상업적 프로젝트에서 검증

최적화 기능

  • 요청 성공률 최대화: 모델별 지원 매개변수 자동 추적
  • 자동 요청 최적화: 프로바이더 규칙에 맞게 요청 자동 수정
  • 추론 컨텍스트 관리: 모델별 최적 컨텍스트 길이 관리

안정성 보장

  • MIT 라이선스: 영구 불변 라이선스
  • 안정적 API: 하위 호환성 보장
  • 엔터프라이즈 지원: 상업적 사용 완전 지원

주요 프로젝트 사례

상업적 활용 사례

  • ScioBot: 교육자를 위한 AI (100k+ 사용자)
  • LombdaAgentSDK: 모듈형 에이전트 생성을 위한 경량 C# SDK
  • NotT3Chat: T3 스택의 C# 버전
  • ClaudeCodeProxy: 프로바이더 멀티플렉싱 프록시
  • Semantic Search: 컨텍스트와 의미 기반 AI 검색
  • Monster Collector: AI 생성 몬스터 데이터베이스

기여 및 라이선스

기여 방법

  • 새로운 프로바이더 구현 환영
  • Feature Matrix 100% 달성을 위한 기여
  • 새로운 추상화 제안 (공개 토론 후)

라이선스

  • MIT 라이선스 적용
  • 영구 불변: 라이선스 변경 없음 보장
  • 상업적 사용 가능: 제한 없는 상업적 활용

추가 리소스

공식 웹사이트

GitHub 저장소

관련 태그

  • AI, 추론 엔진, 멀티모달, 로컬 LLM
  • Google API, Azure API, OpenAI API
  • Anthropic API, Cohere API, Ollama API
  • Mistral API, Perplexity API, Groq API

주의사항

사용 시 고려사항

  • API 키 관리: 각 프로바이더별 적절한 API 키 필요
  • 모델별 제한: 각 모델의 토큰 제한 및 기능 차이 고려
  • 네트워크 의존성: 대부분의 기능이 인터넷 연결 필요
  • 비용 관리: 프로바이더별 사용 비용 모니터링 필요

성능 최적화 팁

  • 적절한 모델 선택: 작업에 맞는 최적 모델 사용
  • 배치 처리: 대량 요청 시 배치 처리 고려
  • 캐싱 활용: 반복적인 요청에 대한 결과 캐싱
  • 스트리밍 사용: 긴 응답에서 사용자 경험 향상