본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 22. 01:05

Backstage와 .NET을 사용하여 AI 기반 개발자 포털 구축하기

요약

Backstage와 .NET, Ollama를 활용하여 소스 코드를 자동으로 스캔하고 요약하는 AI 기반 개발자 포털 구축 가이드를 소개합니다. 이를 통해 문서화가 되지 않거나 오래된 메타데이터 문제를 해결하고, 엔지니어링 조직을 위한 단일 진실 공급원(SSOT)을 구축하는 방법을 다룹니다.

핵심 포인트

  • .NET CLI와 Ollama를 이용한 로컬 AI 기반 코드 요약 구현
  • Backstage를 활용한 동적 서비스 카탈로그 자동화
  • 오래된 문서(stale documentation) 문제 해결 전략
  • 내부 개발자 포털(IDP)의 역할과 가치 설명

Backstage와 .NET을 사용하여 AI 기반 개발자 포털 구축하기

AI에 대해 읽기만 하는 것이 아니라, 실제로 적용해보고 싶으신가요? 대부분의 튜토리얼은 "Hello World" 수준의 챗봇에서 멈춥니다. 우리는 엔지니어링의 흔한 골칫거리인 '오래된 문서(stale documentation)' 문제를 실제로 해결할 수 있는 무언가를 만들어 볼 것입니다.

대상 독자
이 가이드는 팀원들에게 YAML 파일을 수동으로 작성하도록 강요하지 않으면서, 점점 커지는 소프트웨어 환경을 정리해야 하는 플랫폼 엔지니어(Platform Engineers)와 .NET 개발자를 대상으로 합니다.

구축할 내용
서비스 카탈로그(Service Catalog)를 자동으로 채워주는 Backstage 기반의 동적 개발자 포털을 구축하게 됩니다. .NET CLI 도구를 사용하여 소스 코드를 스캔하고, 로컬 AI (Ollama)를 사용하여 요약본을 생성할 것입니다.

소스 저장소: demo-backstage-catalog-generator
제약 사항: 로컬 추론(Local Inference)만 사용합니다. 소스 코드는 절대로 사용자의 기기를 벗어나지 않습니다.

서비스를 업데이트해야 하는데, 그 서비스가 정확히 무엇을 하는지 잊어버린 적이 있나요? 아니면 몇 달 동안 건드리지 않은 코드를 이해하려고 시간을 허비한 적이 있나요? 우리는 보통 아무도 업데이트하지 않는 README.md나 방치된 위키(Wiki)로 이 문제를 해결하려 합니다. 내부 개발자 포털 (Internal Developer Portal, IDP)은 소프트웨어 환경을 가시화함으로써 이 문제를 해결하지만, 이는 데이터가 최신 상태일 때만 가능합니다. 자동화는 "오래된 메타데이터(stale metadata)" 함정을 피할 수 있는 유일한 방법입니다.

팁: 바로 건너뛰고 싶으신가요? 모든 코드가 준비되어 즉시 실행 가능한 GitHub의 전체 작동 데모를 확인해 보세요!

사전 요구 사항
시작하기 전에 다음 항목들이 설치되어 있는지 확인하세요:

  • .NET SDK 8+
  • Node.js (npx 및 yarn 포함)
  • llama3:8b 모델이 풀(pull)된 Ollama
  • GitHub 계정 (호스팅 및 배포용)

내부 개발자 포털이 중요한 이유는 무엇인가요?
"내부 개발자 포털 (Internal Developer Portal, IDP)"이라는 용어는 마치 개발자만을 위한 전용 도구처럼 들릴 수 있어 약간 오해의 소지가 있습니다. 실제로 이는 여러분의 소프트웨어 포트폴리오(Software Portfolio)에 전적으로 집중하는 내부 조직 포털로서 기능합니다. 모든 것이 한곳에 쏟아져 있고 아무것도 찾기 쉬운 것이 없는 범용 SharePoint 사이트와 달리, IDP는 의도적으로 범위가 좁게 설정되어 있습니다.

IDP는 소프트웨어 환경만을 다루며 그 외의 것은 다루지 않는데, 바로 이 점이 IDP를 강력하게 만드는 핵심입니다. IDP는 엔지니어링 조직을 위한 단일 진실 공급원 (Single Source of Truth)이 됩니다. IDP는 모든 역할에 걸쳐 다음과 같은 중요한 질문들에 답을 제공합니다: 엔지니어: 어떤 서비스가 존재하는가? 누가 소유하고 있는가? 그 서비스들은 무엇을 하는가? API는 무엇이며 어떻게 호출하는가? 팀 리드 및 아키텍트: 팀 구성은 어떻게 되어 있는가? 어떤 스쿼드(Squad)가 어떤 서비스 세트를 소유하고 있는가? 어떤 아키텍처 결정이 내려졌으며 그 이유는 무엇인가? 신규 입사자: 한 번도 본 적 없는 코드베이스에 어떻게 빠르게 적응할 수 있는가? 플랫폼 및 운영 팀: 프로덕션(Production) 환경에서 무엇이 실행 중인가, 책임자는 누구인가, 그리고 라이프사이클 상태는 어떠한가? 단순히 서비스를 나열하는 것을 넘어, 성숙한 IDP는 아키텍처 결정 기록 (Architecture Decision Records, ADRs)을 중앙 집중화하며, 이는 아마도 IDP의 가장 가치 있는 기능 중 하나일 것입니다. ADR은 무엇이 결정되었는지만이 아니라, 왜 그런 결정이 내려졌는지를 기록합니다. 이를 드러낼 중앙 장소가 없다면, ADR은 잊혀진 위키 페이지나 아무도 확인하려 하지 않는 Git 리포지토리 속에서 부패하게 됩니다. 문제는 이 모든 정보를 최신 상태로 유지하고 정확하게 관리하는 것입니다. 만약 엔지니어들이 수동으로 메타데이터 YAML 파일을 유지 관리하도록 의존한다면, 데이터는 몇 주 내에 노후화됩니다. 자동화만이 유일하고 지속 가능한 경로입니다.

아키텍처 구성하기
소스 코드에서 메타데이터를 추출하여 시각적으로 제시하기 위한 계획은 다음과 같습니다:
Backstage: 엔지니어가 서비스, API, 문서 및 팀 소유권을 탐색하고 발견하는 UI 레이어
.NET Core: 프로젝트 폴더를 스캔하고, 메타데이터를 추출하며, Backstage와 호환되는 YAML을 생성하는 CLI 도구
Ollama: AI 추론 (Inference)을 로컬에서 실행하므로 소스 코드가 기기를 절대 떠나지 않음
정적 호스팅 (Static hosting): Netlify, Azure Static Web Apps 또는 원하는 모든 제공업체에 배포

정보: 왜 Ollama인가? Ollama는 로컬에서 실행되기 때문입니다. 여러분은 코드를 공용 인터넷을 통해 AI 에이전트에게 노출하고 싶지 않을 것입니다. 그들이 코드를 무엇에 어떻게 사용하는지 알 수 없으며, 이는 안전하다고 느껴지지 않습니다. 만약 고용주가 이 사실을 알게 된다면, 여러분의 직장 생활은 끝날 수도 있습니다.

프로젝트 인프라 설정하기

모든 것을 처음부터 직접 구축하며 따라오거나, 데모 리포지토리(repository)를 클론(clone)하여 즉시 시작할 수 있습니다. 데모를 클론하려면 다음 명령어를 사용하세요:

git clone https://github.com/bgener/demo-backstage-catalog-generator.git
cd demo-backstage-catalog-generator

처음부터 직접 구축하려면, 이 가이드에서 사용할 LLM (Large Language Model) 모델을 다운로드하고 실행하는 것부터 시작하세요:

ollama pull llama3:8b
ollama serve

팁: 저희는 특히 llama3:8b를 사용합니다. 이 모델은 전체 크기의 모델보다 로컬 추론 (inference) 속도가 현저히 빠르며, 우리의 사용 사례에 대해 더 일관되고 간결한 출력을 생성합니다. 만약 강력한 GPU를 보유하고 있다면, llama3를 자유롭게 사용하셔도 좋습니다.

다음으로, 기본 .NET 서비스들을 스캐폴딩 (scaffold) 합니다. 하나의 Web API와 하나의 MVC 프로젝트를 생성하겠습니다:

mkdir Backstage-Dev-Portal
cd Backstage-Dev-Portal
dotnet new webapi -n ServiceA
dotnet new mvc -n ServiceB
dotnet new sln -n Backstage-Dev-Portal
dotnet sln add ServiceA/ServiceA.csproj
dotnet sln add ServiceB/ServiceB.csproj

나중에 기본 컨트롤러 (controller)를 실제 로직으로 교체할 수 있습니다. 이 가공되지 않은 서비스들은 조직 내에서 카탈로그화되지 않은 마이크로서비스 (microservices)를 나타냅니다.

.NET으로 스마트 카탈로그 생성기 구축하기

저희는 OllamaSharp를 사용하여 .NET CLI 도구를 구축할 것입니다. 이 도구는 각 프로젝트를 스캔하고, 관련 파일들을 로컬 AI 모델로 전송하며, Backstage가 사용할 수 있도록 모든 서비스가 포함된 단일 catalog-info.yaml 파일을 생성합니다.

도구를 생성하고 필요한 패키지를 추가하세요:

dotnet new console -n ProjectSummarizer
cd ProjectSummarizer
dotnet add package OllamaSharp

모든 파일을 AI에 전송하는 대신, 토큰 제한 (token limits)을 피하고 연산 시간을 절약하기 위해 더 스마트한 접근 방식을 취합니다. 저희는 *.csproj, Program.cs, 그리고 폴더 구조만 전송할 것입니다. 이것이 AI가 프로젝트 구조와 목적을 이해하는 데 필요한 모든 컨텍스트 (context)입니다.

Program.cs를 아래의 구현 내용으로 교체하세요. 전체 버전은 데모 리포지토리에 있습니다. 여기서는 핵심 부분에 집중하겠습니다. 먼저, Ollama 클라이언트를 설정하고 시스템 프롬프트 (system prompt)를 구성합니다.

이 부분은 체인에서 가장 취약한 부분입니다. 시스템 프롬프트 (system prompt)는 모델이 마크다운 백틱 (markdown backticks)을 환각 (hallucination)하지 않으면서, YAML에 안전한 형식으로 출력하도록 강제해야 합니다:

var ollamaApiClient = new OllamaApiClient ( new Uri ( "http://localhost:11434" )) { SelectedModel = "llama3:8b" }; var chat = new Chat ( ollamaApiClient , systemPrompt : "You are a technical documentation assistant. " + "You produce concise, YAML-safe summaries of .NET projects. " + "Output only plain text, no markdown, no bullet points, no quotes, no colons, no newlines." );

모든 파일을 AI에 보내는 대신, *.csproj, Program.cs, 그리고 폴더 구조만 보냅니다. 이것이 모델에 필요한 모든 컨텍스트 (context)입니다. 경고: 프롬프트 정제 (Prompt sanitization)는 매우 중요합니다. 만약 Program.cs에 복잡한 문자열 리터럴 (string literals)이나 중첩된 콜론 (colons)이 포함되어 있다면, AI가 이를 YAML에 그대로 전달하여 Backstage 파서 (parser)를 망가뜨릴 수 있습니다. 파일을 쓰기 전에 항상 출력을 정제하십시오.

var sb = new StringBuilder (); sb . AppendLine ( $"Project: { projectName } " ); sb . AppendLine ( "Folder structure:" ); AppendFolderStructure ( projectDir , sb , "" ); sb . AppendLine ( File . ReadAllText ( csprojPath )); var programPath = Directory . GetFiles ( projectDir , "Program.cs" , SearchOption . AllDirectories ) . FirstOrDefault (); if ( programPath != null ) sb . AppendLine ( File . ReadAllText ( programPath ));

프롬프트 자체는 모델이 우리가 원하는 출력 형식으로 유도되도록 퓨샷 예시 (few-shot examples)를 사용합니다:

var prompt = "Summarize the project in 1-2 sentences based on the files provided. " + "Do not output anything else. " + "Examples of good output: " + "REST API service providing weather forecasts with temperature data\n" + "ASP.NET MVC application with React frontend for managing todo items\n\n" + sb . ToString ();

await foreach ( var token in chat . SendAsync ( prompt , cts . Token )) summaryBuilder . Append ( token );

마지막으로, 각 요약은 정제되어 Backstage와 호환되는 YAML 엔트리 (entry)로 조립됩니다:

var summary = summaryBuilder . ToString ().

Trim() . Replace ( "\n" , " " ). Replace ( ":" , " -" ). Replace ( """ , "'" ); var yamlEntry = $ @" apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: { projectName . ToLowerInvariant ()} description: "" { summary } "" spec: type: service lifecycle: production owner: group:default/engineering"; 대상 디렉터리에 대해 생성기를 실행합니다 (이미 프로젝트 루트에 있다면 . 을 사용하세요): dotnet run --project ProjectSummarizer -- . AI가 실시간으로 요약을 스트리밍하는 것을 볼 수 있습니다: 여기서 실제 작업의 대부분은 프롬프트 (prompt)를 결정하는 것입니다. 아주 작은 변화만으로도 완전히 다른 출력이 생성될 수 있습니다. 품질에 어떤 영향을 미치는지 확인하기 위해 시스템 프롬프트 (system prompt)와 사용자 프롬프트 (user prompt)를 실험해 보시길 권장합니다. 그것이 여기서 얻을 수 있는 진짜 학습입니다.

AI 카탈로그를 Backstage와 통합하기

catalog-info.yaml이 준비되었으므로, 이를 Backstage 인스턴스에 통합할 수 있습니다.

Backstage 설치하기:
npx @backstage/create-app

안내에 따라 이름을 dev-portal로 지정합니다. 이제 Backstage가 생성된 카탈로그 파일을 가리키도록 설정합니다. dev-portal 디렉터리에 있는 app-config.yaml을 열고 catalog 섹션 아래에 다음을 추가합니다:

catalog :
locations :
- type : file
target : ../Backstage-Dev-Portal/catalog-info.yaml
rules :
- allow : [ Component ]

이 설정은 Backstage에 AI가 생성한 서비스 메타데이터 (metadata)를 어디에서 찾을지 알려줍니다. target 경로는 Backstage 루트 디렉터리를 기준으로 상대적입니다. 생성기가 catalog-info.yaml을 작성한 위치를 가리키도록 경로를 조정하세요.

로컬에서 실행하려면:
cd dev-portal
yarn dev

브라우저에서 http://localhost:3000 을 엽니다. 소프트웨어 카탈로그 (Software Catalog)에 모든 서비스가 나열되어 있고, 설명 (description) 열에 AI가 생성한 요약이 표시되는 것을 볼 수 있습니다.

포털 배포하기

이를 호스팅하려면 포털을 정적 사이트 (static site)로 빌드합니다:
yarn build:static

출력물을 GitHub에 푸시하고 Netlify, Azure Static Web Apps, Vercel 또는 Kubernetes에 직접 호스팅하는 방식 등 어떤 정적 호스팅 제공업체에도 배포할 수 있습니다. 빌드 명령 (build command)을 yarn build:static으로, 게시 디렉터리 (publish directory)를 dist로 설정하세요.

정보: 정적(static) Backstage 빌드는 읽기 전용 카탈로그(read-only catalogs)에 매우 적합합니다. 인증(authentication), 실시간 플러그인 백엔드(real-time plugin backends), 또는 쓰기 작업(write operations)과 같은 동적 기능이 필요한 경우, 대신 전체 Backstage 백엔드를 Node.js 서비스로 배포해야 합니다.

CI/CD를 통한 자동화
진정한 가치는 카탈로그 생성기(catalog generator)를 자동으로 실행하는 데서 옵니다. 다음은 main 브랜치로 푸시(push)될 때마다 요약본을 재생성하는 GitHub Actions 워크플로우입니다:

name: Update Backstage Catalog
on: push
branches: [ main ]
jobs: generate-catalog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Install and start Ollama
run: |
curl -fsSL https://ollama.com/install.sh | sh
ollama serve &
sleep 5
ollama pull llama3:8b
- name: Generate catalog
run: dotnet run --project ProjectSummarizer -- "$GITHUB_WORKSPACE"
- name: Commit updated catalog
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
git add catalog-info.yaml
git diff --cached --quiet || git commit -m "chore: regenerate AI catalog summaries"
git push

경고: CI 성능: CI에서 Ollama를 실행하면 기본적으로 CPU 전용 추론(CPU-only inference)을 사용합니다. 표준 GitHub 러너(runner)에서 llama3:8b 요약은 프로젝트당 약 20~30초가 소요됩니다. 대규모 모노레포(monorepo)의 경우 CI 비용이 급증할 수 있습니다. 규모를 확장할 계획이라면 GPU가 장착된 지속적인 셀프 호스팅 러너(self-hosted runner) 사용을 고려하세요.

마치며
실질적인 규칙은 간단합니다. 메타데이터 생성은 코드가 있는 곳에서 자동화하되, UI(Backstage)는 가벼운 정적 클라이언트(static client)로 유지하세요. 이렇게 하면 운영 환경에 무거운 런타임 의존성(runtime dependency)을 추가하지 않고도 "오래된 문서(stale documentation)" 문제를 방지할 수 있습니다.

좁은 컨텍스트 사용: AI에 저장소 전체를 보내지 마세요. Program.cs 및 *.csproj와 같은 파일만으로도 충분한 경우가 많습니다.
엄격한 정제(Sanitize): AI 출력은 비결정론적(non-deterministic)입니다. YAML에 쓰기 전에는 항상 콜론(:)과 줄바꿈을 제거하세요.

정적 시작 (Start static): 읽기 전용 정적 포털은 동적 포털보다 유지 관리하기가 10배 더 쉽습니다. FAQ: Ollama 대신 OpenAI를 사용할 수 있나요? 네, 하지만 소스 코드(또는 최소한 Program.cs)를 제3자에게 전송하게 됩니다. 보안이 우려된다면 로컬 모델 (local model)을 사용하세요. 이것이 README 파일을 대체하나요? 아니요. 이것은 보통 스프레드시트에 존재하는 "서비스 디렉토리 (Service Directory)"를 대체합니다. 엔지니어들이 실제로 필요로 하는 README로 안내하는 역할을 합니다. 프로젝트 이름 변경은 어떻게 처리하나요? 생성기 (generator)는 폴더 이름 또는 .csproj 이름을 사용합니다. 이름을 변경하면 정체성 (identity)을 안정적으로 매핑하지 않는 한, Backstage는 이를 새로운 컴포넌트 (component)로 인식합니다. 저는 개발자 포털부터 플랫폼 엔지니어링 (platform engineering)에 이르기까지 바로 이러한 종류의 내부 도구 구축을 돕고 있습니다. 제 작업물을 확인하거나 연락해 주세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0