Skip to content
Published on

영어 테크니컬 라이팅: API 문서와 RFC 작성 실전 가이드 2026

Authors
  • Name
    Twitter
영어 테크니컬 라이팅: API 문서와 RFC 작성 실전 가이드 2026

개요: 왜 개발자에게 영어 테크니컬 라이팅이 필요한가

코드는 기계가 읽지만, 문서는 사람이 읽는다. API를 아무리 잘 설계해도 문서가 부실하면 채택률은 떨어진다. Stripe가 "개발자 경험(DX)" 1위로 꼽히는 이유는 뛰어난 API 설계뿐 아니라, 읽기 쉽고 정확한 문서 때문이다. GitHub의 2025 Octoverse 보고서에 따르면, 오픈소스 프로젝트의 컨트리뷰터 수와 문서 품질 사이에 강한 양의 상관관계가 있다.

한국 개발자가 영어 기술 문서 작성에서 겪는 어려움은 크게 세 가지다.

  1. 문법보다 구조의 문제: 영어 실력이 충분해도 "어떤 순서로 무엇을 써야 하는지" 모르면 문서 품질이 낮다
  2. 스타일 가이드 부재: 팀 내 일관된 문체 규칙 없이 각자의 스타일로 쓰면 문서 전체가 혼란스러워진다
  3. 도구와 포맷의 장벽: OpenAPI spec, RFC 형식, changelog 규약 등 표준 포맷에 대한 이해 부족

이 글은 일반적인 영작문 팁이 아니라, 개발자가 실무에서 마주치는 구체적인 문서 유형별 작성법을 다룬다. OpenAPI 3.1 기반 API 문서, IETF 스타일 RFC/디자인 문서, README, changelog까지 실제 템플릿과 코드 예시를 중심으로 정리했다.

테크니컬 라이팅의 핵심 원칙

Diataxis 프레임워크: 문서의 4가지 유형

Daniele Procida가 제안한 Diataxis 프레임워크는 기술 문서를 네 가지 유형으로 분류한다. Python 공식 문서, Django, Canonical(Ubuntu) 등이 이 프레임워크를 채택했다.

유형목적독자 상태예시
Tutorial학습(Learning)처음 시작하는 사용자"Getting Started" 가이드
How-to Guide목표 달성(Goal)특정 문제를 해결하려는 사용자"How to paginate API results"
Reference정보 참조(Information)정확한 스펙이 필요한 사용자API endpoint 목록, 파라미터 표
Explanation이해(Understanding)배경과 맥락을 알고 싶은 사용자"Why we chose eventual consistency"

API 문서를 쓸 때 가장 흔한 실수는 Reference(스펙 나열)만 제공하고 Tutorial이나 How-to Guide를 빠뜨리는 것이다. Stripe, Twilio 같은 성공적인 API 제품들은 네 가지 유형을 모두 갖추고 있다.

3대 스타일 가이드 비교

영어 기술 문서 작성의 표준이 되는 세 가지 스타일 가이드를 비교한다.

항목Google Developer Docs Style GuideMicrosoft Writing Style GuideApple Style Guide
Friendly but not informalWarm and relaxed, crisp and clearSimple and direct
인칭2인칭(you) 권장2인칭(you) 권장2인칭(you) 권장
능동태강력 권장강력 권장강력 권장
문장 길이26단어 이하 권장짧고 간결하게간결성 강조
옥스포드 콤마사용사용사용
축약형허용(it's, you're)허용제한적 허용
코드 표기backtick으로 코드 감싸기code formatting 사용코드 폰트 사용
접근성높은 우선순위높은 우선순위높은 우선순위

세 가이드 모두 공통적으로 강조하는 핵심은 명확성(clarity), 간결성(conciseness), 일관성(consistency)이다. 팀에서 하나를 선택해 기준으로 삼되, 프로젝트 내부 스타일 가이드를 우선하는 것이 Google의 권장 사항이다.

API 문서 작성법

OpenAPI 3.1 스펙 기반 문서화

OpenAPI 3.1은 JSON Schema 2020-12와 완전히 호환되며, 웹훅(Webhook) 지원이 추가되어 현재 API 문서화의 사실상 표준이다. 다음은 사용자 관리 API의 OpenAPI 스펙 예시다.

openapi: 3.1.0
info:
  title: User Management API
  version: 2.1.0
  description: |
    Manages user accounts, authentication, and profile data.

    ## Authentication
    All endpoints require a Bearer token in the Authorization header.
    Obtain a token via `POST /auth/token`.

    ## Rate Limiting
    - Authenticated requests: 1000 requests per minute
    - Unauthenticated requests: 60 requests per minute
  contact:
    name: API Support
    email: api-support@example.com
    url: https://developer.example.com/support

servers:
  - url: https://api.example.com/v2
    description: Production
  - url: https://staging-api.example.com/v2
    description: Staging

paths:
  /users:
    get:
      operationId: listUsers
      summary: List all users
      description: |
        Returns a paginated list of users. Results are sorted by
        creation date in descending order by default.
      parameters:
        - name: page
          in: query
          description: Page number (1-indexed)
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: per_page
          in: query
          description: Number of results per page (max 100)
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: status
          in: query
          description: Filter by account status
          schema:
            type: string
            enum: [active, inactive, suspended]
      responses:
        '200':
          description: A paginated list of users
          headers:
            X-Total-Count:
              description: Total number of users matching the query
              schema:
                type: integer
            X-Rate-Limit-Remaining:
              description: Number of requests remaining in the current window
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/User'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'

components:
  schemas:
    User:
      type: object
      required: [id, email, created_at]
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the user
          examples: ['550e8400-e29b-41d4-a716-446655440000']
        email:
          type: string
          format: email
          description: User's email address
        display_name:
          type: ['string', 'null']
          description: User's display name. Null if not set.
          maxLength: 100
        status:
          type: string
          enum: [active, inactive, suspended]
          description: Current account status
        created_at:
          type: string
          format: date-time
          description: Account creation timestamp (ISO 8601)

    Pagination:
      type: object
      properties:
        current_page:
          type: integer
        total_pages:
          type: integer
        total_count:
          type: integer

  responses:
    Unauthorized:
      description: Authentication credentials are missing or invalid
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: 'UNAUTHORIZED'
              message: 'Bearer token is missing or expired'

    RateLimited:
      description: Too many requests
      headers:
        Retry-After:
          description: Seconds to wait before retrying
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: 'RATE_LIMITED'
              message: 'Rate limit exceeded. Retry after 30 seconds.'

    Error:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: string
              description: Machine-readable error code
            message:
              type: string
              description: Human-readable error description
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  reason:
                    type: string

이 스펙에서 주목할 포인트를 정리한다.

  • description 필드를 충분히 활용: summary는 한 줄 요약이고, description은 상세 설명이다. 둘 다 채운다
  • examples 제공: 스키마에 examples를 포함하면 자동 생성 문서의 가독성이 크게 향상된다
  • 에러 응답 표준화: 모든 에러를 $ref로 참조하는 공통 Error 스키마로 통일한다
  • Rate Limiting 정보 명시: 헤더와 info 섹션 모두에 명시한다

엔드포인트 문서 작성 규칙

개별 엔드포인트를 문서화할 때 따라야 할 규칙이다.

1. Summary는 동사로 시작한다

Good:  "List all users"
Good:  "Create a new payment intent"
Good:  "Delete a webhook endpoint"

Bad:   "This endpoint lists all users"
Bad:   "Getting user information"
Bad:   "User list"

2. Description은 "무엇을 하는가"와 "주의할 점"을 포함한다

Good:
  Returns a paginated list of users. Results are sorted by creation
  date in descending order by default. Only returns users within
  the authenticated organization's scope.

Bad:
  Gets users.

3. 파라미터에는 제약 조건과 기본값을 반드시 명시한다

Good:
  per_page (integer) - Number of results per page.
  Minimum: 1, Maximum: 100, Default: 20

Bad:
  per_page (integer) - Page size.

에러 코드 문서화

API 에러 응답은 개발자가 가장 자주 참조하는 문서 중 하나다. 다음은 에러 코드를 체계적으로 문서화하는 구조다.

# Error Response Documentation Template
errors:
  - code: 'VALIDATION_ERROR'
    status: 400
    description: 'Request body or query parameters failed validation'
    causes:
      - 'Required field is missing'
      - 'Field value exceeds maximum length'
      - 'Invalid enum value'
    example:
      error:
        code: 'VALIDATION_ERROR'
        message: 'Validation failed'
        details:
          - field: 'email'
            reason: 'must be a valid email address'
          - field: 'display_name'
            reason: 'must not exceed 100 characters'

  - code: 'RESOURCE_NOT_FOUND'
    status: 404
    description: 'The requested resource does not exist or you lack permission to access it'
    causes:
      - 'Resource was deleted'
      - 'Resource ID is malformed'
      - 'Resource belongs to a different organization'
    example:
      error:
        code: 'RESOURCE_NOT_FOUND'
        message: 'User 550e8400-e29b-41d4-a716-446655440000 not found'

  - code: 'CONFLICT'
    status: 409
    description: 'The request conflicts with the current state of the resource'
    causes:
      - 'Email address already registered'
      - 'Concurrent modification detected (stale ETag)'
    example:
      error:
        code: 'CONFLICT'
        message: 'A user with this email already exists'
        details:
          - field: 'email'
            reason: 'already_exists'

  - code: 'INTERNAL_ERROR'
    status: 500
    description: 'An unexpected server error occurred. The team has been notified.'
    causes:
      - 'Unhandled exception'
      - 'Downstream service failure'
    example:
      error:
        code: 'INTERNAL_ERROR'
        message: 'An internal error occurred. Reference ID: req_abc123'

에러 문서화에서 핵심 규칙은 다음과 같다.

  • 원인(causes)을 나열한다: "400 Bad Request"만으로는 디버깅이 불가능하다. 어떤 상황에서 이 에러가 발생하는지 명시한다
  • example을 반드시 포함한다: 개발자는 실제 응답 형태를 보고 에러 핸들링 코드를 작성한다
  • 보안 고려: 404와 403을 구분하면 리소스 존재 여부가 노출된다. 보안이 중요하면 둘 다 404로 응답하고 문서에 이를 명시한다
  • Reference ID 제공: 500 에러에는 추적 가능한 reference ID를 포함해 지원 요청 시 사용하도록 안내한다

API 문서 도구 비교

도구유형OpenAPI 지원주요 특징가격
Swagger UI오픈소스3.0, 3.1인터랙티브 테스트 콘솔, 가장 큰 커뮤니티무료
Redoc오픈소스3.0, 3.13-panel 레이아웃, 깔끔한 디자인, 주간 100만 다운로드무료 (Redocly Pro 유료)
StoplightSaaS3.0, 3.1Design-first 접근, 모킹, 거버넌스유료 (SmartBear 인수)
MintlifySaaS3.0, 3.1MDX 기반, 커스터마이징 용이무료 플랜 존재
ReadMeSaaS3.0, 3.1인터랙티브 문서, API 메트릭스유료
Bump.shSaaS3.0, 3.1Git 연동 자동 배포, diff 추적무료 플랜 존재

스타트업이나 오픈소스 프로젝트라면 Redoc으로 시작하는 것을 권장한다. 설정 없이 빠르게 배포 가능하며, 프로덕션 수준의 문서를 즉시 생성한다. 엔터프라이즈 환경에서는 Redocly Pro나 ReadMe가 API 메트릭스와 버전 관리를 지원해 적합하다.

RFC/디자인 문서 작성법

RFC의 목적과 구조

소프트웨어 엔지니어링에서 RFC(Request for Comments)는 IETF의 인터넷 표준 문서에서 유래했지만, 현재는 사내 기술 의사결정 문서로 널리 사용된다. Google, Meta, Uber 등 대형 테크 기업들이 주요 기술 결정을 RFC로 문서화한다.

RFC의 핵심 가치는 "말"이 아닌 "글"로 기술 결정을 내리는 것이다. 회의에서는 목소리 큰 사람이 이기지만, RFC에서는 논리가 이긴다.

다음은 실무에서 바로 사용할 수 있는 RFC 템플릿이다.

# RFC: [Title]

- **Author(s):** [Names]
- **Status:** Draft | In Review | Accepted | Rejected | Superseded
- **Created:** YYYY-MM-DD
- **Last Updated:** YYYY-MM-DD
- **Reviewers:** [Names]
- **Decision Deadline:** YYYY-MM-DD

## Summary

[2-3 sentences describing the proposal. A reader should understand
the core idea after reading only this section.]

## Motivation

[Why is this change necessary? What problem does it solve?
Include data, metrics, or user feedback that supports the need.]

### Current State

[Describe the current system/process and its limitations.]

### Desired State

[Describe the target state after implementing this proposal.]

## Detailed Design

### Architecture Overview

[High-level architecture diagram or description]

### API Changes

[Any new or modified API endpoints, schemas, or contracts]

### Data Model Changes

[Database schema changes, migration strategy]

### Implementation Plan

[Phased rollout plan with milestones]

| Phase | Scope | Timeline | Success Criteria |
| ----- | ----- | -------- | ---------------- |
| 1     |       |          |                  |
| 2     |       |          |                  |

## Alternatives Considered

### Alternative 1: [Name]

[Description, pros, cons, and why it was not chosen]

### Alternative 2: [Name]

[Description, pros, cons, and why it was not chosen]

## Risks and Mitigations

| Risk | Likelihood | Impact | Mitigation |
| ---- | ---------- | ------ | ---------- |
|      |            |        |            |

## Security Considerations

[Authentication, authorization, data privacy impacts]

## Backward Compatibility

[Breaking changes, migration path, deprecation timeline]

## Observability

[Logging, monitoring, alerting changes needed]

## Open Questions

- [ ] [Question 1]
- [ ] [Question 2]

## References

- [Link to related RFC, design doc, or external resource]

RFC 작성 핵심 규칙

1. Summary를 먼저 쓰고 나머지를 채운다

바쁜 시니어 엔지니어는 Summary만 읽고 리뷰할지 결정한다. Summary가 불명확하면 문서 전체가 무시된다. 다음 구조를 따른다.

Good Summary:
  This RFC proposes replacing our current Redis-based session store
  with a JWT-based stateless authentication system. This change
  reduces infrastructure costs by ~40% and eliminates the session
  store as a single point of failure.

Bad Summary:
  This document discusses authentication improvements.

2. Alternatives Considered는 필수다

대안을 고려하지 않은 RFC는 설득력이 없다. 최소 2가지 대안을 제시하고, 각각의 장단점을 명확히 기술한 뒤 현재 제안이 더 나은 이유를 설명한다.

3. 명확한 Decision Deadline을 설정한다

기한 없는 RFC는 영원히 리뷰되지 않는다. "Please review by March 15"처럼 구체적 날짜를 명시한다.

4. Open Questions로 논의를 유도한다

모든 것을 결정한 RFC보다, 의도적으로 열린 질문을 남긴 RFC가 더 좋은 피드백을 받는다.

README 작성법

README는 프로젝트의 첫인상이다. 오픈소스 프로젝트의 경우 README 품질이 곧 프로젝트의 신뢰도를 결정한다. 다음은 필수 섹션을 포함한 README 템플릿이다.

# Project Name

[![Build Status](https://img.shields.io/github/actions/workflow/status/org/repo/ci.yml)](link)
[![npm version](https://img.shields.io/npm/v/package-name)](link)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](link)

One-line description: what it does and who it's for.

## Features

- **Feature 1** - Brief description
- **Feature 2** - Brief description
- **Feature 3** - Brief description

## Quick Start

### Prerequisites

- Node.js >= 18.0
- PostgreSQL >= 15

### Installation

npm install package-name

### Basic Usage

import Client from 'package-name';

const client = new Client({ apiKey: process.env.API_KEY });
const result = await client.doSomething({ param: 'value' });
console.log(result);

## Documentation

- [Getting Started Guide](docs/getting-started.md)
- [API Reference](docs/api-reference.md)
- [Configuration](docs/configuration.md)
- [Migration Guide](docs/migration.md)

## Contributing

We welcome contributions. Please read our
[Contributing Guide](CONTRIBUTING.md) before submitting a PR.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing`)
5. Open a Pull Request

## License

This project is licensed under the MIT License.
See [LICENSE](LICENSE) for details.

README 작성에서 자주 하는 실수와 개선 방법을 정리한다.

  • Quick Start가 3단계를 넘긴다: 설치부터 첫 결과 확인까지 3단계 이내로 줄인다. 복잡한 설정은 별도 문서로 분리한다
  • Prerequisites를 빠뜨린다: 런타임 버전, OS 요구사항, 필수 환경변수를 명시하지 않으면 설치 실패 이슈가 쏟아진다
  • 뱃지(Badge)만 잔뜩 달고 내용은 빈약하다: 뱃지는 빌드 상태, 버전, 라이선스 3개면 충분하다
  • 스크린샷이 없다: UI가 있는 프로젝트라면 스크린샷이나 GIF를 반드시 포함한다

문체 가이드라인

능동태(Active Voice) 사용

Google, Microsoft, Apple의 스타일 가이드 모두 능동태를 기본으로 권장한다. 수동태는 문장을 길고 모호하게 만든다.

수동태 (Avoid)능동태 (Prefer)
The file is created by the systemThe system creates the file
The request should be sent by the clientThe client sends the request
Errors can be handled by using try-catchHandle errors with try-catch
The configuration must be updated before deploymentUpdate the configuration before deployment
It is recommended that TLS 1.3 be usedUse TLS 1.3

수동태가 적절한 예외 상황도 있다. 행위자가 중요하지 않거나 의도적으로 생략해야 할 때다.

Passive OK: "The data is encrypted at rest using AES-256."
(누가 암호화하는지보다 암호화 사실 자체가 중요)

Passive OK: "Deprecated endpoints will be removed in v3.0."
(누가 제거하는지보다 제거 사실이 중요)

간결성(Conciseness) 확보

불필요한 단어를 제거하면 문서의 정보 밀도가 올라간다.

장황한 표현간결한 표현
In order toTo
Due to the fact thatBecause
At the present timeNow / Currently
In the event thatIf
It is necessary toYou must / Must
For the purpose ofTo / For
A large number ofMany
Has the ability toCan
Prior toBefore
In addition toAlso

실전 교정 예시:

Before:
  In order to configure the database connection, it is necessary
  to set the DATABASE_URL environment variable prior to starting
  the application server.

After:
  Set the DATABASE_URL environment variable before starting the
  application server.

28단어가 14단어로 줄었다. 정보 손실은 없다.

일관성(Consistency) 유지

같은 개념을 여러 단어로 표현하면 독자가 혼란스러워한다.

Inconsistent:
  "Click the Submit button." ... "Press the Send button."
  ... "Tap the Confirm button."

Consistent:
  "Click Submit." ... "Click Send." ... "Click Confirm."

일관성을 유지하기 위한 규칙은 다음과 같다.

  • 용어집(Glossary)을 만든다: 프로젝트에서 사용하는 핵심 용어와 정의를 문서화한다
  • UI 요소 표기를 통일한다: "button", "btn", "버튼" 중 하나를 선택하고 전체 문서에서 동일하게 사용한다
  • 코드 표기 규칙을 정한다: 함수명은 code font로, 제품명은 일반 텍스트로 쓰는 식의 규칙을 정한다
  • American English vs British English를 결정한다: "color" vs "colour", "initialize" vs "initialise" 중 하나를 선택한다

자주 하는 실수와 교정 예시

한국어 사고방식에서 비롯되는 영어 기술 문서의 대표적인 실수를 정리한다.

1. 주어 생략

한국어는 주어를 자주 생략하지만, 영어 기술 문서에서는 주어를 반드시 명시해야 한다.

Bad:  "Can configure by editing the config file."
Good: "You can configure the service by editing the config file."

Bad:  "Must restart after changing settings."
Good: "Restart the server after changing settings."

단, 절차(Procedure) 설명에서는 명령문(imperative)을 사용하므로 주어 "You"를 생략한다. "Configure the database"는 올바른 명령문이다.

2. 관사(a, an, the) 오용

Bad:  "Send request to endpoint."
Good: "Send a request to the endpoint."

Bad:  "The each user has unique ID."
Good: "Each user has a unique ID."

Bad:  "Restart a server." (특정 서버를 가리킬 때)
Good: "Restart the server."

기본 규칙: 처음 언급하면 a/an, 이미 언급했거나 유일한 것이면 the, 일반적 개념이면 무관사(복수형).

3. 불필요한 "please" 사용

기술 문서는 대화가 아니다. 절차 설명에서 "please"는 불필요한 노이즈다.

Bad:  "Please click the Save button."
Good: "Click Save."

Bad:  "Please note that this feature requires admin access."
Good: "This feature requires admin access."

4. 동사-명사 혼동

Bad:  "Do the setup of the environment."
Good: "Set up the environment."

Bad:  "Perform the deletion of old records."
Good: "Delete old records."

Bad:  "Make a configuration change."
Good: "Change the configuration."

동사로 직접 표현할 수 있는 것을 명사화(nominalization)하면 문장이 길어지고 약해진다.

5. 모호한 대명사

Bad:  "The client sends a request to the server. It processes
       the data and returns a response. It then parses the JSON."
       (It이 client인지 server인지 불명확)

Good: "The client sends a request to the server. The server
       processes the data and returns a response. The client
       then parses the JSON."

Changelog 작성 규칙

Changelog는 API 소비자에게 "무엇이 바뀌었는지"를 알리는 문서다. Keep a Changelog(keepachangelog.com) 형식을 따르는 것이 표준이다.

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/),
and this project adheres to [Semantic Versioning](https://semver.org/).

## [2.1.0] - 2026-03-01

### Added

- `GET /users` endpoint now supports `status` query parameter
  for filtering by account status (#234)
- Rate limit headers (`X-Rate-Limit-Remaining`) included in
  all responses (#241)

### Changed

- Default pagination size changed from 50 to 20 for improved
  response times (#238)
- Error response format unified across all endpoints to use
  the standard error schema (#240)

### Deprecated

- `GET /users/search` endpoint. Use `GET /users` with query
  parameters instead. Will be removed in v3.0. (#235)

### Fixed

- Fixed race condition in concurrent user updates that could
  cause data loss (#237)
- Corrected OpenAPI spec for `PATCH /users` to include
  `display_name` field (#239)

## [2.0.0] - 2026-02-15

### Removed

- Removed `GET /users/list` endpoint (deprecated since v1.5)
- Dropped support for API key authentication. Use Bearer
  tokens instead.

### Changed

- **BREAKING:** User ID format changed from integer to UUID

Changelog에서 지켜야 할 핵심 규칙을 정리한다.

  • Added/Changed/Deprecated/Removed/Fixed/Security 카테고리를 사용한다
  • 이슈/PR 번호를 링크한다: 변경의 맥락을 추적할 수 있게 한다
  • BREAKING 변경은 굵게 표시한다: 소비자가 즉시 인지할 수 있어야 한다
  • 날짜 형식은 ISO 8601(YYYY-MM-DD)을 사용한다
  • "Unreleased" 섹션을 유지한다: 다음 릴리스에 포함될 변경사항을 미리 볼 수 있게 한다

리뷰 체크리스트

기술 문서를 작성한 후, 다음 체크리스트로 셀프 리뷰를 수행한다.

구조 (Structure)

  • Diataxis 유형(Tutorial/How-to/Reference/Explanation) 중 이 문서의 목적이 명확한가
  • 목차(Table of Contents)가 있고, 섹션 제목만으로 내용을 파악할 수 있는가
  • 가장 중요한 정보가 문서 상단에 위치하는가 (Inverted Pyramid)
  • 각 섹션이 하나의 주제만 다루는가

문체 (Style)

  • 능동태를 기본으로 사용했는가
  • 문장 길이가 26단어를 넘지 않는가
  • "In order to", "Due to the fact that" 같은 장황한 표현을 제거했는가
  • 용어가 문서 전체에서 일관적인가
  • "please", "kindly", "just" 같은 불필요한 단어를 제거했는가

코드 및 기술 정보 (Technical Accuracy)

  • 모든 코드 예시가 실제로 동작하는가
  • API 엔드포인트의 HTTP 메서드, 경로, 파라미터가 정확한가
  • 에러 코드와 응답 형식이 실제 구현과 일치하는가
  • 버전 정보가 최신인가

독자 관점 (Reader Experience)

  • 사전 지식 없이 이 문서를 이해할 수 있는가
  • 약어(acronym)를 처음 사용할 때 풀어서 설명했는가
  • 외부 링크가 유효한가
  • 스크린샷이 최신 UI를 반영하는가

접근성 (Accessibility)

  • 이미지에 alt text가 있는가
  • 색상만으로 정보를 전달하지 않는가
  • 표에 헤더가 있는가
  • 코드 블록에 언어 태그가 있는가

도구 추천

작성 도구

도구용도특징
Vale스타일 린팅Google/Microsoft 스타일 가이드 규칙을 자동 검사. CI/CD 파이프라인에 통합 가능
Grammarly문법/스타일 검사브라우저 확장, IDE 플러그인 지원. Technical writing 톤 설정 가능
Hemingway Editor가독성 검사수동태, 복잡한 문장, 부사 과다 사용을 시각적으로 표시
LanguageTool문법 검사오픈소스 대안. 셀프 호스팅 가능
write-good스타일 린팅npm 패키지. CLI에서 마크다운 파일 검사. weasel words, passive voice 탐지

문서 생성 도구

도구입력출력특징
DocusaurusMDX정적 사이트React 기반, 버전 관리, 검색 내장
MkDocs (Material)Markdown정적 사이트Python 기반, 깔끔한 디자인
NextraMDXNext.js 사이트Next.js 프로젝트에 자연스럽게 통합
Astro StarlightMDX정적 사이트빠른 빌드, 다국어 지원, 접근성 우선
SphinxreStructuredText다양Python 생태계 표준, 크로스 레퍼런싱 강력

CI/CD 통합 파이프라인

문서 품질을 자동으로 검증하는 파이프라인 구성 예시다.

# .github/workflows/docs-lint.yml
name: Documentation Lint

on:
  pull_request:
    paths:
      - 'docs/**'
      - '*.md'
      - 'openapi/**'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Lint prose with Vale
        uses: errata-ai/vale-action@v2
        with:
          files: docs/
          config: .vale.ini

      - name: Validate OpenAPI spec
        run: |
          npx @redocly/cli lint openapi/spec.yaml

      - name: Check for broken links
        uses: lycheeverse/lychee-action@v2
        with:
          args: --verbose docs/

      - name: Spell check
        uses: streetsidesoftware/cspell-action@v6
        with:
          files: 'docs/**/*.md'

이 파이프라인은 PR이 docs 디렉토리나 마크다운 파일을 수정할 때 자동 실행된다. Vale이 스타일 규칙을 검사하고, Redocly CLI가 OpenAPI 스펙의 유효성을 검증하며, lychee가 깨진 링크를 찾고, cspell이 오타를 검출한다.

실전 적용 로드맵

테크니컬 라이팅 역량을 단계적으로 쌓기 위한 로드맵을 제안한다.

1주차 - 기초 확립

  • Google Developer Documentation Style Guide 전체 읽기 (2-3시간)
  • 기존 프로젝트 README를 이 글의 템플릿 기준으로 개선하기

2주차 - API 문서화

  • 팀의 API 하나를 골라 OpenAPI 3.1 스펙으로 작성하기
  • Redoc으로 문서를 렌더링하고 팀에 공유하기

3주차 - RFC 연습

  • 최근 기술 의사결정 하나를 RFC 형식으로 문서화하기
  • 팀원에게 리뷰를 요청하고 피드백을 반영하기

4주차 - 자동화 구축

  • Vale 설치 및 팀 스타일 규칙 설정
  • CI 파이프라인에 문서 린팅 단계 추가

이 과정을 거치면 "영어를 잘 쓰는 것"이 아니라 "좋은 기술 문서를 쓰는 것"에 집중할 수 있게 된다. 기술 문서의 품질은 영어 실력보다 구조적 사고와 독자 관점의 이해에서 결정된다.

참고자료