IronHive Azure storage provider
Install
| Product | Versions |
|---|---|
| .NET |
README
IronHive
IronHive๋ ๊ธฐ์ ์ฉ AI ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ .NET 10 ํ์ดํ๋ผ์ธ ํ๋ ์์ํฌ์ ๋๋ค. ์ด๋ฆ ๊ธฐ๋ฐ ๋ ์ง์คํธ๋ฆฌ ํจํด์ผ๋ก ๋ฉํฐ Provider LLM ํตํฉ, ๋ฉํฐ์์ด์ ํธ ์ค์ผ์คํธ๋ ์ด์ , RAG ํ์ดํ๋ผ์ธ, ํ์ผ ์ฒ๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ฃผ์ ๊ธฐ๋ฅ
- ๋ฉํฐ 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 AIinputTokenLimitยทoutputTokenLimit, Anthropicmax_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) - RAG ํ์ดํ๋ผ์ธ โ ํ
์คํธ ์ถ์ถ, ์ฒญํน, ์๋ฒ ๋ฉ, ๋ฒกํฐ ๊ฒ์. ์ปฌ๋ ์
์
hive.Memory(CreateCollectionAsyncยทGetCollectionAsync), ์ ์ฌ ์์ปค๋hive.CreateMemoryWorkerFrom(builder => โฆ). ๋ฒกํฐยทํ ์คํ ๋ฆฌ์ง๋ฅผ ๋จผ์ ๋ฑ๋กํด์ผ ํ๋ค(๋ก์ปฌ:AddLocalVectorStorageยทAddLocalQueueStorage). PDFยทWordยทExcelยทPowerPointยท์ด๋ฏธ์ง ํ์๋ opt-inservices.AddFileParser()(docs/MEMORY.md) - ๋ฆฌ๋ญํน โ
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). OpenAPI:new OpenApiClientManager(tools)์await AddOrUpdateAsync(client)๋กOpenApiClient๋ฅผ ๋ฑ๋กํ๋ฉด ์คํ์ ์ฐ์ฐ์ด ๊ทธIToolCollection์ ๋๊ตฌ๋ก ๋ค์ด๊ฐ๋ค(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๋ก ๋ํยท์คํ โ MCPMcpClientTool๋ฑ). ๋๊ตฌ ์ธ์ ์คํธ๋ฆฌ๋ฐ(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; - ์ํฌํ๋ก์ฐ โ ์ฝ๋ ๊ธฐ๋ฐ ํ์
์์ ์ํฌํ๋ก์ฐ ์์ง.
new WorkflowFactory(sp)์CreateBuilder()(Fluent) ๋๋CreateFromYaml<TContext>ยทCreateFromJson<TContext>๋ก ๋ง๋ค๊ณIWorkflow<TContext>.RunAsync๋ก ์คํ(docs/WORKFLOW.md) - ์์ด์ ํธ ๋ฏธ๋ค์จ์ด โ
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) - ์คํ ๋ฆฌ์ง โ ๋ก์ปฌ:
AddLocalFileStorageยทAddLocalVectorStorageยทAddLocalQueueStorage(Core). ํด๋ผ์ฐ๋:AddAmazonS3StorageยทAddAzureBlobStorageยทAddAzureFilesStorage. Qdrant ยท RabbitMQ ๋ ๋น๋ ํ์ฅ์ด ์์ผ๋ฏ๋ก ์ธ์คํด์ค๋ฅผ ์ง์ ๋ฑ๋กํ๋ค โAddVectorStorage("qdrant", new QdrantVectorStorage(new QdrantConfig { โฆ }))ยทAddQueueStorage("rabbit", new RabbitMQueueStorage(new RabbitMQConfig { โฆ }))(docs/STORAGES.md) - ํ
๋ ๋ฉํธ๋ฆฌ โ ์ค์ผ์คํธ๋ ์ดํฐ๊ฐ
HiveTelemetry.SourceName("IronHive") ์ด๋ฆ์ActivitySourceยทMeter๋ก traceยทmetric ์ ๋ธ๋ค. OpenTelemetry ์AddSource/AddMeter๋ก ๊ตฌ๋ ํ๋ฉด ์ผ์ง๋ค - ๊ตฌ์กฐํ ์ถ๋ ฅ โ
OutputFormat.For<T>()/For(schema)๋ ์คํค๋ง๋ก ๊ตฌ์,OutputFormat.Json์ ์คํค๋ง ์๋ JSON ๋ชจ๋(provider ๋ค์ดํฐ๋ธ JSON ๋ชจ๋๋ก ๋ฒ์ญ โ OpenAIjson_object, GeminiresponseMimeType, 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.cpptimings)๊ฐMessageResponse.ExtraBody๋ก ๋์์จ๋ค(OpenAI Compatible, docs/PROVIDERS.md) - ํธ์ถ ๋จ์ ํค๋ โ
MessageGenerationRequest.Headers(MessageRequest.HeadersยทAgentInvokeOptions.HeadersยทChatOptions.AdditionalProperties[ChatClientAdapter.RequestHeadersKey])๊ฐ ๊ทธ ํธ์ถ์๋ง ์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฃ๋๋ค โ ํ ํด๋ผ์ด์ธํธ๋ก ์ฌ๋ฌ ์คํ ๋จ์๋ฅผ ๋๋ฆฌ๋ฉฐ ๊ฒ์ดํธ์จ์ด ๊ท์ ํ๊ทธยท์ถ์ id ๋ฅผ ํธ์ถ๋ง๋ค ๋ค๋ฅด๊ฒ ๋ณด๋ผ ๋. ๋ค provider ๊ณตํต, configHeaders์์ ์นํ๊ณ ๊ฐ์ ์ด๋ฆ์ด๋ฉด ์์ฒญ ๊ฐ์ด ์ด๊ธด๋ค(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, OpenAIinsufficient_quota, Anthropicbilling_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์์ ์คํํฉ๋๋ค. ํด๋ผ์ฐ๋ ๊ณ์ ์ด๋ ๋คํธ์ํฌ ์ฐ๊ฒฐ ์์ด๋ ์์ด์ ํธ ๋ฃจํ ์ ์ฒด๊ฐ ๋์ํฉ๋๋ค.
- ๋ค์ดํฐ๋ธ .NET, ๋ธ๋ฆฌ์ง ๋ถํ์ โ Microsoft Agent Framework์ ๋ก์ปฌ ์คํ ๊ฒฝ๋ก(Foundry Local)๋ 2026๋ ๊ธฐ์ค Python ์ ์ฉ์ด๋ฉฐ, .NET์์ ์ฐ๋ ค๋ฉด ์ปค๋ฎค๋ํฐ ์ด๋ํฐ๋ฅผ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. IronHive๋ ๋ก์ปฌ ์ถ๋ก ์ด ์ฒ์๋ถํฐ .NET 1๊ธ ์๋ฏผ์ ๋๋ค.
- RAG ํ์ดํ๋ผ์ธ ๋ด์ฅ โ ๋ฌธ์ ์ฒ๋ฆฌ(FileFlux/WebFlux)๋ถํฐ ํ์ด๋ธ๋ฆฌ๋ ๊ฒ์(FluxIndex)๊น์ง ๋ณ๋ ํตํฉ ์์ด ๋ฐ๋ก ์ฌ์ฉํฉ๋๋ค.
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.Storages.Qdrant |
Qdrant ๋ฒกํฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค โ QdrantVectorStorage |
IronHive.Storages.Amazon |
Amazon S3 ํ์ผ ์ ์ฅ์ โ AddAmazonS3Storage |
IronHive.Storages.Azure |
Azure Blob / File Share โ AddAzureBlobStorage ยท AddAzureFilesStorage |
IronHive.Storages.RabbitMQ |
RabbitMQ ํ โ RabbitMQueueStorage |
IronHive.Plugins.MCP |
Model Context Protocol (HTTP/Stdio/OAuth) โ McpClientManager |
IronHive.Plugins.OpenAPI |
OpenAPI ๋๊ตฌ ์๋ ์์ฑ โ OpenApiClientManager |
์ถ๋ ฅ ๊ธธ์ด ํ๋ผ๋ฏธํฐ ์ ํ (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/WORKFLOW.md | ์ํฌํ๋ก์ฐ ์์ง (Fluent ยท YAML ยท JSON) |
| docs/TOOLS.md | FunctionTool ๋ฐ ์ปค์คํ ๋๊ตฌ |
| docs/MEMORY.md | RAG ํ์ดํ๋ผ์ธ ๋ฐ MemoryWorker |
| docs/PROVIDERS.md | AI ํ๋ก๋ฐ์ด๋ ์ค์ |
| docs/STORAGES.md | ์คํ ๋ฆฌ์ง ๋ฐฑ์๋ ์ค์ |
| docs/PLUGINS.md | MCP / OpenAPI ํ๋ฌ๊ทธ์ธ |
| docs/SERVICES.md | IHiveService ์๋น์ค ์์ธ |
Skills (AI ์ฝ๋ฉ ์์ด์ ํธ์ฉ)
AI ์ฝ๋ฉ ์์ด์ ํธ(GitHub Copilot, Claude Code, Cursor ๋ฑ)์์ IronHive Skills๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด:
npx skills add iyulab/ironhive
์ค์น ํ ์์ด์ ํธ๊ฐ IronHive API ํจํด, ์ค์ผ์คํธ๋ ์ด์ , RAG ํ์ดํ๋ผ์ธ, ํด ์ฌ์ฉ๋ฒ์ ์๋์ผ๋ก ์ธ์ํฉ๋๋ค.
์๊ตฌ ์ฌํญ
- .NET 10.0+
๋ผ์ด์ ์ค
MIT โ LICENSE ์ฐธ์กฐ.
Changes from Previous Version
Adoption Assessment
Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.
Related Guides & Workflows
Learn how to evaluate, integrate, or audit this package in your .NET project.