+++
date = '2025-03-12'
draft = false
title = 'Temporal, Restate, Hatchet, Inngest オープンソースプロジェクト比較分析'
+++
今日、分散システムの開発を簡素化し、耐障害性のあるワークフロー管理のためのさまざまなオープンソースソリューションが存在します。この報告書では、Temporal、Restate、Hatchet、Inngestという4つの主要なオープンソースプロジェクトを深く比較分析します。
## 概要と核心概念
### Temporal
Temporalは耐障害性のある実行プラットフォームで、分散システムの構築の複雑さを抽象化するオープンソースソリューションです。ホストやソフトウェアの障害が発生しても、完全なアプリケーションの状態を保持し、他のマシンへの実行をスムーズにマイグレーションします[^1_1]。Temporalは、タイマー、イベントソーシング、状態チェックポイント、再試行、タイムアウトのためのカスタムコード作成の必要性を排除し、開発の加速を支援します[^1_3]。
Temporalは、Stripe、Netflix、Datadog、HashiCorp、Alaska Airlines、Boxなど数千社が、ミッションクリティカルなワークロードと基本的なワークロードの両方に利用しています。Twilioのすべてのメッセージ、Coinbaseのすべてのトランザクション、SnapのすべてのストーリーがTemporalを使用しているとされています[^1_1]。
### Restate
Restateは耐障害性のある実行エンジンで、状態を持つサーバーレスアプリケーションを構築するためのオープンソースプロジェクトです。一般的なRPCサービスのように見えるコードを書くことで、エンジンが実行の進行状況を保存し、クラッシュ後には以前の状態に復元して中断した地点から実行を再開します[^1_8]。
また、Restateは長い待機時間や他のサービスからの応答の遅延といった状況において、自動的に実行を一時停止して計算リソースを無駄にしません。これは「待機時間」の間にKnativeサービスがゼロスケーリングできることを意味します[^1_8]。
### Hatchet
Hatchetは分散型の耐障害性のあるタスクキューで、同時実行性、公正性、レート制限といったスケーラビリティの問題を解決するために設計されています[^1_14]。管理が難しいレガシーキューやpub/subシステムに代わって、失敗から回復し、さまざまなスケーラビリティの問題を解決する耐障害性のあるワークロードを設計できます[^1_15]。
Hatchetは、超低遅延(平均開始時間25ms)と高スループットのスケジューリングを提供し、FIFO、LIFO、ラウンドロビン、プライオリティキューといった戦略を内蔵しており、最小限の設定で一般的なスケーラビリティの問題を回避できます[^1_17]。
### Inngest
Inngestはすべてのクラウドで作動するオープンソースの耐障害性ワークフロープラットフォームです。失敗時には自動的に再試行される状態保持、長期実行ステップ関数をコードで記述できるようにします[^1_21]。キュー、イベントストリーム、状態に関するすべてを抽象化して、コードに集中できるようにします。
Inngestは、2021年にBufferの元CTOであるDan FarrellyとDockerの元エンジニアであるTony Holdstock-Brownによって設立され、2023年にGGVを先頭に300万ドルのシード投資を受けました[^1_20]。
## 技術的特徴の比較
### アーキテクチャと技術スタック
TemporalはGo言語で書かれたgRPCライブラリを使用し、完全なアプリケーション状態を保持する開発の抽象化を提供します[^1_7]。ワーカーパターンを使って実行し、クライアントはワークフローファンクションを実行しますが、実際にはワーカーのワークフローを実行する構造です[^1_7]。
RestateはHTTP/2サーバーを通じてサービスを公開し、Knativeと連携してサーバーレスアプリケーションをデプロイできます[^1_8]。Restateは単一バイナリで提供され、実行と運用が簡単であり、Rustで開発されているため資源効率が良く、高い耐久性を持ちます[^1_10]。
HatchetはPostgresを基盤としたトランザクションキューとDAGスタイルの実行をサポートします。`SKIP LOCKED`と最近のPGリリースのマイルストーン(アクティブ-アクティブレプリケーションなど)を活用して、複数の地域にわたってPostgresを水平スケールし、10k TPS以上の垂直スケールを実現できるとしています[^1_19]。
Inngestはマルチテナント、バッチ、デバウンスをサポートする独自のキューシステムを設計し、FoundationDBへの移行中です。バックエンドは主にGoで書かれており、キャッシング、Clickhouse、イベントストリーム及びオーケストレーションを使用します[^1_21]。
### サポートしている言語
各プロジェクトがサポートするプログラミング言語は以下の通りです:
- Temporal: 検索結果には明確には記載されていませんが、Goが主要言語であるようです。
- Restate: Golang、Java、Kotlin、TypeScript、Rust、Pythonをサポートします[^1_8]。
- Hatchet: Python、TypeScript、Go用のオープンソースSDKを提供します[^1_15]。
- Inngest: TypeScript(47%)、Go(48%)、Java、Python SDKを提供し、クロスランゲージファンクションコールが可能です[^1_21][^1_23]。
### 機能の比較
**Temporal**:
- 完全なアプリケーション状態保持および別のマシンへのマイグレーション[^1_1]
- タイマー、イベントソーシング、状態チェックポイント、再試行、タイムアウトの自動処理[^1_3]
- キュー、pub/subシステム、スケジューラの必要性を排除[^1_1]
**Restate**:
- RPCサービススタイルのコードに耐障害性を提供[^1_8]
- クラッシュ後に以前の状態を復元し、中断点から実行を再開[^1_8]
- 待機時間が長い場合、自動的に実行を一時停止してリソースを節約[^1_8]
- 状態マシン、イベント処理、サガ、非同期タスクなどの実装が可能[^1_9]
**Hatchet**:
- 超低遅延(平均開始時間25ms)および高スループットのスケジューリング[^1_17]
- FIFO、LIFO、ラウンドロビン、プライオリティキューといった内蔵戦略[^1_14]
- カスタム再試行ポリシーと統合エラーハンドリング[^1_14]
- Cron、一時的なスケジューリング、スパイク保護、段階的ストリーミングのサポート[^1_14]
**Inngest**:
- マルチテナント認識フロー制御(同時性、スロットリング、デバウンス、優先順位)[^1_24]
- 複数言語間の関数呼び出しをサポート[^1_21]
- バッチ処理、多くのイベントを単一の関数呼び出しでグループ化[^1_21]
- 改善されたダッシュボード、トラッキングおよびメトリクスが組み込まれている[^1_21]
- 関数の再生、一時停止、大量キャンセルといった高度な回復ツール[^1_21]
## 使用例と応用分野
### Temporal
Temporalはサービスオーケストレーション、トランザクション処理、インフラ管理、非同期タスク、タスクスケジューリングに適しています[^1_1]。特にStripe、Netflix、Datadog、HashiCorp、Alaska Airlines、Boxなどの大手企業でミッションクリティカルなワークロードに利用されています[^1_1]。
### Restate
Restateはワークフロー、イベント中心のアプリケーション、サガパターンの実装、状態を持つイベント処理に適しています[^1_8]。Knativeとともに使用することで、可用性が不足する状況でも状態を保持したサーバーレスアプリケーションを構築できます。また、ワークフロー、サガ、状態を持つイベント処理(Knative Eventingと組み合わせる)など、さまざまなアプリケーションを構築できます[^1_8]。
### Hatchet
Hatchetは生成的AIのための公正性(忙しいユーザーがシステムを圧倒しないようにリクエストを公正に分配)、文書および画像インデクシングのためのバッチ処理、マルチモーダルシステムのためのワークフローオーケストレーション、イベントベースの処理のための正確性といった使用例に適しています[^1_14]。
### Inngest
InngestはAIエージェントのワークフロー、生成的AIのための公正性、文書インデクシングのためのバッチ処理、マルチモーダルシステムのためのワークフローオーケストレーションといった使用例に適しています[^1_24]。また、AI関連のチェーンステップ関数、検索/RAGインデックスおよびデータパイプライン、統合およびWebhook、決済および請求フローといった使用例もサポートします[^1_21]。
## 長所と短所の分析
### Temporal
**長所**:
- 数千社で検証された安定したプラットフォーム[^1_1]
- 完全なアプリケーション状態保持による高信頼性[^1_1]
- MITライセンス下で提供される100%オープンソースソリューション[^1_1]
**短所**:
- 分析によれば、Go、Rust、TypeScriptをまたいで動作を分析するのが難しい可能性がある[^1_7]
- 内部構造が複雑であり、プロトコルレベルでのデータ送信/受信情報に基づいて分析するのが難しい[^1_7]
### Restate
**長所**:
- 単一バイナリで提供され、実行と運用が簡単[^1_10]
- 資源効率が良く、高い復元力を持つ(Rust使用)[^1_10]
- サーバーレス/ステートレスHTTPサーバーとしてデプロイ可能[^1_8]
**短所**:
- 比較的新しいプロジェクトであり、Temporalに比べてエコシステムが小さい可能性がある
- デプロイ戦略が複雑になる場合がある(k8sクラスターへのステートフルデプロイまたはRestate Cloud管理サービスの使用)[^1_8]
### Hatchet
**長所**:
- Postgresを基盤としており、データ損失リスクを減少させる(Redisベースのソリューションと比較)[^1_19]
- 超低遅延(平均開始時間25ms)および高スループットのスケジューリングを提供[^1_17]
- アプリケーション開発者向けの観察可能性機能が組み込まれている[^1_19]
**短所**:
- 現在RabbitMQをpub/subとして使用しているため追加の依存関係が必要[^1_19]
- エンジン-エンジンおよびエンジン-ワーカー接続にNATSの使用を検討中であり、まだ開発中の部分がある[^1_19]
### Inngest
**長所**:
- 開発者に優しいSDKとシンプルなAPI設計[^1_21]
- ローカル開発のためのDev Serverを提供し、テストとデバッグが容易[^1_24]
- マルチテナント認識フロー制御機能を提供[^1_24]
**短所**:
- SSPLライセンスは一部の企業での使用が難しい可能性がある[^1_22]
- Go(48%)とTypeScript(47%)が主要言語であり、他の言語サポートが制限される可能性がある[^1_23]
## ライセンスとコミュニティ
TemporalはMITライセンスで提供されており、活発なコミュニティとともにオープンソースで開発されています[^1_1]。Restateのライセンスは検索結果に明確には記載されていません。HatchetはMITライセンスで提供されています[^1_15]。InngestはServer Side Public License(SSPL)に基づいており、遅延オープンソース出版(DOSP)の下でApache 2.0ライセンスも含まれています[^1_21]。
## 結論
四つのオープンソースプロジェクトはすべて耐障害性のある実行とワークフロー管理のソリューションを提供しますが、それぞれ独特のアプローチと強みを持っています。
Temporalは最も成熟した広く採用されているソリューションで、ミッションクリティカルなワークロードに適しています。Restateは状態を持つサーバーレスアプリケーションに重点を置いており、リソース効率に優れています。HatchetはPostgresベースのタスクキューを使用し、データ損失リスクを減少させ、開発者に優しい観察可能性を提供します。Inngestは開発者体験に重点を置き、マルチテナント認識のフロー制御を備えたすべてのクラウドで作動するワークフロープラットフォームを提供します。
プロジェクトの選択は特定の要求、既存の技術スタック、チームの専門性に応じて変わることがあります。しかし、この四つのソリューションはすべて分散システムの複雑さを抽象化し、開発者がビジネスロジックに集中できるようにする共通の目標を持っています。
## 参考資料
上記の内容はTemporal[^1_1][^1_2][^1_3][^1_4][^1_5][^1_7]、Restate[^1_8][^1_9][^1_10][^1_11][^1_12][^1_13]、Hatchet[^1_14][^1_15][^1_16][^1_17][^1_18][^1_19]、Inngest[^1_20][^1_21][^1_22][^1_23][^1_24][^1_25][^1_26][^1_27]に関する公開された情報に基づいて作成されました。
<div style="text-align: center"></div>
[^1_1]: https://github.com/temporalio
[^1_2]: https://www.opensourcealternative.to/project/temporal
[^1_3]: https://temporal.io
[^1_4]: https://web.temporal.io
[^1_5]: https://aws.amazon.com/startups/offers/temporal?lang=ja
[^1_6]: https://news.hada.io/topic?id=12005
[^1_7]: https://swcho.github.io/blogs/2023-12-25-temporal-2
[^1_8]: https://knative.dev/blog/articles/Building-Stateful-applications-with-Knative-and-Restate/
[^1_9]: https://github.com/restatedev/restate
[^1_10]: https://restate.dev
[^1_11]: https://docs.restate.dev
[^1_12]: https://www.contributor.fyi/restate
[^1_13]: https://github.com/restatedev
[^1_14]: https://news.hada.io/topic?id=13722
[^1_15]: https://github.com/hatchet-dev/hatchet
[^1_16]: https://docs.hatchet.run/home
[^1_17]: https://hatchet.run
[^1_18]: https://openalternative.co/hatchet
[^1_19]: https://news.ycombinator.com/item?id=39643136
[^1_20]: https://appmaster.io/ja/news/inggestneun-300man-jageum-jiweon-baegendeu-weokeupeulrou-gaebaleul-mogeumhabnida
[^1_21]: https://news.ycombinator.com/item?id=41604042
[^1_22]: https://news.ycombinator.com/item?id=31910762
[^1_23]: https://openalternative.co/inngest
[^1_24]: https://www.inngest.com
[^1_25]: https://www.inngest.com/blog/open-source-event-driven-queue
[^1_26]: https://github.com/inngest
[^1_27]: https://github.com/inngest/inngest
[^1_28]: https://github.com/temporalio/temporal
[^1_29]: https://lilys.ai/notes/737647
[^1_30]: https://news.ycombinator.com/item?id=42821705
[^1_31]: https://x.com/restatedev/status/1800893174313054431
[^1_32]: https://techcrunch.com/2024/06/12/restate-raises-7m-for-its-lightweight-workflows-as-code-platform/
[^1_33]: https://www.linkedin.com/posts/fredericlardinois_restate-raises-7m-for-its-lightweight-workflows-as-code-activity-7206639427824066560-qYwf
[^1_34]: https://oneoneone.kr/content/14e64599
[^1_35]: https://github.com/hatchet-dev
[^1_36]: https://www.odoo.com/ja_KR/customers/hatchet-outdoor-supply-co-7498416
---
# RestateとHatchetオープンソースプロジェクトの深掘り比較分析
RestateとHatchetはともに分散システムでの耐障害性のあるワークロードを処理するためのオープンソースソリューションですが、それぞれのアプローチと重視する領域が異なります。この報告書では2つのプロジェクトの核心概念、アーキテクチャ、機能、使用例などを比較し、それぞれのソリューションの長所と短所を分析します。
## 核心概念と目的
### Restateのアプローチ
Restateは耐障害性のある実行エンジンで、状態を持つ回復力のあるアプリケーションを構築することに重点を置いています。一般的なRPCサービスのように見えるコードを書くことで、Restateが実行の進行状況を保存し、障害が発生した後も以前の状態に復元し、中断した地点から実行を再開します[^2_2]。
Restateは「コードを書くスタイルを変えることなく耐障害性を提供する」という哲学を持ち、開発者が一般的な関数やサービスを記述するようにコードを書くことを可能にします[^2_2]。これは複雑な分散システムの開発負担を大幅に軽減します。
### Hatchetのアプローチ
一方、Hatchetは分散型の耐障害性のあるタスクキューで、管理が難しいレガシーキューやpub/subシステムに代わって、失敗から回復するワークロードを設計することに重点を置いています[^2_3]。特に同時実行性、公正性、レート制限といったスケーラビリティの問題を解決するために設計されています[^2_3]。
Hatchetは最小限の設定で作業を複数のワーカーに分散させ、失敗時に安定して回復することを目指しています。また、アプリケーション開発者向けの可視性と観察可能性を重視しています[^2_7]。
## 技術的特徴とアーキテクチャ
### Restateの技術的特徴
Restateは次のような主要な技術的特徴を持っています:
HTTP/2サーバーを通じてサービスを公開し、単一バイナリで提供されるため実行と運用が簡単です[^2_2]。Rustで開発されており、資源効率が良く高い復元力を持ち、FaaS、Kubernetes、サーバー、コンテナといった多様な環境で動作します[^2_2]。
また、Restateは長い待機時間の際に実行を自動的に一時停止し、計算リソースを無駄にしません。これは「待機時間」の間にリソースを効率的に活用できることを意味します[^2_2]。
### Hatchetの技術的特徴
Hatchetは以下のような主要な技術的特徴を持っています:
Postgresを基盤としたトランザクションキューとDAG(有向非巡回グラフ)スタイルの実行をサポートします[^2_3]。`SKIP LOCKED`と最近のPostgreSQLリリースの主要機能を活用して、複数の地域にわたる水平スケーリングと10k TPS以上の垂直スケーリングを実現できるとしています[^2_3]。
超低遅延(平均開始時間25ms)および高スループットスケジューリングを提供し、FIFO(先入れ先出し)、LIFO(後入れ先出し)、ラウンドロビン、プライオリティキューといった戦略を内蔵しており、一般的なスケーラビリティの問題を最小限の設定で解決できます[^2_7]。
## 主要機能比較
### Restateの主要機能
Restateは次のような主要機能を提供します:
ワークフローコード: 耐障害性のある実行により、障害が発生してもコードが最後まで安定的に実行されます[^2_2]。
API呼び出しとWebhook: 同期コードとWebhookといった非同期イベントを安定的に接続します[^2_2]。
非同期タスク: Restateを通じて呼び出されたすべての関数は耐障害性を持ち、非同期に実行されます[^2_2]。
状態保持イベント処理: Kafkaのようなイベントソースからイベントを処理し、細分化された再試行とワークフローセマンティクスを提供します[^2_2]。
耐障害性のあるシグナル: 外部シグナル、イベント、ユーザー入力を安定して処理するワークフローとイベントハンドラーを生成します[^2_2]。
冪等性: すべてのRPCまたはイベントハンドラーに冪等性を追加します[^2_2]。
サガ: 中断し、ロールバックすべきときに前の操作をキャンセルする長期実行トランザクションであるサガとその補償パターンを実装します[^2_2]。
状態マシン: データベースやトランザクションを使用せずに一貫性があり、スケーラブルな状態マシンを生成します[^2_2]。
### Hatchetの主要機能
Hatchetは次のような主要機能を提供します:
可視性: すべての実行を完全に検索可能であり、ログをストリーミングし、遅延時間、エラーレートまたはユーザー定義メトリックを追跡します[^2_7]。
実用的な耐障害性実行: イベントを再生し、ワークフローの特定の段階で手動で実行を再開できます[^2_7]。
Cron: 関数実行のための繰り返しスケジュールを設定します[^2_7]。
一時的スケジューリング: 特定の時間と日付に実行されるよう関数実行を予約します[^2_7]。
スパイク保護: トラフィックスパイクをスムーズに処理し、システムが処理できる量だけを実行します[^2_7]。
段階的ストリーミング: バックグラウンドワーカーで関数が進行するにつれて更新を購読します[^2_7]。
カスタム再試行ポリシーと統合エラーハンドリング: 一時的な失敗から迅速に回復します[^2_3]。
## 使用例と適用分野
### Restateの使用例
Restateは次のような使用例に特に適しています:
ワークフローおよび長期実行プロセス: 耐障害性のある実行により、複雑なワークフローや長期実行プロセスを安定的に管理できます[^2_2]。
イベント中心のアプリケーション: Kafkaのようなイベントソースからイベントを処理し、状態を保持したまま処理できます[^2_2]。
サガパターンの実装: 長期実行のトランザクションや補償パターンを導入し、ロールバックが必要な場合に前の操作をキャンセルできます[^2_2]。
状態マシン: データベースやトランザクションなしで一貫性があり且つスケーラブルな状態マシンを生成できます[^2_2]。
### Hatchetの使用例
Hatchetは次のような使用例に特に適しています:
生成型AIのための公正性: 忙しいユーザーがシステムを圧倒しないようにリクエストを公正に分配します[^2_3]。
文書および画像インデクシングのためのバッチ処理: 大規模バッチ処理を行い、失敗時には作業の途中から再開できます[^2_3]。
マルチモーダルシステムのためのワークフローオーケストレーション: マルチモーダル入力と出力をオーケストレーションし、DAGスタイルの実行を支援します[^2_3]。
イベントベースの処理のための正確性: 外部イベントまたはシステム内部のイベントに反応し、自動的にイベントを再生できます[^2_3]。
## スケーラビリティと性能
### Restateのスケーラビリティと性能
Restateは単一バイナリで提供され、実行と運用が簡単で、Rustで開発されているため、資源効率が良く復元力が高いです[^2_2]。さらに、Restate 1.2バージョンからは高可用性、分散デプロイの機能を追加し、スケーラビリティを強化しました[^2_2]。
Restateは長い待機時間の場合に実行を自動的に一時停止し、計算リソースを効率的に利用し、FaaS、Kubernetes、サーバー、コンテナなどのさまざまな環境で柔軟に動作します[^2_2]。
### Hatchetのスケーラビリティと性能
Hatchetは超低遅延(平均開始時間25ms)および高スループットのスケジューリングを提供し、リアルタイムのインタラクション機能とミッションクリティカルなタスクに必要な安定性を完璧にバランスさせます[^2_7]。
Postgresを基盤にしたトランザクションキューシステムを利用し、`SKIP LOCKED`と最近のPostgreSQLリリースの主要機能を活かして、複数の地域にわたる水平スケーリングと10k TPS以上の垂直スケーリングを実現できるとしています[^2_3]。
## 開発者体験とサポート環境
### Restateの開発者体験
Restateは一般的な関数やサービスのようにコードが書けるようにし、開発者が分散システムの複雑さを心配する必要をなくします[^2_2]。また、RestateはGolang、Java、Kotlin、TypeScript、Rust、Pythonなど、さまざまな言語をサポートします[^2_2]。
Restate 1.2バージョンからはグラフィックUIが提供され、分散アプリケーションのデバッグをサポートし、ローカル開発サーバーによって開発およびテスト環境を向上させます[^2_2]。
### Hatchetの開発者体験
HatchetはPython、TypeScript、Go向けのオープンソースSDKを提供し、開発者が適切なツールを使用して開発できるようサポートします[^2_3]。また、アプリケーション開発者向けに組み込まれた観察可能性機能によって、開発とデバッグの体験が向上します[^2_3]。
Hatchetはすべての実行が完全に検索可能で、問題を迅速に特定できるようにし、ログをストリーミングし、遅延時間、エラーレートまたはユーザー定義メトリックを追跡します[^2_7]。
## 総合比較と選定基準
RestateとHatchetはそれぞれ独自の強みと最適化された使用例を持っています。
### Restateに適した場合
コードを最小限に変更しながら耐障害性のある実行が必要な場合、サガパターンや状態マシンといった複雑な分散システムパターンを実装する必要がある場合、かつ資源効率と復元力が重要な場合は、Restateがより適している可能性があります。
### Hatchetに適した場合
タスクキューや公正なタスク配分が必要な場合、可視性とモニタリングが重要な場合、生成型AIなどの最新の使用例に最適化されたソリューションが必要な場合、そしてPostgresを基盤とした安定したトランザクションキューシステムを望む場合は、Hatchetがより適している可能性があります。
## 結論
RestateとHatchetは共に分散システムにおける耐障害性のあるワークロード処理のための強力なオープンソースソリューションです。Restateは耐障害性のある実行とさまざまな分散システムパターンの実装に重きを置く一方、Hatchetはタスクキュー、公正なタスク配分、可視性に重きを置いています。
各プロジェクトは固有の強みと最適化された使用例を持っていますので、プロジェクトの要件、既存のインフラ、開発チームの専門性などを考慮して適切なソリューションを選択することが重要です。両方のソリューションは、それぞれ分散システム開発の複雑さを抽象化し、開発者がコアビジネスロジックに集中できるように助ける共通の目標を持っています。
<div style="text-align: center"></div>
[^2_1]: https://blog.naver.com/haha266/220423107892?viewType=pc
[^2_2]: https://restate.dev
[^2_3]: https://github.com/hatchet-dev/hatchet
[^2_4]: https://redkiwiapp.com/ko/english-guide/synonyms/ax-hatchet
[^2_5]: http://tomasterenglish.blogspot.com/2009/
[^2_6]: https://www.redhat.com/ko/topics/open-source/what-is-open-source
[^2_7]: https://hatchet.run
[^2_8]: https://redkiwiapp.com/ko/english-guide/synonyms/hache-hatchet/details
[^2_9]: https://www.elancer.co.kr/blog/detail/191
[^2_10]: https://opensea.io/kr/assets/matic/0x2953399124f0cbb46d2cbacd8a89cf0599974963/39548590783365893747111059265928015194837162577353334555869211182704134979604
[^2_11]: https://scienceon.kisti.re.kr/srch/selectPORSrchArticle.do?cn=NART49925491
[^2_12]: https://www.hpe.com/kr/ko/what-is/open-source.html
[^2_13]: https://ita9naiwa.github.io/일기/2020/10/02/how-to-do-github.html
[^2_14]: https://epdf.pub/websters-korean-to-english-crossword-puzzles-level-6.html
[^2_15]: https://blog.naver.com/brickbot/220440698612?viewType=pc
[^2_16]: https://www.youtube.com/watch?v=VnD0e1dJ-T0
[^2_17]: https://wikidocs.net/250639
[^2_18]: https://www.cio.com/article/3538379/칼럼-소형-언어-모델과-오픈소스가-ai를-혁신하는-방법.html
[^2_19]: https://tech.kakaoenterprise.com/191
·435 文字·3 分