Skip to main content
Published
Oct 22, 2026
2d ago
Total Downloads
116.1K
116,124

Install

dotnet add package IronHive.Providers.Anthropic --version 0.69.0
ProductVersions
.NET
net10.0

README

IronHive

IronHive๋Š” ๊ธฐ์—…์šฉ AI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ .NET 10 ํŒŒ์ดํ”„๋ผ์ธ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. HiveServiceBuilder ๋กœ ๋ฉ€ํ‹ฐ Provider LLM(OpenAI ยท Anthropic ยท Google AI ยท OpenAI ํ˜ธํ™˜)์„ ๋“ฑ๋กํ•˜๊ณ , IHiveService ๋กœ ์—์ด์ „ํŠธ ยท ๋ฉ€ํ‹ฐ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์”๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅ

  • ๋ฉ€ํ‹ฐ Provider LLM โ€” OpenAI, Anthropic, Google AI (Gemini/Vertex AI), OpenAI Compatible (Ollama, LM Studio, GPUStack ๋“ฑ). HiveServiceBuilder ์— ์ด๋ฆ„์„ ๋ถ™์—ฌ ๋“ฑ๋กํ•œ๋‹ค: AddOpenAIProviders ยท AddAnthropicProviders ยท AddGoogleAIProviders ยท AddVertexAIProviders ยท AddOpenAICompatibleProviders ยท AddGpuStackProviders(๊ฐ provider ํŒจํ‚ค์ง€). ๋งˆ์ง€๋ง‰ ์ธ์ž โ€ฆServiceType ํ”Œ๋ž˜๊ทธ(๊ธฐ๋ณธ All)๋กœ ๋“ฑ๋กํ•  ์„œ๋น„์Šค(๋ชจ๋ธ ๋ชฉ๋กยท๋ฉ”์‹œ์ง€ยท์ž„๋ฒ ๋”ฉยท์ด๋ฏธ์ง€ยท์˜ค๋””์˜ค ๋“ฑ)๋ฅผ ๊ณ ๋ฅธ๋‹ค. ์—์ด์ „ํŠธ๋Š” hive.CreateAgentFrom(cfg => โ€ฆ) ยท CreateAgentFromYaml(yaml)(docs/AGENTS.md)
  • ๋ชจ๋ธ ๋ชฉ๋ก์˜ ํ•œ๋„ โ€” IModelFinder.ListModelsAsync/FindModelAsync ๊ฐ€ ๋ชฉ๋ก API ๊ฐ€ ์•Œ๋ ค ์ฃผ๋Š” ์ปจํ…์ŠคํŠธ์™€ ์ตœ๋Œ€ ์ถœ๋ ฅ์„ LanguageModelCard.ContextWindowยทMaxOutputTokens ๋กœ ์‹ฃ๋Š”๋‹ค(Google AI inputTokenLimitยทoutputTokenLimit, Anthropic max_input_tokensยทmax_tokens, OpenAI ์™€์ด์–ด ์„œ๋ฒ„ยท๊ฒŒ์ดํŠธ์›จ์ด์˜ max_model_lenยทcontext_lengthยทcontext_windowยทmax_completion_tokensยทtop_provider.* โ€” OpenAIModelFinderยทOpenAICompatibleModelFinder, ๋“ฑ๋ก ์‹œ ์ž๋™). ์•Œ๋ ค ์ฃผ์ง€ ์•Š๋Š” ์„œ๋ฒ„๋Š” null
  • ์‚ฌ์šฉ๋Ÿ‰ ๋‚ด์—ญ โ€” MessageTokenUsage ๊ฐ€ ์ž…๋ ฅยท์ถœ๋ ฅ ํ•ฉ๊ณ„ ์™ธ์— ์บ์‹œ ์ฝ๊ธฐ(CachedInputTokens), ์บ์‹œ ์“ฐ๊ธฐ(CacheWriteInputTokens)์™€ ๊ทธ TTL ๋ณ„ ๋‚ด์—ญ(CacheWritesByTtl โ€” Anthropic 5๋ถ„/1์‹œ๊ฐ„), ์ถ”๋ก  ํ† ํฐ(ReasoningTokens)์„ ๊ณต๊ธ‰์ž๊ฐ€ ๋ณด๊ณ ํ•˜๋Š” ๋งŒํผ ์‹ฃ๋Š”๋‹ค โ€” ๊ณต๊ธ‰์ž๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๋งค๊ธฐ๋Š” ๋ถ€๋ถ„์„ ์†Œ๋น„์ž๊ฐ€ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค. M.E.AI ์–ด๋Œ‘ํ„ฐ๋Š” UsageDetails.ReasoningTokenCount ์™€ AdditionalCounts[ChatClientAdapter.CacheWriteInputTokenCountKey] ๋กœ ์˜ฎ๊ธด๋‹ค
  • Anthropic ํ”„๋กฌํ”„ํŠธ ์บ์‹ฑ โ€” AnthropicConfig.PromptCaching(๊ธฐ๋ณธ FiveMinutes): ์š”์ฒญ๋งˆ๋‹ค ์ตœ์ƒ์œ„ cache_control(์ž๋™ ์บ์‹ฑ)์„ ์‹ค์–ด API ๊ฐ€ ๋งˆ์ง€๋ง‰ ์บ์‹œ ๊ฐ€๋Šฅ ๋ธ”๋ก์— ๋ธŒ๋ ˆ์ดํฌํฌ์ธํŠธ๋ฅผ ๋‘๊ฒŒ ํ•œ๋‹ค โ€” ๋„๊ตฌ ๋ฃจํ”„ยท๋‹คํšŒ ๋Œ€ํ™”์˜ ๋‹ค์Œ ์š”์ฒญ์ด ๊ฐ™์€ ์ ‘๋‘๋ฅผ ์บ์‹œ ์ฝ๊ธฐ ๋‹จ๊ฐ€๋กœ ์ฝ๋Š”๋‹ค. OneHour ๋Š” 1์‹œ๊ฐ„ ์ˆ˜๋ช…, Off ๋Š” ๋ˆ๋‹ค. ๋ชจ๋ธ ์ตœ์†Œ ๊ธธ์ด(512~4,096 ํ† ํฐ)๋ณด๋‹ค ์งง์€ ํ”„๋กฌํ”„ํŠธ๋Š” ์บ์‹œ๋˜์ง€ ์•Š๋Š”๋‹ค
  • ๋ฉ€ํ‹ฐ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ โ€” SequentialOrchestrator ยท ParallelOrchestrator ยท HubSpokeOrchestrator(๊ฐ์ž์˜ โ€ฆOrchestratorOptions ๋กœ ์ƒ์„ฑ), HandoffOrchestratorBuilder ยท GroupChatOrchestratorBuilder ยท GraphOrchestratorBuilder(DAG). ๊ณตํ†ต ์˜ต์…˜ โ€” ํƒ€์ž„์•„์›ƒ ยท StopOnAgentFailure ยท ์—์ด์ „ํŠธ ๋ฏธ๋“ค์›จ์–ด ยท ์Šน์ธ ํ•ธ๋“ค๋Ÿฌ ยท ์ปจํ…์ŠคํŠธ ์Šค์ฝ”ํ”„ ยท ๊ฒฐ๊ณผ distiller โ€” ์€ ์˜ต์…˜ ๊ฐ์ฒด ๋˜๋Š” ๋นŒ๋”์˜ Setโ€ฆ ์œผ๋กœ ์ค€๋‹ค(docs/ORCHESTRATION.md)
  • ๋ฌธ์„œ ์ฒ˜๋ฆฌ๋Š” ์ด ํŒจํ‚ค์ง€์— ์—†๋‹ค โ€” ๋ฌธ์„œ ํŒŒ์‹ฑ์€ FileFlux, ์ ์žฌยท์ฒญํ‚นยท๋ฒกํ„ฐ ๊ฒ€์ƒ‰ ๊ฐ™์€ RAG ํŒŒ์ดํ”„๋ผ์ธ์€ FluxIndexยทFluxFeed ๋ฅผ ์“ด๋‹ค
  • ๋ฆฌ๋žญํ‚น โ€” hive.Rerank. OpenAI Compatible ยท GPUStack ์˜ Rerank ์„œ๋น„์Šค ํƒ€์ž…(Cohere ํ˜•ํƒœ /rerank)์ด ๋“ฑ๋กํ•œ๋‹ค
  • ๋‹ค์ค‘ ๋ชจ๋‹ฌ๋ฆฌํ‹ฐ โ€” ์ด๋ฏธ์ง€ ์ƒ์„ฑ(hive.Images), ์Œ์„ฑ TTS/STT(hive.Audio), ๋น„๋””์˜ค ์ƒ์„ฑ(hive.Videos). ํ•ด๋‹น ์„œ๋น„์Šค๋ฅผ ๊ฐ€์ง„ provider ๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๋”ฐ๋ผ์˜จ๋‹ค(OpenAI ยท OpenAI Compatible ยท GPUStack: ์ด๋ฏธ์ง€ยท์˜ค๋””์˜ค, Google AI/Vertex AI: ์ด๋ฏธ์ง€ยท๋น„๋””์˜คยท์˜ค๋””์˜ค)
  • ํ”Œ๋Ÿฌ๊ทธ์ธ โ€” MCP: McpClientManager.AddOrUpdate(new McpHttpClientConfig{โ€ฆ} / McpStdioClientConfig{โ€ฆ}) ๋กœ ์„œ๋ฒ„๋ฅผ ๋ถ™์ด๊ณ  ์„ธ์…˜์˜ ๋„๊ตฌ๋ฅผ ์—์ด์ „ํŠธ ๋„๊ตฌ์— ๋”ํ•œ๋‹ค(HTTP/Stdio/OAuth)(docs/PLUGINS.md)
  • M.E.AI ํ˜ธํ™˜ โ€” ํŒจํ‚ค์ง€ IronHive.Extensions.AI(์˜์กด: Abstractions ๋ฟ โ€” Core ์—†์ด provider ๋ฅผ IChatClient ๋กœ): generator.AsChatClient(model, provider) ยท AsEmbeddingGenerator(model[, dimensions])(์ฐจ์›์„ ์ฃผ๋ฉด EmbeddingGeneratorMetadata.DefaultModelDimensions ๋กœ ์•Œ๋ฆฌ๊ณ  ๋ฒกํ„ฐ ํฌ๊ธฐ๋ฅผ ๊ฒ€์‚ฌ) ยท AIToolAdapter(์ž„์˜์˜ AITool์„ ITool๋กœ ๋ž˜ํ•‘ยท์‹คํ–‰ โ€” MCP McpClientTool ๋“ฑ). ๋„๊ตฌ ์ธ์ž ์ŠคํŠธ๋ฆฌ๋ฐ(opt-in): ChatOptions.AdditionalProperties[ChatClientAdapter.StreamToolArgumentsKey] = true ์ด๋ฉด ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์ด ์ธ์ž๋ฅผ ์“ฐ์ด๋Š” ๋™์•ˆ FunctionCallDeltaContent(CallId ยท ์ฒซ ์กฐ๊ฐ์˜ Name ยท ArgumentsFragment)๋กœ๋„ ๋‚ด๊ณ , ์™„์ „ํ•œ FunctionCallContent ๊ฐ€ ๋’ค๋”ฐ๋ฅธ๋‹ค(Chat CompletionsยทResponsesยทAnthropic โ€” Anthropic ์€ ์ด๋•Œ ๋„๊ตฌ๋งˆ๋‹ค eager_input_streaming ์„ ์ผœ์„œ ์„œ๋ฒ„๊ฐ€ ์ž…๋ ฅ์„ ๋๊นŒ์ง€ ๋ชจ์•˜๋‹ค ๋ณด๋‚ด์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค(MessageGenerationRequest.StreamToolArguments, ์„œ๋ฒ„ ๊ฒ€์ฆ ์—†์Œ). Google ์€ ํ˜ธ์ถœ์„ ํ•œ ๋ฒˆ์— ๋ณด๋‚ธ๋‹ค). using IronHive.Extensions.AI;
  • ์—์ด์ „ํŠธ ๋ฏธ๋“ค์›จ์–ด โ€” RetryMiddleware ยท TimeoutMiddleware ยท CircuitBreakerMiddleware ยท FallbackMiddleware ยท RateLimitMiddleware ยท BulkheadMiddleware ยท CachingMiddleware ยท LoggingMiddleware ยท CompositeMiddleware. opt-in: agent.WithMiddleware(โ€ฆ). ๋ฉ”์‹œ์ง€ ๋‹จ์œ„ ๋ฏธ๋“ค์›จ์–ด(์˜ˆ: ToolResultBudgetMiddleware)๋Š” HiveServiceBuilder.AddMessageMiddleware(โ€ฆ)(docs/MIDDLEWARE.md)
  • ํ•จ์ˆ˜ ๋„๊ตฌ โ€” tools.AddFunctionTool<T>()(๋˜๋Š” ์ธ์Šคํ„ด์Šคยท๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ์˜ค๋ฒ„๋กœ๋“œ)๋กœ .NET ๋ฉ”์„œ๋“œ๋ฅผ ์—์ด์ „ํŠธ ๋„๊ตฌ(IToolCollection)๋กœ ๋“ฑ๋ก(docs/TOOLS.md)
  • ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ โ€” ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ๊ฐ€ HiveTelemetry.SourceName("IronHive") ์ด๋ฆ„์˜ ActivitySource ยท Meter ๋กœ traceยทmetric ์„ ๋‚ธ๋‹ค. OpenTelemetry ์˜ AddSource/AddMeter ๋กœ ๊ตฌ๋…ํ•˜๋ฉด ์ผœ์ง„๋‹ค
  • ๊ตฌ์กฐํ™” ์ถœ๋ ฅ โ€” OutputFormat.For<T>()/For(schema) ๋Š” ์Šคํ‚ค๋งˆ๋กœ ๊ตฌ์†, OutputFormat.Json ์€ ์Šคํ‚ค๋งˆ ์—†๋Š” JSON ๋ชจ๋“œ(provider ๋„ค์ดํ‹ฐ๋ธŒ JSON ๋ชจ๋“œ๋กœ ๋ฒˆ์—ญ โ€” OpenAI json_object, Gemini responseMimeType, Anthropic ์€ ์‹œ์Šคํ…œ ์ง€์‹œ). AgentInvokeOptions.OutputFormat ๋˜๋Š” IChatClient ์˜ ChatOptions.ResponseFormat ์œผ๋กœ ์ผ ๋‹ค
  • ๋„๊ตฌ ๊ฒฐ๊ณผ ํ…์ŠคํŠธํ™” โ€” ToolOutput.ToText()๊ฐ€ ๊ฒฐ๊ณผ ๋ธ”๋ก์„ ๋ฌธ์ž์—ด ํ•˜๋‚˜๋กœ ํ‰ํƒ„ํ™”(ํ…์ŠคํŠธ๋Š” ์ค„๋ฐ”๊ฟˆ์œผ๋กœ, ํ…์ŠคํŠธ ์•„๋‹Œ ๋ธ”๋ก์€ [image content omitted] ๋˜๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ์ค€ ๋ฌธ๊ตฌ) โ€” ํ…์ŠคํŠธ๋งŒ ๋‚˜๋ฅด๋Š” ์†Œ๋น„์žยทwire ์šฉ(docs/TOOLS.md)
  • ๋„๊ตฌ ๊ฒฐ๊ณผ ํ•ฉ๊ณ„ ์˜ˆ์‚ฐ โ€” ToolResultBudgetMiddleware๊ฐ€ ํ•œ ํ˜ธ์ถœ์˜ ๋„๊ตฌ ๋ฃจํ”„ ์ „์ฒด์—์„œ ๋ชจ๋ธ์— ๋ณด๋‚ด๋Š” ๊ฒฐ๊ณผ ํ…์ŠคํŠธ ํ•ฉ๊ณ„๋ฅผ ์ œํ•œ(์ž‘์€ ๋ฌธ๋งฅ ์ฐฝ ๋Œ€์‘, docs/TOOLS.md)
  • ๊ณต๊ธ‰์ž ๊ณ ์œ  ํ•„๋“œ โ€” MessageRequest.ExtraBody(์ž„๋ฒ ๋”ฉ์€ EmbeddingRequestOptions.ExtraBody, EmbedBatchAsync(model, inputs, options)) ๊ฐ€ ์š”์ฒญ ๋ณธ๋ฌธ์— ํ•ฉ์ณ์ง€๊ณ , ๋งคํ•‘๋˜์ง€ ์•Š์€ ์‘๋‹ต ํ•„๋“œ(์˜ˆ: llama.cpp timings)๊ฐ€ MessageResponse.ExtraBody ๋กœ ๋Œ์•„์˜จ๋‹ค(OpenAI Compatible, docs/PROVIDERS.md)
  • ํ˜ธ์ถœ ๋‹จ์œ„ ํ—ค๋” โ€” MessageGenerationRequest.Headers(MessageRequest.Headers ยท AgentInvokeOptions.Headers ยท ChatOptions.AdditionalProperties[ChatClientAdapter.RequestHeadersKey])๊ฐ€ ๊ทธ ํ˜ธ์ถœ์—๋งŒ ์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‹ฃ๋Š”๋‹ค โ€” ํ•œ ํด๋ผ์ด์–ธํŠธ๋กœ ์—ฌ๋Ÿฌ ์‹คํ–‰ ๋‹จ์œ„๋ฅผ ๋Œ๋ฆฌ๋ฉฐ ๊ฒŒ์ดํŠธ์›จ์ด ๊ท€์† ํƒœ๊ทธยท์ถ”์  id ๋ฅผ ํ˜ธ์ถœ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฒŒ ๋ณด๋‚ผ ๋•Œ. ๋„ค provider ๊ณตํ†ต, config Headers ์œ„์— ์–นํžˆ๊ณ  ๊ฐ™์€ ์ด๋ฆ„์ด๋ฉด ์š”์ฒญ ๊ฐ’์ด ์ด๊ธด๋‹ค(docs/PROVIDERS.md ยซํ˜ธ์ถœ ๋‹จ์œ„ ํ—ค๋”ยป)
  • ๊ฒŒ์ดํŠธ์›จ์ด ์ž๊ฒฉ์ฆ๋ช… ํ˜•ํƒœ โ€” OpenAI ์™€์ด์–ด(OpenAI ยท OpenAI Compatible ยท GPUStack)์˜ ํ‚ค ์Šฌ๋กฏ์ด ApiKeyPlacement(CredentialPlacement.Authorization("Basic") ยท .Authorization(null) ยท .InHeader("api-key"), ๊ธฐ๋ณธ Bearer)๋กœ ํ‚ค๋ฅผ ๋ณด๋‚ผ ํ—ค๋”์™€ scheme ์„ ์ •ํ•œ๋‹ค โ€” ํ‚ค๋Š” ๊ณ„์† ApiKey/ApiKeyResolver ์— ์žˆ๋‹ค(docs/PROVIDERS.md)
  • ํ† ํฐ ๋กœ๊ทธ ํ™•๋ฅ  โ€” MessageRequest.LogProbabilities(์ƒ์œ„ ๋Œ€์•ˆ 0~20)๋กœ ์ถœ๋ ฅ ํ† ํฐ๋ณ„ ๋กœ๊ทธ ํ™•๋ฅ ์„ ๋ฐ›๋Š”๋‹ค(MessageResponse.LogProbabilities, ์ŠคํŠธ๋ฆฌ๋ฐ done ํ”„๋ ˆ์ž„์—๋„; OpenAI Compatible ยท Google AI, docs/PROVIDERS.md)
  • ๋„๋ฉ”์ธ ์˜ˆ์™ธ โ€” ์ปจํ…์ŠคํŠธ ์œˆ๋„์šฐ ์ดˆ๊ณผ ์‹œ ํ”„๋กœ๋ฐ”์ด๋”๋ณ„ ์˜ค๋ฅ˜๋ฅผ ContextOverflowException(ContextWindowยทRequestTokens ํฌํ•จ)์œผ๋กœ ์ •๊ทœํ™” โ€” ๋ฌธ์ž์—ด ํŒŒ์‹ฑ ์—†์ด catch๋กœ ์••์ถ•ยท๋ณต๊ตฌ ๋กœ์ง ์ž‘์„ฑ ๊ฐ€๋Šฅ. ํ”„๋กœ๋ฐ”์ด๋” ๋Œ€์‹  ์ž๊ธฐ OpenAI SDK ํด๋ผ์ด์–ธํŠธ(๋˜๋Š” Microsoft.Extensions.AI.OpenAI)๋ฅผ ์“ฐ๋Š” ๊ฒฝ์šฐ OpenAIErrors.TryMapContextOverflow(ex)/TryMapRateLimit(ex)/TryMapBilling(ex)(IronHive.Providers.OpenAI)๋กœ ๊ฐ™์€ ๋งคํ•‘์„ ๋ฐ›๋Š”๋‹ค. ๊ณ„์ •์ด ์ง€๋ถˆํ•  ์ˆ˜ ์—†๋Š” ๊ฑฐ์ ˆ(HTTP 402, OpenAI insufficient_quota, Anthropic billing_error)์€ BillingException โ€” ๊ธฐ๋‹ค๋ ค๋„ ํ’€๋ฆฌ์ง€ ์•Š์œผ๋ฏ€๋กœ RateLimitException ๊ณผ ๊ตฌ๋ถ„๋œ๋‹ค. OpenAI ํ˜ธํ™˜ ํด๋ผ์ด์–ธํŠธ(IronHive.Providers.OpenAI.Compatible)์˜ ๊ทธ ๋ฐ–์˜ HTTP ์˜ค๋ฅ˜๋Š” ProviderHttpException โ€” HttpRequestException(๊ฐ™์€ StatusCode)์ด๋ฉด์„œ ์„œ๋ฒ„๊ฐ€ ๋ณด๋‚ธ Retry-After/retry-after-ms ๋ฅผ RetryAfter ๋กœ ์‹ฃ๋Š”๋‹ค(503 + ํžŒํŠธ = ยซ๊ธฐ๋‹ค๋ ค๋ผยป, ํžŒํŠธ ์—†์Œ = ๋‹ค๋ฅธ ๊ณณ์œผ๋กœ). ์ด๋ฏธ ์‹œ์ž‘๋œ ์ŠคํŠธ๋ฆผ์˜ ์‹คํŒจ(์ŠคํŠธ๋ฆผ ์•ˆ์˜ ์˜ค๋ฅ˜ ์ด๋ฒคํŠธ, ์™„๋ฃŒ ์‹ ํ˜ธ ์—†์ด ๋Š๊ธด ์—ฐ๊ฒฐ)๋Š” ๋„ค ํ”„๋กœ๋ฐ”์ด๋” ๋ชจ๋‘ ์ •์ƒ ์™„๋ฃŒ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ˆ์™ธ๋‹ค โ€” ์œ„ ํƒ€์ž… ์ค‘ ๋งž๋Š” ๊ฒƒ, ๋‚˜๋จธ์ง€๋Š” ProviderResponseException(ErrorCode, ๊ฐ™์€ ์˜ค๋ฅ˜์˜ ์ŠคํŠธ๋ฆผ ๋ฐ– HTTP ์ƒํƒœ EquivalentStatusCode)

์™œ IronHive์ธ๊ฐ€

2026๋…„ 4์›” Microsoft Agent Framework 1.0์ด AutoGen๊ณผ Semantic Kernel์„ ํ†ตํ•ฉํ•ด GA๋กœ ์ถœ์‹œ๋˜๋ฉฐ .NET LLM ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์˜ ์œ ๋ ฅํ•œ ๊ธฐ๋ณธ ์„ ํƒ์ง€๋กœ ๋– ์˜ฌ๋ž์Šต๋‹ˆ๋‹ค. IronHive๋Š” ์ด์™€ ๋‹ค๋ฅธ ์„ค๊ณ„ ์ถ•์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค โ€” ๋กœ์ปฌ ์šฐ์„ , ํด๋ผ์šฐ๋“œ ๋ฌด์˜์กด์ž…๋‹ˆ๋‹ค.

  • ์™„์ „ํ•œ ๋กœ์ปฌ ์ถ”๋ก  ๋ฃจํ”„ โ€” lm-supply๋กœ LLM ์ƒ์„ฑยท์ž„๋ฒ ๋”ฉยท๋ฆฌ๋žญํ‚นยทOCR๊นŒ์ง€ GGUF/ONNX ๋ฐฑ์—”๋“œ๋กœ ์ˆœ์ˆ˜ .NET์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์šฐ๋“œ ๊ณ„์ •์ด๋‚˜ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ์—†์ด๋„ ์—์ด์ „ํŠธ ๋ฃจํ”„ ์ „์ฒด๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • RAG ๋Š” ๊ฐ™์€ ์ƒํƒœ๊ณ„์˜ ์ „์šฉ ์Šคํƒ์œผ๋กœ โ€” ๋ฌธ์„œ ์ฒ˜๋ฆฌ(FileFlux/WebFlux)๋ถ€ํ„ฐ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๊ฒ€์ƒ‰(FluxIndex)๊นŒ์ง€ ๊ฐ™์€ .NET ์ƒํƒœ๊ณ„ ํŒจํ‚ค์ง€๋กœ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Azure ์ƒํƒœ๊ณ„์— ์ด๋ฏธ ํˆฌ์žํ•œ ํŒ€์ด๋ผ๋ฉด Microsoft Agent Framework๊ฐ€ ์ž์—ฐ์Šค๋Ÿฌ์šด ์„ ํƒ์ž…๋‹ˆ๋‹ค. ์˜คํ”„๋ผ์ธ/์—์–ด๊ฐญ ํ™˜๊ฒฝ, ๋ฐ์ดํ„ฐ ์ƒ์ฃผ ์š”๊ตฌ์‚ฌํ•ญ, ๋˜๋Š” ํด๋ผ์šฐ๋“œ ์ข…์†์„ ํ”ผํ•˜๋ ค๋Š” .NET ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ผ๋ฉด IronHive๊ฐ€ ๊ทธ ์ž๋ฆฌ๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค.

์„ค์น˜

dotnet add package IronHive.Core
dotnet add package IronHive.Providers.OpenAI    # ๋˜๋Š” Anthropic, GoogleAI ๋“ฑ

๋น ๋ฅธ ์‹œ์ž‘

Standalone (์ฝ˜์†”)

using IronHive.Core;
using IronHive.Providers.OpenAI;
using IronHive.Abstractions.Messages.Content;

var hive = new HiveServiceBuilder()
    .AddOpenAIProviders("openai", new OpenAIConfig { ApiKey = "your-api-key" })
    .Build();

var agent = hive.CreateAgentFrom(cfg =>
{
    cfg.Provider = "openai";
    cfg.Model = "gpt-4o-mini";
    cfg.Instructions = "๋‹น์‹ ์€ ์นœ์ ˆํ•œ ๋„์šฐ๋ฏธ์ž…๋‹ˆ๋‹ค.";
});

// ๋‹จ์ˆœ ํ…์ŠคํŠธ ํ˜ธ์ถœ
var response = await agent.InvokeAsync("์•ˆ๋…•ํ•˜์„ธ์š”");

// per-request ์˜ต์…˜ (์—์ด์ „ํŠธ ๊ธฐ๋ณธ๊ฐ’ ์œ„์— ์ด ํ˜ธ์ถœ์—๋งŒ overlay)
var response2 = await agent.InvokeAsync("์•ˆ๋…•ํ•˜์„ธ์š”", new AgentInvokeOptions
{
    ThinkingEffort = MessageThinkingEffort.High,
    ThinkingOutput = MessageThinkingOutput.Summary,  // ์ถ”๋ก  ์š”์•ฝ์„ ์‘๋‹ต์— ์‹ฃ๊ธฐ (None ์ด๋ฉด ์ˆจ๊น€)
    Suggestions = new SuggestionOptions(),  // ํ›„์† ์งˆ์˜ ์ œ์•ˆ ํ™œ์„ฑํ™”
    MaxTokens = 2048,  // ์ถ”๋ก ๊ณผ ๋‹ต์ด ๋‚˜๋ˆ  ์“ฐ๋Š” ํ•œ๋„ โ€” ์˜ˆ์‚ฐ ๋ฐฉ์‹ provider ๋Š” ์ถ”๋ก  ์˜ˆ์‚ฐ์„ ์ด ์•ˆ์— ๋งž์ถ˜๋‹ค(ThinkingBudget.FitWithin)
});

// ์ŠคํŠธ๋ฆฌ๋ฐ
await foreach (var chunk in agent.InvokeStreamingAsync("์•ˆ๋…•ํ•˜์„ธ์š”"))
{
    // chunk ์ฒ˜๋ฆฌ
}

ASP.NET Core DI ํ†ตํ•ฉ

// Program.cs
builder.Services.AddHiveService((hiveBuilder, sp) =>
    hiveBuilder
        .AddOpenAIProviders("openai", new OpenAIConfig
        {
            ApiKey = builder.Configuration["OpenAI:ApiKey"]!
        })
        .Build());

// ์„œ๋น„์Šค์—์„œ IHiveService ์ฃผ์ž…
public class ChatService(IHiveService hive)
{
    public async Task<string> ChatAsync(string text)
    {
        var agent = hive.CreateAgentFrom(cfg =>
        {
            cfg.Provider = "openai";
            cfg.Model = "gpt-4o-mini";
        });
        var response = await agent.InvokeAsync(text);
        return response.Message?.Content
            .OfType<TextMessageContent>()
            .FirstOrDefault()?.Value ?? string.Empty;
    }
}

ํŒจํ‚ค์ง€

ํŒจํ‚ค์ง€ ์„ค๋ช…
IronHive.Abstractions ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ ๊ณ„์•ฝ (์˜์กด: Microsoft.Extensions.DependencyInjection.Abstractions ๋ฟ)
IronHive.Core ํ•ต์‹ฌ ๊ตฌํ˜„ (์—์ด์ „ํŠธ, ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ, ์„œ๋น„์Šค)
IronHive.Extensions.AI provider ๋ฅผ Microsoft.Extensions.AI IChatClient / IEmbeddingGenerator ๋กœ โ€” Abstractions ๋งŒ ์˜์กด(Core ๋ถˆํ•„์š”)
IronHive.Providers.OpenAI OpenAI ์ „์šฉ (Responses API, Embeddings, ์ด๋ฏธ์ง€, TTS/STT) โ€” AddOpenAIProviders. OpenAI ํ˜ธํ™˜ ์„œ๋น„์Šค๋Š” IronHive.Providers.OpenAI.Compatible
IronHive.Providers.Anthropic Anthropic Claude โ€” AddAnthropicProviders
IronHive.Providers.GoogleAI Google Gemini + Vertex AI (์ด๋ฏธ์ง€, ๋น„๋””์˜ค, ์˜ค๋””์˜ค ํฌํ•จ) โ€” AddGoogleAIProviders ยท AddVertexAIProviders
IronHive.Providers.OpenAI.Compatible Ollama, LM Studio, vLLM, llama.cpp, GPUStack ๋“ฑ โ€” Chat Completions ยท ์ž„๋ฒ ๋”ฉ ยท ๋ฆฌ๋žญํ‚น(/rerank) ยท ์ด๋ฏธ์ง€ ยท ์˜ค๋””์˜ค. AddOpenAICompatibleProviders ยท AddGpuStackProviders
IronHive.Plugins.MCP Model Context Protocol (HTTP/Stdio/OAuth) โ€” McpClientManager

์ถœ๋ ฅ ๊ธธ์ด ํŒŒ๋ผ๋ฏธํ„ฐ ์„ ํƒ (0.16.0~) โ€” OpenAI ๊ฐ€ max_tokens ๋ฅผ max_completion_tokens ๋กœ ๊ฐœ๋ช…ํ•˜๋ฉด์„œ ์ƒํƒœ๊ณ„๊ฐ€ ๊ฐˆ๋ ธ๋‹ค. ์ตœ์‹  OpenAI ๋ชจ๋ธ์€ ๊ตฌ ์ด๋ฆ„์„ ๊ฑฐ๋ถ€ํ•˜๊ณ , ๋‹ค์ˆ˜์˜ self-hosted ์„œ๋ฒ„๋Š” ์ƒˆ ์ด๋ฆ„์„ ๋ชจ๋ฅธ ์ฑ„ ๋ฌด์‹œํ•œ๋‹ค โ€” ๋ชจ๋ฅด๋Š” ํ•„๋“œ๋Š” ์˜ค๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์นจ๋ฌต์ด๋ฏ€๋กœ, ์ƒํ•œ์ด ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง€๊ณ  ์ฆ์ƒ์€ "์‘๋‹ต์ด ์˜ˆ์ƒ๋ณด๋‹ค ๊ธธ๋‹ค" ๋ฟ์ด๋‹ค. ์–ด๋””์„œ๋‚˜ ํ†ตํ•˜๋Š” ์ด๋ฆ„์ด ์—†์–ด ์„ ํƒ์ง€๋กœ ์ œ๊ณตํ•œ๋‹ค:

var config = new OpenAICompatibleConfig
{
    BaseUrl = "http://localhost:11434",
    TokenLimitParameter = TokenLimitParameter.MaxTokens   // ๊ตฌ ์ด๋ฆ„๋งŒ ์•„๋Š” ์„œ๋ฒ„
};

๊ธฐ๋ณธ๊ฐ’์€ MaxCompletionTokens โ€” ์ข…์ „ ๋™์ž‘ ๊ทธ๋Œ€๋กœ๋ผ ๊ธฐ์กด ์„ค์ •์€ ์˜ํ–ฅ๋ฐ›์ง€ ์•Š๋Š”๋‹ค. Both ๋Š” ๋‘˜ ๋‹ค ๋ฐ›์•„๋“ค์ด๋Š” ์—”๋“œํฌ์ธํŠธ์—์„œ๋งŒ ์“ด๋‹ค(๊ตฌ ์ด๋ฆ„์„ ๊ฑฐ๋ถ€ํ•˜๋Š” ๊ณณ์—์„œ๋Š” ์š”์ฒญ ์ „์ฒด๊ฐ€ ์‹คํŒจํ•œ๋‹ค). MaxTokens ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์–ด๋А ์„ค์ •์—์„œ๋„ ๋‘ ํ•„๋“œ ๋ชจ๋‘ ์ „์†ก๋˜์ง€ ์•Š๋Š”๋‹ค.

localhost ์™€ ์—ฐ๊ฒฐ ํƒ€์ž„์•„์›ƒ (0.41.0~) โ€” ๊ฐ provider ๊ฐ€ ์ง์ ‘ ๋งŒ๋“œ๋Š” ์ „์†ก์€ ํ˜ธ์ŠคํŠธ์˜ ์ฃผ์†Œ๋“ค์„ ๊ฒฝ์ฃผ์‹œํ‚จ๋‹ค (RFC 8305): localhost ๊ฐ€ ::1 ๋ถ€ํ„ฐ ํ’€๋ ค๋„ IPv4 ์ „์šฉ ๋กœ์ปฌ ์„œ๋ฒ„(llama-server ยท Ollama ๊ธฐ๋ณธ๊ฐ’)์— ๊ณง๋ฐ”๋กœ ๋ถ™๋Š”๋‹ค. ๊ทธ ์ „์—๋Š” Windows ์—์„œ ๊ฑฐ๋ถ€๋œ IPv6 ์—ฐ๊ฒฐ์ด ์•ฝ 2 ์ดˆ ๊ฑธ๋ ค OpenAI-compatible ์˜ 2 ์ดˆ ConnectTimeout ์ด ๋จผ์ € ๋๋‚ฌ๋‹ค. HttpClient ๋ฅผ ์ง์ ‘ ์ฃผ์ž…ํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ™์€ ๋™์ž‘์€ IronHive.Abstractions.Http.ProviderConnect.CreateHandler(timeout) ๋กœ ์–ป๋Š”๋‹ค. OpenAI-compatible ยท GPUStack ์˜ ๊ธฐ๋ณธ ConnectTimeout ์€ 0.46.1 ๋ถ€ํ„ฐ 3 ์ดˆ๋‹ค โ€” Windows ๊ฐ€ ๊ฑฐ๋ถ€๋œ ์—ฐ๊ฒฐ์„ ์•Œ๋ฆฌ๋Š” ~2 ์ดˆ๋ณด๋‹ค ๊ธธ์–ด์•ผ ๊บผ์ง„ ์„œ๋ฒ„๊ฐ€ ํƒ€์ž„์•„์›ƒ์ด ์•„๋‹ˆ๋ผ ๊ฑฐ๋ถ€๋กœ ๋ณด๊ณ ๋œ๋‹ค.

์ŠคํŠธ๋ฆผ idle ํƒ€์ž„์•„์›ƒ StreamIdleTimeout (0.51.0~) โ€” ๋ชจ๋“  provider config ์— ์žˆ๋‹ค. ์ŠคํŠธ๋ฆฌ๋ฐ ์‘๋‹ต์ด ์ด ์‹œ๊ฐ„๋ณด๋‹ค ์˜ค๋ž˜ ์นจ๋ฌตํ•˜๋ฉด(์ฒซ ์ด๋ฒคํŠธ ์ „, ๋˜๋Š” ์ด๋ฒคํŠธ ์‚ฌ์ด) TimeoutException(ยซstream idle timeoutยป)์œผ๋กœ ๋๋‚œ๋‹ค. ์ „์ฒด ์š”์ฒญ ์‹œํ•œ๊ณผ ๋‹ฌ๋ฆฌ ๋А๋ฆฐ ์ŠคํŠธ๋ฆผ(๊ธด ํ”„๋กฌํ”„ํŠธ ํ‰๊ฐ€ ๋’ค ํ๋ฅด๋Š” ๋‹ต๋ณ€)๊ณผ ์ฃฝ์€ ์ŠคํŠธ๋ฆผ์„ ๊ฐ€๋ฅธ๋‹ค โ€” ๋กœ์ปฌ ์„œ๋ฒ„๋ผ๋ฉด ์ฒซ ํ† ํฐ ์ „ ํ‰๊ฐ€ ์‹œ๊ฐ„๋ณด๋‹ค ํฌ๊ฒŒ. ๊ธฐ๋ณธ ๋ฌด์ œํ•œ. OpenAICompatibleConfig ยท GpuStackConfig ๋Š” ์ด ๋ฒ„์ „๋ถ€ํ„ฐ Timeout ๋„ ๊ฐ–๋Š”๋‹ค. ๊ฐ™์€ ์˜ˆ์‚ฐ์„ ์ง์ ‘ ์“ฐ๋ ค๋ฉด IronHive.Abstractions.Http.ProviderStreams.WithIdleTimeout. ์ƒ์„ธ: docs/PROVIDERS.md ใ€Œ์ŠคํŠธ๋ฆผ idle ํƒ€์ž„์•„์›ƒใ€.

๋„๊ตฌ ์ด๋ฏธ์ง€ ์šด๋ฐ˜ CarryImageToolResultsAsUserMessage (0.49.0~) โ€” Chat Completions ์˜ tool ๋ฉ”์‹œ์ง€๋Š” ํ…์ŠคํŠธ๋งŒ ๋‹ด๊ณ , OpenAI ํ˜ธํ™˜ ์„œ๋ฒ„(vLLM ยท llama.cpp)๋Š” ๊ทธ ์ž๋ฆฌ์˜ ์ด๋ฏธ์ง€ part ๋ฅผ ๊ฑฐ๋ถ€ํ•œ๋‹ค. ๊ธฐ๋ณธ(๊บผ์ง)์€ ์ข…์ „๋Œ€๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ž๋ฆฌํ‘œ์‹œ ํ•œ ์ค„๋กœ ๋ฐ”๊พผ๋‹ค. ์ผœ๋ฉด ๋„๊ตฌ ๋ฉ”์‹œ์ง€๋Š” ํ…์ŠคํŠธ์™€ [image image/png โ€” attached in the next message] ๋ฅผ ๊ฐ–๊ณ , ๊ทธ ๋ผ์šด๋“œ์˜ ๋„๊ตฌ ๋ฉ”์‹œ์ง€๋“ค ๋’ค user ๋ฉ”์‹œ์ง€ ํ•˜๋‚˜๊ฐ€ ์ด๋ฏธ์ง€๋ฅผ ์‹ฃ๋Š”๋‹ค โ€” ๋กœ์ปฌ vision ๋ชจ๋ธ์ด MCP ๋„๊ตฌ๊ฐ€ ๊ทธ๋ฆฐ ๊ทธ๋ฆผ์„ ๋ณด๋Š” ๊ฒฝ๋กœ๋‹ค.

var config = new OpenAICompatibleConfig { BaseUrl = "http://127.0.0.1:8080", CarryImageToolResultsAsUserMessage = true };

SDK ์žฌ์‹œ๋„ ํšŸ์ˆ˜ MaxRetries (0.46.0~) โ€” OpenAIConfig ยท OpenAICompatibleConfig ยท GpuStackConfig ยท AnthropicConfig ๊ฐ€ ๊ฐ™์€ ์ด๋ฆ„ยท์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”๋‹ค: ์‹คํŒจํ•œ ์š”์ฒญ(์ „์†ก ์‹คํŒจ ยท 408 ยท 429 ยท 5xx)์„ SDK ๊ฐ€ ๋ช‡ ๋ฒˆ ๋‹ค์‹œ ๋ณด๋‚ด๋Š”๊ฐ€. null ์€ SDK ๊ธฐ๋ณธ๊ฐ’ (OpenAI ๊ณ„์—ด 3ํšŒ = ์ตœ๋Œ€ 4 ์š”์ฒญ), 0 ์€ ํ•œ ๋ฒˆ๋งŒ ๋ณด๋‚ธ๋‹ค. ์—ฐ๊ฒฐ ํ™•์ธ์ฒ˜๋Ÿผ ์ฆ‰๋‹ต์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ RetryMiddleware ๋กœ ์ง์ ‘ ์žฌ์‹œ๋„ํ•˜๋Š” ๊ณณ์—์„œ๋Š” 0 ์œผ๋กœ ๋‘ฌ์•ผ ์žฌ์‹œ๋„๊ฐ€ ๊ณฑํ•ด์ง€์ง€ ์•Š๋Š”๋‹ค.

๋ฌธ์„œ

๋ฌธ์„œ ์„ค๋ช…
docs/ARCHITECTURE.md ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜ ๋ฐ ์„ค๊ณ„ ์›์น™
docs/SETUP.md HiveServiceBuilder ๊ตฌ์„ฑ ๋ฐ DI ํ†ตํ•ฉ
docs/AGENTS.md ์—์ด์ „ํŠธ ์ƒ์„ฑ ๋ฐ ํ˜ธ์ถœ
docs/MIDDLEWARE.md ๋ฏธ๋“ค์›จ์–ด ์‹œ์Šคํ…œ (Retry, Timeout, CircuitBreaker ๋“ฑ)
docs/ORCHESTRATION.md ๋ฉ€ํ‹ฐ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ํŒจํ„ด
docs/TOOLS.md FunctionTool ๋ฐ ์ปค์Šคํ…€ ๋„๊ตฌ
docs/PROVIDERS.md AI ํ”„๋กœ๋ฐ”์ด๋” ์„ค์ •
docs/PLUGINS.md MCP ํ”Œ๋Ÿฌ๊ทธ์ธ
docs/SERVICES.md IHiveService ์„œ๋น„์Šค ์ƒ์„ธ

Skills (AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ์šฉ)

AI ์ฝ”๋”ฉ ์—์ด์ „ํŠธ(GitHub Copilot, Claude Code, Cursor ๋“ฑ)์—์„œ IronHive Skills๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด:

npx skills add iyulab/ironhive

์„ค์น˜ ํ›„ ์—์ด์ „ํŠธ๊ฐ€ IronHive API ํŒจํ„ด, ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜, ํˆด ์‚ฌ์šฉ๋ฒ•์„ ์ž๋™์œผ๋กœ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.

์š”๊ตฌ ์‚ฌํ•ญ

  • .NET 10.0+

๋ผ์ด์„ ์Šค

MIT โ€” LICENSE ์ฐธ์กฐ.

Changes from Previous Version

No structural changes between v0.68.0 and v0.69.0.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

Compatibility metadata lists 1 target framework; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.