Skip to main content
net10.0

iron-prow adapter: ironhive providers as gateway candidates.

Published
Jul 1, 2026
3mo ago
Total Downloads
8.0K
8,011

Install

dotnet add package IronProw.IronHive --version 0.1.0
ProductVersions
.NET
net10.0

README

iron-prow

safe-inference gateway โ€” every LLM call's first gate.
provider selection (frontier โˆจ LAN GpuStack) ยท guardrail ยท resilience โ€” delivered as a standard Microsoft.Extensions.AI.IChatClient.

๋‘ ๊ฐˆ๋ž˜ ํ•„์ˆ˜: frontier/LAN ๊ฒŒ์ดํŠธ์›จ์ด(A) and local-provider safety(B).
์—ญํ• ยท๋ฒ”์œ„ยท์„ค๊ณ„ ๊ทผ๊ฑฐ๋Š” CHARTER.md ์ฐธ์กฐ.

Packages

Package ์—ญํ• 
IronProw.Core ๊ฒŒ์ดํŠธ์›จ์ด ๊ณ„์•ฝ, resilience, ์„ ํƒ ๋กœ์ง โ€” iyulab ๊ตฌํ˜„ ์˜์กด 0
IronProw.IronHive IronHive provider ์–ด๋Œ‘ํ„ฐ โ€” OpenAI ยท Anthropic ยท GoogleAI (frontier) ยท GpuStack (LAN)
IronProw.FluxGuard FluxGuard guardrail ์–ด๋Œ‘ํ„ฐ (IGuard ๊ตฌํ˜„)
IronProw.LMSupply ๋กœ์ปฌ ์ถ”๋ก  ์•ˆ์ „ ๋ž˜ํผ (length-bounding + readiness gate)
dotnet add package IronProw.Core
dotnet add package IronProw.IronHive    # frontier provider adapters
dotnet add package IronProw.FluxGuard  # guardrail adapter
dotnet add package IronProw.LMSupply   # local-provider safety adapter

Quick Start

A. Frontier / LAN ๊ฒŒ์ดํŠธ์›จ์ด

IronHive ๊ธฐ๋ฐ˜ frontier provider + FluxGuard guardrail์„ ๋“ฑ๋กํ•œ๋‹ค.
DI ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ‘œ์ค€ IChatClient๋ฅผ resolveํ•˜๋ฉฐ, ๊ฒŒ์ดํŠธ์›จ์ด๊ฐ€ selectionยทretryยท์ž…์ถœ๋ ฅ ๊ฒ€์‚ฌ๋ฅผ ์ž๋™ ์ฒ˜๋ฆฌํ•œ๋‹ค.

using IronProw.Core;
using IronProw.IronHive;
using IronProw.FluxGuard;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;

services.AddIronProw()
        .AddIronHiveOpenAI(
            id: "openai",
            priority: 10,
            modelId: "gpt-4o",
            configure: cfg => cfg.ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!)
        .AddIronHiveAnthropic(
            id: "anthropic",
            priority: 5,
            modelId: "claude-opus-4-5",
            configure: cfg => cfg.ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY")!)
        .UseFluxGuard();  // Standard preset (L1 regex guards, offline)

// ํ‘œ์ค€ Microsoft.Extensions.AI.IChatClient ๋ฐ˜ํ™˜
IChatClient chat = host.Services.GetRequiredService<IChatClient>();
var response = await chat.GetResponseAsync("Hello");

IronProw.IronHive๋Š” ๋„ค ๊ฐ€์ง€ provider ์–ด๋Œ‘ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค:

  • AddIronHiveOpenAI ยท AddIronHiveAnthropic ยท AddIronHiveGoogleAI โ€” frontier (ProviderKind.Frontier)
  • AddIronHiveGpuStack โ€” LAN GpuStack (ProviderKind.Lan, key-optional). cfg => cfg.BaseUrl = "http://gpustack.lan:8080" ํ˜•ํƒœ๋กœ endpoint ์ง€์ •.

Ollama / ๊ธฐํƒ€ OpenAI-ํ˜ธํ™˜(LMStudioยทvLLM)์€ ์•„์ง ์–ด๋Œ‘ํ„ฐ๊ฐ€ ์—†๋‹ค โ€” ironhive์— ํ•ด๋‹น provider๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค(generic OpenAI-Compatible provider ๋„์ž… ์˜ˆ์ •).

UseFluxGuard() (ํŒŒ๋ผ๋ฏธํ„ฐ ์—†์Œ) ๋Š” Standard preset(L1 regex, offline)์„ ์ ์šฉํ•œ๋‹ค.
์ปค์Šคํ…€ FluxGuard ์ธ์Šคํ„ด์Šค๋ฅผ ์ฃผ์ž…ํ•˜๋ ค๋ฉด UseFluxGuard(IFluxGuard) ์˜ค๋ฒ„๋กœ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
fail mode: ๊ธฐ๋ณธ์€ fail-closed(๋ถˆํ™•์‹ค verdict ์ฐจ๋‹จ). ๊ฐ€์šฉ์„ฑ์„ ์šฐ์„ ํ•˜๋Š” ์†Œ๋น„์ž๋Š” UseFluxGuard(failMode: FluxGuardFailMode.Open)์œผ๋กœ opt-in โ€” Flagged/NeedsEscalation์„ ํ†ต๊ณผ์‹œํ‚จ๋‹ค(์ •์˜๋œ Block์€ mode ๋ฌด๊ด€ ํ•ญ์ƒ ์ฐจ๋‹จ).

B. Local-provider safety (lm-supply / ONNX / DirectML)

๋กœ์ปฌ ์ถ”๋ก ์„ iron-prow ์•ˆ์ „ ๋ ˆ์ด์–ด๋กœ ๊ฐ์‹ผ๋‹ค. lm-supply ์ƒ์„ฑ์ž(IGeneratorModel/ITextGenerator)๋ฅผ ๊ทธ๋Œ€๋กœ ๋„˜๊ธฐ๋ฉด iron-prow๊ฐ€ ๋‚ด๋ถ€ GeneratorChatClient ๋ธŒ๋ฆฌ์ง€๋กœ IChatClient์— ์ ์‘์‹œํ‚จ๋‹ค โ€” ์†Œ๋น„์ž๊ฐ€ ๋ธŒ๋ฆฌ์ง€๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

using IronProw.Core;
using IronProw.LMSupply;
using IronProw.FluxGuard;
using LMSupply.Generator;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;

// generator: lm-supply๊ฐ€ ๋กœ๋“œํ•œ IGeneratorModel/ITextGenerator (์ƒ๋ช…์ฃผ๊ธฐ๋Š” ํ˜ธ์ถœ์ž ์†Œ์œ ).
//            ์˜ˆ: var generator = await LocalGenerator.LoadAsync("gguf:default", options, null, ct);
// probe:     IReadinessProbe โ€” ๋ชจ๋ธ ๋กœ๋“œ ์ƒํƒœ๋ฅผ ๋ณด๊ณ ํ•˜๋Š” ๊ตฌํ˜„์ฒด.
//            lm-supply GeneratorPool ๊ธฐ๋ฐ˜์€ GeneratorPoolProbe๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
//            GeneratorPool ์—†์ด LoadAsync๋กœ ๋‹จ์ผ ๋ชจ๋ธ์„ ์ง์ ‘ ๋กœ๋“œํ•˜๋Š” ๊ฒฝ์šฐ
//            (์˜ˆ: textree)๋Š” LazyReadinessProbe(() => loaded, [modelId])๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
services.AddIronProw()
        .AddLMSupplyLocal(
            id: "local-phi3",
            priority: 20,
            generator: generator,
            probe: probe,
            options: new LocalSafetyOptions { DefaultMaxOutputTokens = 1024 })
        .UseFluxGuard();

IChatClient chat = host.Services.GetRequiredService<IChatClient>();

AddLMSupplyLocal์ด ์ œ๊ณตํ•˜๋Š” safety:

  • bridge โ€” GeneratorChatClient๊ฐ€ lm-supply ์ƒ์„ฑ์ž๋ฅผ IChatClient๋กœ ์ ์‘(role ๋งคํ•‘, MaxOutputTokensโ†’MaxNewTokens, sampler/tool ์ „ํŒŒ, streaming flatten). ์ด๋ฏธ ๋ธŒ๋ฆฌ์ง€๋œ IChatClient๋ฅผ ๋ณด์œ ํ•œ ํ˜ธ์ถœ์ž(์˜ˆ: ironhive-host)๋Š” AddLMSupplyLocal(..., IChatClient rawClient, ...) ์˜ค๋ฒ„๋กœ๋“œ๋ฅผ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
  • model-ID preflight โ€” IReadinessProbe.GetAvailableModelIdsAsync๋กœ ๋ชจ๋ธ ์กด์žฌ ๊ฒ€์ฆ
  • readiness gate โ€” IReadinessProbe.IsReadyAsync๋กœ ๋กœ๋“œ ์™„๋ฃŒ ํ™•์ธ
  • length-bounding โ€” LocalSafetyOptions.DefaultMaxOutputTokens (๋ฏธ์„ค์ • ํ˜ธ์ถœ์— ์ž๋™ ์ ์šฉ, ๊ธฐ๋ณธ 512)

๋‘ ๊ฐˆ๋ž˜ ์กฐํ•ฉ

๋‘ ๊ฐˆ๋ž˜๋ฅผ ๊ฐ™์€ DI ๋“ฑ๋ก์—์„œ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ๋‹ค. priority๊ฐ€ ๋†’์€ provider๊ฐ€ ๋จผ์ € ์„ ํƒ๋˜๊ณ , fallback ์‹œ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„ provider๋กœ ๊ฐ•๋“ฑ๋œ๋‹ค.

services.AddIronProw()
        .AddIronHiveOpenAI("openai", priority: 10, "gpt-4o",
            cfg => cfg.ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!)
        .AddLMSupplyLocal("local", priority: 20, generator, probe)
        .UseFluxGuard()
        .Configure(opt =>
        {
            opt.EnableFallback = true;                              // ๊ธฐ๋ณธ๊ฐ’
            opt.Resilience.MaxRetries = 3;                         // ๊ธฐ๋ณธ๊ฐ’: 2
            opt.Resilience.BaseDelay = TimeSpan.FromMilliseconds(300); // ๊ธฐ๋ณธ๊ฐ’: 200ms
            opt.OnTransition = t =>                                 // retry/fallback/exhausted ์ด๋ฒคํŠธ (UI ์นฉ ๋“ฑ)
                Console.WriteLine($"[{t.Kind}] {t.ProviderId} ({t.ProviderIndex + 1}/{t.TotalProviders})");
        });

OnTransition(์„ ํƒ)์€ ๊ฐ ๊ฒŒ์ดํŠธ์›จ์ด ์ „ํ™˜(retry / fallback / exhausted)๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” best-effort ์ฝœ๋ฐฑ์ด๋‹ค. ์†Œ๋น„์ž๊ฐ€ ์–ด๋А provider๋กœ ๊ฐ•๋“ฑ๋๋Š”์ง€ UI์— ํ‘œ์‹œ(์˜ˆ: resilience ์นฉ)ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฝœ๋ฐฑ์ด ๋˜์ง€๋Š” ์˜ˆ์™ธ๋Š” ์‚ผ์ผœ์ง€๋ฉฐ ์ถ”๋ก ์„ ์ ˆ๋Œ€ ๊นจ์ง€ ์•Š๋Š”๋‹ค. ๋ฏธ์„ค์ • ์‹œ ๋™์ž‘์€ ๊ธฐ์กด๊ณผ ๋™์ผ(๋ฌด๋ณด๊ณ ).

Crash-fallback ์ œํ•œ

LocalSafetyChatClient(๊ฐˆ๋ž˜ B)๋Š” IReadinessProbe๋กœ ๋กœ์ปฌ ์ถ”๋ก  ๋ถˆ๊ฐ€๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ๊ฒŒ์ดํŠธ์›จ์ด SelectingChatClient์˜ provider-level fallback์œผ๋กœ ์Šน๊ฒฉํ•œ๋‹ค. ์ด๊ฒƒ์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ˆ˜์ค€ fallback(M2-4 ๋ฒ”์œ„)์ด๋‹ค.

์ง„์งœ ํ•˜๋“œ์›จ์–ด ์ˆ˜์ค€ fallback(์˜ˆ: ONNX GenAI DirectML โ†’ CPU)์€ upstream lm-supply์˜ ์ฑ…์ž„์ด๋‹ค.
lm-supply 0.35.x ๊ธฐ์ค€, ONNX GenAI ์ƒ์„ฑ ๊ฒฝ๋กœ๋Š” DirectML โ†’ CPU ํด๋ฐฑ์ด ์—†๋‹ค(์ž„๋ฒ ๋”ฉ ๊ฒฝ๋กœยทllama-server ๊ฒฝ๋กœ๋Š” ๋ณด์œ ). iron-prow๋Š” ์ด gap์„ ๊ฐ์‹ธ์ง€ ์•Š๋Š”๋‹ค โ€” upstream์ด ์ˆ˜์ •๋˜๋ฉด iron-prow ๋ณ€๊ฒฝ ์—†์ด ์ด๋“์ด ํก์ˆ˜๋œ๋‹ค.

๋‘ ๊ฐˆ๋ž˜ ํ•„์ˆ˜ ์„ค๊ณ„

iron-prow๋Š” ๋‘ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋…๋ฆฝ์ ์ด๋ฉด์„œ๋„ ์กฐํ•ฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ปค๋ฒ„ํ•œ๋‹ค:

๊ฐˆ๋ž˜ ์ง„์ž…์  ์ฑ…์ž„
A. Frontier / LAN AddIronHiveOpenAI ยท AddIronHiveAnthropic ยท AddIronHiveGoogleAI ยท AddIronHiveGpuStack provider ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ, ์šฐ์„ ์ˆœ์œ„ ์„ ํƒ, retry, provider-level fallback, ์ „ํ™˜ ์ด๋ฒคํŠธ(OnTransition)
B. local-provider safety AddLMSupplyLocal model-ID preflight, readiness gate, length-bounding, crashโ†’fallback

์–ด๋А ํ•œ ๊ฐˆ๋ž˜๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ์ˆ˜์š”์˜ ์ ˆ๋ฐ˜์„ ๋†“์นœ๋‹ค (CHARTER ยง๊ธฐ๋Šฅ ํ‘œ๋ฉด).
UseFluxGuard()๋Š” ๋‘ ๊ฐˆ๋ž˜ ๊ณตํ†ต โ€” ๊ด€๋ฌธ์—์„œ ์ผ๊ด„ ์ ์šฉ๋œ๋‹ค.

โš ๏ธ The guard is opt-in. AddIronProw() installs a default NullGuard that allows all traffic. A gateway without UseFluxGuard() (or a custom UseGuard(...)) performs NO input/output guardrail checks. Always register a guard in production.

See also

  • CHARTER.md โ€” iron-prow ์ •์ฒด์„ฑ, ๋ฒ”์œ„, ์˜์กด ๊ทœ์น™, ๋กœ๋“œ๋งต ์•ต์ปค

License

MIT

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.