본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 5장: AI 기반 문서화 자동화
2026년 1월 27일·AI / ML·

5장: AI 기반 문서화 자동화

코드 변경에 따라 API 문서, README, 변경 로그를 AI로 자동 갱신하는 시스템을 구축하고, 문서와 코드의 동기화를 유지하는 전략을 다룹니다.

19분976자9개 섹션
devtoolsautomationcode-qualitydevopsllm
공유
ai-dev-workflow5 / 10
12345678910
이전4장: AI 기반 테스트 자동 생성다음6장: PR 분석과 변경 영향도 예측

문서화의 고질적 문제

소프트웨어 프로젝트에서 문서는 코드 다음으로 중요한 자산입니다. 그러나 대부분의 프로젝트에서 문서는 코드의 변경 속도를 따라가지 못합니다. 새로운 API가 추가되어도 문서는 갱신되지 않고, 파라미터가 변경되어도 README는 이전 버전의 사용법을 안내합니다.

이 문제의 근본 원인은 명확합니다. 문서 갱신이 별도의 수작업이기 때문입니다. 개발자는 코드를 수정한 후 관련 문서를 찾아서 일일이 갱신해야 합니다. 이 과정은 번거롭고, 누락되기 쉽습니다.

AI 기반 문서화 자동화는 이 문제를 해결합니다. 코드 변경을 분석하여 영향을 받는 문서를 식별하고, 해당 문서를 자동으로 갱신합니다.

text
문서화 자동화의 목표:
 
  1. 코드와 문서의 동기화 유지
  2. API 변경 시 문서 자동 갱신
  3. PR별 변경 로그 자동 생성
  4. README의 사용법 예시 최신 상태 유지
  5. 새 함수/클래스의 JSDoc/docstring 자동 생성

문서화 자동화 시스템 아키텍처

전체 구조

문서화 자동화 시스템은 세 개의 핵심 모듈로 구성됩니다.

영향 분석 모듈

코드 변경이 어떤 문서에 영향을 미치는지 식별하는 모듈입니다. 변경의 성격에 따라 갱신해야 할 문서 유형이 달라집니다.

src/doc-impact-analyzer.ts
typescript
interface DocImpact {
  // 영향 받는 문서 파일
  affectedDocs: AffectedDoc[]
  // 새로 생성해야 할 문서
  newDocs: NewDocSpec[]
  // 인라인 문서가 필요한 코드
  missingInlineDocs: InlineDocSpec[]
}
 
interface AffectedDoc {
  filePath: string
  docType: "api" | "readme" | "changelog" | "guide"
  // 문서에서 갱신이 필요한 섹션
  affectedSections: string[]
  // 영향을 준 코드 변경
  sourceChanges: FileChange[]
}
 
interface InlineDocSpec {
  filePath: string
  functionName: string
  lineNumber: number
  // 기존 문서 존재 여부
  hasExistingDoc: boolean
}
 
async function analyzeDocImpact(
  changes: FileChange[]
): Promise<DocImpact> {
  const impact: DocImpact = {
    affectedDocs: [],
    newDocs: [],
    missingInlineDocs: [],
  }
 
  for (const change of changes) {
    // API 엔드포인트 변경 감지
    if (isApiFile(change.filename)) {
      const apiChanges = extractApiChanges(change)
      if (apiChanges.length > 0) {
        impact.affectedDocs.push({
          filePath: findApiDocPath(change.filename),
          docType: "api",
          affectedSections: apiChanges.map(
            a => a.endpoint
          ),
          sourceChanges: [change],
        })
      }
    }
 
    // 공개 인터페이스 변경 감지
    if (isPublicModule(change.filename)) {
      const exportChanges = extractExportChanges(change)
      if (exportChanges.length > 0) {
        impact.affectedDocs.push({
          filePath: "README.md",
          docType: "readme",
          affectedSections: ["Usage", "API Reference"],
          sourceChanges: [change],
        })
      }
    }
 
    // 인라인 문서 누락 감지
    const undocumentedFunctions = findUndocumentedFunctions(
      change
    )
    for (const func of undocumentedFunctions) {
      impact.missingInlineDocs.push({
        filePath: change.filename,
        functionName: func.name,
        lineNumber: func.line,
        hasExistingDoc: false,
      })
    }
  }
 
  // CHANGELOG는 항상 갱신 대상
  impact.affectedDocs.push({
    filePath: "CHANGELOG.md",
    docType: "changelog",
    affectedSections: ["Unreleased"],
    sourceChanges: changes,
  })
 
  return impact
}

API 문서 자동 갱신

OpenAPI 스펙 갱신

REST API를 제공하는 프로젝트에서 OpenAPI(Swagger) 스펙을 코드 변경에 맞춰 자동 갱신하는 방법을 다룹니다.

src/api-doc-updater.ts
typescript
interface ApiChange {
  type: "added" | "modified" | "removed"
  method: string          // GET, POST, PUT, DELETE
  endpoint: string        // /api/users/:id
  changes: {
    parameters?: ParameterChange[]
    requestBody?: BodyChange
    response?: ResponseChange
  }
}
 
async function updateApiDocs(
  apiChanges: ApiChange[],
  existingSpec: string
): Promise<string> {
  const prompt = `다음 API 변경 사항을 반영하여 OpenAPI 스펙을 갱신해 주세요.
 
## 현재 OpenAPI 스펙
\`\`\`yaml
` + existingSpec + `
\`\`\`
 
## API 변경 사항
`
    + apiChanges.map(change => {
        return "- [" + change.type.toUpperCase() + "] "
          + change.method + " " + change.endpoint
          + ": " + JSON.stringify(change.changes)
      }).join("\n")
    + `
 
## 규칙
1. 기존 스펙의 형식과 스타일을 유지합니다.
2. 변경된 부분만 수정합니다.
3. description은 한글로 작성합니다.
4. 응답 스키마에 예시를 포함합니다.
 
갱신된 전체 OpenAPI 스펙을 YAML 형식으로 응답하세요.
`
 
  const updatedSpec = await callLLM(prompt)
  return extractYamlBlock(updatedSpec)
}

TypeScript 타입 기반 문서 생성

TypeScript 프로젝트에서는 타입 정의를 기반으로 API 문서를 생성할 수 있습니다. 타입이 곧 문서의 소스 오브 트루스(Source of Truth) 역할을 합니다.

src/type-doc-generator.ts
typescript
// 타입 정의에서 문서를 생성하는 예시
 
// 입력: 타입 정의
interface CreateUserRequest {
  /** 사용자 이메일 (고유) */
  email: string
  /** 사용자 이름 (2-50자) */
  name: string
  /** 비밀번호 (최소 8자, 영문+숫자+특수문자) */
  password: string
  /** 프로필 이미지 URL (선택) */
  avatarUrl?: string
}
 
interface CreateUserResponse {
  /** 생성된 사용자 ID */
  id: string
  /** 사용자 이메일 */
  email: string
  /** 사용자 이름 */
  name: string
  /** 계정 생성 시각 (ISO 8601) */
  createdAt: string
}
 
// LLM에게 타입 정의를 전달하면 다음과 같은 문서를 생성합니다:
 
/*
생성 결과 예시:
 
## POST /api/users
 
사용자를 생성합니다.
 
### Request Body
 
| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| email | string | O | 사용자 이메일 (고유) |
| name | string | O | 사용자 이름 (2-50자) |
| password | string | O | 비밀번호 (최소 8자) |
| avatarUrl | string | X | 프로필 이미지 URL |
 
### Response (201 Created)
 
| 필드 | 타입 | 설명 |
|------|------|------|
| id | string | 생성된 사용자 ID |
| email | string | 사용자 이메일 |
| name | string | 사용자 이름 |
| createdAt | string | 계정 생성 시각 (ISO 8601) |
*/

인라인 문서 자동 생성

JSDoc / TSDoc 생성

새로 작성되거나 수정된 함수에 대해 JSDoc 주석을 자동 생성합니다.

src/jsdoc-generator.ts
typescript
async function generateJSDoc(
  functionCode: string,
  context: string
): Promise<string> {
  const prompt = `다음 함수에 대한 JSDoc 주석을 생성해 주세요.
 
## 함수 코드
\`\`\`typescript
` + functionCode + `
\`\`\`
 
## 주변 맥락
\`\`\`typescript
` + context + `
\`\`\`
 
## JSDoc 작성 규칙
1. 함수의 목적을 한 문장으로 요약합니다.
2. 각 매개변수의 의미와 제약 조건을 설명합니다.
3. 반환값의 의미를 설명합니다.
4. throws 절이 있으면 에러 조건을 문서화합니다.
5. 비자명한 동작이 있으면 주의사항을 추가합니다.
6. 한글로 작성합니다.
 
JSDoc 주석만 응답하세요 (함수 코드는 제외).
`
 
  return await callLLM(prompt)
}

생성 결과의 예시입니다.

typescript
/**
 * 주어진 조건에 맞는 사용자 목록을 페이지네이션하여 조회합니다.
 *
 * @param filter - 검색 조건
 * @param filter.role - 사용자 역할 필터 (선택)
 * @param filter.status - 계정 상태 필터 (선택)
 * @param filter.createdAfter - 이 시점 이후 생성된 사용자만 조회
 * @param pagination - 페이지네이션 옵션
 * @param pagination.page - 페이지 번호 (1부터 시작)
 * @param pagination.pageSize - 페이지당 항목 수 (기본값: 20, 최대: 100)
 * @returns 페이지네이션된 사용자 목록과 전체 개수
 * @throws {ValidationError} 유효하지 않은 페이지 번호나 페이지 크기
 * @throws {DatabaseError} 데이터베이스 연결 실패
 */
async function findUsers(
  filter: UserFilter,
  pagination: PaginationOptions
): Promise<PaginatedResult<User>> {
  // ...
}

CHANGELOG 자동 생성

Conventional Commits 기반 분류

커밋 메시지가 Conventional Commits 형식을 따르는 경우, 커밋을 자동으로 분류하여 CHANGELOG를 생성할 수 있습니다.

src/changelog-generator.ts
typescript
interface ChangelogEntry {
  version: string
  date: string
  categories: {
    features: ChangeItem[]
    fixes: ChangeItem[]
    breaking: ChangeItem[]
    performance: ChangeItem[]
    docs: ChangeItem[]
    refactor: ChangeItem[]
  }
}
 
interface ChangeItem {
  description: string
  scope?: string
  commit: string
  pr?: number
}
 
function categorizeCommits(
  commits: CommitInfo[]
): ChangelogEntry["categories"] {
  const categories = {
    features: [] as ChangeItem[],
    fixes: [] as ChangeItem[],
    breaking: [] as ChangeItem[],
    performance: [] as ChangeItem[],
    docs: [] as ChangeItem[],
    refactor: [] as ChangeItem[],
  }
 
  for (const commit of commits) {
    const parsed = parseConventionalCommit(commit.message)
    if (!parsed) continue
 
    const item: ChangeItem = {
      description: parsed.description,
      scope: parsed.scope,
      commit: commit.sha.slice(0, 7),
      pr: extractPRNumber(commit.message),
    }
 
    if (parsed.breaking) {
      categories.breaking.push(item)
    }
 
    switch (parsed.type) {
      case "feat":
        categories.features.push(item)
        break
      case "fix":
        categories.fixes.push(item)
        break
      case "perf":
        categories.performance.push(item)
        break
      case "docs":
        categories.docs.push(item)
        break
      case "refactor":
        categories.refactor.push(item)
        break
    }
  }
 
  return categories
}

AI 기반 CHANGELOG 요약

커밋 메시지만으로는 사용자 관점의 변경 내용을 파악하기 어려운 경우가 있습니다. AI를 활용하면 코드 변경의 실제 영향을 사용자 관점에서 요약할 수 있습니다.

src/ai-changelog.ts
typescript
async function generateAIChangelog(
  commits: CommitInfo[],
  diffs: FileDiff[]
): Promise<string> {
  const prompt = `다음 커밋 목록과 코드 변경 내용을 분석하여,
사용자 관점의 CHANGELOG를 작성해 주세요.
 
## 커밋 목록
` + commits.map(c => "- " + c.sha.slice(0, 7) + " " + c.message).join("\n") + `
 
## 주요 코드 변경
` + diffs.map(d => {
    return "### " + d.filename + "\n"
      + "```diff\n" + d.patch + "\n```"
  }).join("\n\n") + `
 
## CHANGELOG 작성 규칙
1. 사용자가 체감하는 변경만 포함합니다.
2. 내부 리팩터링은 제외합니다.
3. 각 항목은 "했습니다" 형식의 완결된 문장으로 작성합니다.
4. Breaking Change가 있으면 마이그레이션 방법을 안내합니다.
5. 새 기능은 간단한 사용 예시를 포함합니다.
 
Markdown 형식으로 응답하세요.
`
 
  return await callLLM(prompt)
}

README 자동 갱신

변경 감지와 섹션별 갱신

README의 특정 섹션만 선택적으로 갱신하는 방법을 설계합니다.

src/readme-updater.ts
typescript
interface ReadmeSection {
  title: string
  startLine: number
  endLine: number
  content: string
}
 
function parseReadmeSections(readme: string): ReadmeSection[] {
  const lines = readme.split("\n")
  const sections: ReadmeSection[] = []
  let currentSection: ReadmeSection | null = null
 
  for (let i = 0; i < lines.length; i++) {
    const headingMatch = lines[i].match(/^(#{1,3})\s+(.+)/)
    if (headingMatch) {
      if (currentSection) {
        currentSection.endLine = i - 1
        currentSection.content = lines
          .slice(currentSection.startLine, i)
          .join("\n")
        sections.push(currentSection)
      }
      currentSection = {
        title: headingMatch[2],
        startLine: i,
        endLine: lines.length - 1,
        content: "",
      }
    }
  }
 
  if (currentSection) {
    currentSection.content = lines
      .slice(currentSection.startLine)
      .join("\n")
    sections.push(currentSection)
  }
 
  return sections
}
 
async function updateReadmeSection(
  sectionTitle: string,
  currentContent: string,
  codeChanges: FileChange[]
): Promise<string> {
  const prompt = `README의 "` + sectionTitle + `" 섹션을 코드 변경에 맞게 갱신해 주세요.
 
## 현재 섹션 내용
` + currentContent + `
 
## 관련 코드 변경
` + codeChanges.map(c => {
    return "### " + c.filename + "\n```diff\n" + c.patch + "\n```"
  }).join("\n\n") + `
 
## 규칙
1. 기존 문서의 스타일과 톤을 유지합니다.
2. 변경된 부분만 수정합니다.
3. 코드 예시가 있으면 최신 API에 맞게 갱신합니다.
4. 새로운 기능이 추가되었으면 해당 내용을 추가합니다.
5. 제거된 기능이 있으면 해당 내용을 삭제합니다.
 
갱신된 섹션 내용만 응답하세요.
`
 
  return await callLLM(prompt)
}

문서화 파이프라인 통합

GitHub Actions 워크플로우

문서화 자동화를 GitHub Actions에 통합합니다. 코드 변경 PR이 머지되면 문서 갱신 PR을 자동으로 생성합니다.

.github/workflows/ai-docs.yml
yaml
name: AI Documentation Update
 
on:
  pull_request:
    types: [closed]
    branches: [main]
 
permissions:
  contents: write
  pull-requests: write
 
jobs:
  update-docs:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
 
      - run: npm install
 
      - name: Analyze changes and update docs
        env:
          ANTHROPIC_API_KEY: $ANTHROPIC_KEY_VALUE
          GITHUB_TOKEN: $GITHUB_TOKEN_VALUE
        run: node scripts/update-docs.js
 
      - name: Create docs update PR
        env:
          GITHUB_TOKEN: $GITHUB_TOKEN_VALUE
        run: |
          git config user.name "AI Docs Bot"
          git config user.email "ai-docs-bot@example.com"
          BRANCH="docs/auto-update-$(date +%Y%m%d%H%M%S)"
          git checkout -b $BRANCH
          git add -A
          if git diff --staged --quiet; then
            echo "No documentation changes needed"
            exit 0
          fi
          git commit -m "docs: AI-generated documentation update"
          git push origin $BRANCH
          gh pr create \
            --title "docs: auto-update documentation" \
            --body "This PR was automatically generated to update documentation based on recent code changes." \
            --base main \
            --head $BRANCH
Info

문서 갱신 PR을 코드 변경 PR과 분리하면, 문서 변경을 독립적으로 리뷰할 수 있습니다. 문서 갱신이 잘못된 경우에도 코드 변경에는 영향을 주지 않습니다.

문서 품질 검증

코드-문서 일관성 검사

문서가 코드와 일치하는지 자동으로 검증하는 시스템을 구축합니다.

src/doc-consistency-checker.ts
typescript
interface ConsistencyIssue {
  docFile: string
  section: string
  issue: string
  severity: "error" | "warning"
}
 
async function checkDocConsistency(
  sourceFiles: string[],
  docFiles: string[]
): Promise<ConsistencyIssue[]> {
  const issues: ConsistencyIssue[] = []
 
  // 1. API 문서에 없는 엔드포인트 찾기
  const codeEndpoints = extractEndpointsFromCode(sourceFiles)
  const docEndpoints = extractEndpointsFromDocs(docFiles)
 
  for (const endpoint of codeEndpoints) {
    if (!docEndpoints.has(endpoint)) {
      issues.push({
        docFile: "docs/api.md",
        section: "API Reference",
        issue: endpoint + " 엔드포인트가 문서에 없습니다",
        severity: "error",
      })
    }
  }
 
  // 2. 문서에는 있지만 코드에서 제거된 엔드포인트
  for (const endpoint of docEndpoints) {
    if (!codeEndpoints.has(endpoint)) {
      issues.push({
        docFile: "docs/api.md",
        section: "API Reference",
        issue: endpoint + " 엔드포인트가 코드에서 제거되었습니다",
        severity: "error",
      })
    }
  }
 
  // 3. 코드 예시 실행 가능성 검증
  const codeExamples = extractCodeExamples(docFiles)
  for (const example of codeExamples) {
    const isValid = await validateCodeExample(example)
    if (!isValid) {
      issues.push({
        docFile: example.sourceFile,
        section: example.section,
        issue: "코드 예시가 현재 API와 맞지 않습니다",
        severity: "warning",
      })
    }
  }
 
  return issues
}

정리

이 장에서는 AI 기반 문서화 자동화 시스템을 구축했습니다. 영향 분석, API 문서 갱신, 인라인 문서 생성, CHANGELOG 생성, README 갱신, 문서 품질 검증까지 문서화 자동화의 전체 파이프라인을 다루었습니다.

핵심 내용을 정리합니다.

  • 코드 변경을 분석하여 영향을 받는 문서를 자동으로 식별합니다
  • API 변경 시 OpenAPI 스펙과 API 문서를 자동 갱신합니다
  • Conventional Commits과 AI 요약을 결합하여 CHANGELOG를 생성합니다
  • README의 특정 섹션만 선택적으로 갱신하여 기존 문서를 보존합니다
  • 코드-문서 일관성 검사로 문서 품질을 보장합니다

다음 장에서는 PR 분석과 변경 영향도 예측을 다룹니다. PR의 변경 범위와 위험도를 AI로 분석하고, 리뷰어에게 구조화된 인사이트를 제공하는 시스템을 구축합니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#devtools#automation#code-quality#devops#llm

관련 글

AI / ML

6장: PR 분석과 변경 영향도 예측

PR의 변경 범위와 위험도를 AI로 분석하고, 리뷰어에게 구조화된 인사이트를 제공하는 시스템을 구축합니다.

2026년 1월 29일·17분
AI / ML

4장: AI 기반 테스트 자동 생성

코드 변경을 분석하여 단위 테스트와 통합 테스트를 자동으로 생성하는 시스템을 구축하고, 테스트 품질을 검증하는 방법을 다룹니다.

2026년 1월 25일·18분
AI / ML

7장: GitHub Copilot 심층 활용 전략

GitHub Copilot의 인라인 자동 완성, Copilot Chat, Agent Mode를 실전에서 효과적으로 활용하는 전략과 팀 단위 도입 방법을 다룹니다.

2026년 1월 31일·19분
이전 글4장: AI 기반 테스트 자동 생성
다음 글6장: PR 분석과 변경 영향도 예측

댓글

목차

약 19분 남음
  • 문서화의 고질적 문제
  • 문서화 자동화 시스템 아키텍처
    • 전체 구조
    • 영향 분석 모듈
  • API 문서 자동 갱신
    • OpenAPI 스펙 갱신
    • TypeScript 타입 기반 문서 생성
  • 인라인 문서 자동 생성
    • JSDoc / TSDoc 생성
  • CHANGELOG 자동 생성
    • Conventional Commits 기반 분류
    • AI 기반 CHANGELOG 요약
  • README 자동 갱신
    • 변경 감지와 섹션별 갱신
  • 문서화 파이프라인 통합
    • GitHub Actions 워크플로우
  • 문서 품질 검증
    • 코드-문서 일관성 검사
  • 정리