| <div align="center"> |
|
|
| # ๐ป Kiro Gateway |
|
|
| **Kiro API (Amazon Q Developer / AWS CodeWhisperer) ํ๋ก์ ๊ฒ์ดํธ์จ์ด** |
|
|
| [๐ฌ๐ง English](../../README.md) โข [๐ท๐บ ะ ัััะบะธะน](../ru/README.md) โข [๐จ๐ณ ไธญๆ](../zh/README.md) โข [๐ช๐ธ Espaรฑol](../es/README.md) โข [๐ฎ๐ฉ Indonesia](../id/README.md) โข [๐ง๐ท Portuguรชs](../pt/README.md) โข [๐ฏ๐ต ๆฅๆฌ่ช](../ja/README.md) |
|
|
| [@Jwadow](https://github.com/jwadow)๊ฐ โค๏ธ๋ฅผ ๋ด์ ์ ์ |
|
|
| [](https://www.gnu.org/licenses/agpl-3.0) |
| [](https://www.python.org/downloads/) |
| [](https://fastapi.tiangolo.com/) |
| [](#-ํ๋ก์ ํธ-ํ์) |
|
|
| *Kiro์ Claude ๋ชจ๋ธ์ Claude Code, OpenCode, Cursor, Cline, Roo Code, Kilo Code, Obsidian, OpenAI SDK, LangChain, Continue ๋ฐ ๊ธฐํ OpenAI ๋๋ Anthropic ํธํ ๋๊ตฌ์ ํจ๊ป ์ฌ์ฉ* |
|
|
| [๋ชจ๋ธ](#-์ง์-๋ชจ๋ธ) โข [๊ธฐ๋ฅ](#-๊ธฐ๋ฅ) โข [๋น ๋ฅธ-์์](#-๋น ๋ฅธ-์์) โข [์ค์ ](#%EF%B8%8F-์ค์ ) โข [๐ ํ์](#-ํ๋ก์ ํธ-ํ์) |
|
|
| </div> |
|
|
| --- |
|
|
| ## ๐ค ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ |
|
|
| > โ ๏ธ **์ค์:** ๋ชจ๋ธ ๊ฐ์ฉ์ฑ์ Kiro ํ๋(๋ฌด๋ฃ/์ ๋ฃ)์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. ๊ฒ์ดํธ์จ์ด๋ ๊ตฌ๋
์ ๋ฐ๋ผ IDE ๋๋ CLI์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ์ ๋ํ ์ก์ธ์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ์๋ ๋ชฉ๋ก์ **๋ฌด๋ฃ ํ๋**์์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ์ ๋ณด์ฌ์ค๋๋ค. |
|
|
| > ๐ **Claude Opus 4.5**๋ 2026๋
1์ 17์ผ์ ๋ฌด๋ฃ ํ๋์์ ์ ๊ฑฐ๋์์ต๋๋ค. ์ ๋ฃ ํ๋์์ ์ฌ์ฉ ๊ฐ๋ฅํ ์ ์์ต๋๋ค โ IDE/CLI์ ๋ชจ๋ธ ๋ชฉ๋ก์ ํ์ธํ์ธ์. |
|
|
| ๐ **Claude Sonnet 4.5** โ ๊ท ํ ์กํ ์ฑ๋ฅ. ์ฝ๋ฉ, ๊ธ์ฐ๊ธฐ, ๋ฒ์ฉ ์์
์ ์ ํฉ. |
|
|
| โก **Claude Haiku 4.5** โ ๋ฒ๊ฐ์ฒ๋ผ ๋น ๋ฆ. ๋น ๋ฅธ ์๋ต, ๊ฐ๋จํ ์์
, ์ฑํ
์ ์๋ฒฝ. |
|
|
| ๐ฆ **Claude Sonnet 4** โ ์ด์ ์ธ๋. ๋๋ถ๋ถ์ ์ฌ์ฉ ์ฌ๋ก์์ ์ฌ์ ํ ๊ฐ๋ ฅํ๊ณ ์ ๋ขฐํ ์ ์์. |
|
|
| ๐ฆ **Claude 3.7 Sonnet** โ ๋ ๊ฑฐ์ ๋ชจ๋ธ. ํ์ ํธํ์ฑ์ ์ํด ์ ๊ณต. |
|
|
| > ๐ก **์ค๋งํธ ๋ชจ๋ธ ํด์:** ์ด๋ค ๋ชจ๋ธ ์ด๋ฆ ํ์์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ โ `claude-sonnet-4-5`, `claude-sonnet-4.5`, ๋๋ `claude-sonnet-4-5-20250929`์ ๊ฐ์ ๋ฒ์ ์ด๋ฆ๋. ๊ฒ์ดํธ์จ์ด๊ฐ ์๋์ผ๋ก ์ ๊ทํํฉ๋๋ค. |
|
|
| --- |
|
|
| ## โจ ๊ธฐ๋ฅ |
|
|
| | ๊ธฐ๋ฅ | ์ค๋ช
| |
| |------|------| |
| | ๐ **OpenAI ํธํ API** | OpenAI ํธํ ๋๊ตฌ์ ํจ๊ป ์๋ | |
| | ๐ **Anthropic ํธํ API** | ๋ค์ดํฐ๋ธ `/v1/messages` ์๋ํฌ์ธํธ | |
| | ๐ **VPN/ํ๋ก์ ์ง์** | ์ ํ๋ ๋คํธ์ํฌ์ฉ HTTP/SOCKS5 ํ๋ก์ | |
| | ๐ง **ํ์ฅ ์ฌ๊ณ ** | ์ถ๋ก ๊ธฐ๋ฅ์ ์ฐ๋ฆฌ ํ๋ก์ ํธ๋ง์ ๋
์ ๊ธฐ๋ฅ | |
| | ๐๏ธ **๋น์ ์ง์** | ๋ชจ๋ธ์ ์ด๋ฏธ์ง ์ ์ก | |
| | ๐ ๏ธ **๋๊ตฌ ํธ์ถ** | ํจ์ ํธ์ถ ์ง์ | |
| | ๐ฌ **์ ์ฒด ๋ฉ์์ง ๊ธฐ๋ก** | ์์ ํ ๋ํ ์ปจํ
์คํธ ์ ๋ฌ | |
| | ๐ก **์คํธ๋ฆฌ๋ฐ** | ์์ ํ SSE ์คํธ๋ฆฌ๋ฐ ์ง์ | |
| | ๐ **์ฌ์๋ ๋ก์ง** | ์ค๋ฅ ์ ์๋ ์ฌ์๋ (403, 429, 5xx) | |
| | ๐ **ํ์ฅ ๋ชจ๋ธ ๋ชฉ๋ก** | ๋ฒ์ ๋ชจ๋ธ ํฌํจ | |
| | ๐ **์ค๋งํธ ํ ํฐ ๊ด๋ฆฌ** | ๋ง๋ฃ ์ ์๋ ๊ฐฑ์ | |
|
|
| --- |
|
|
| ## ๐ ๋น ๋ฅธ ์์ |
|
|
| ### ์ฌ์ ์๊ตฌ ์ฌํญ |
|
|
| - Python 3.10+ |
| - ๋ค์ ์ค ํ๋: |
| - ๋ก๊ทธ์ธ๋ ๊ณ์ ์ด ์๋ [Kiro IDE](https://kiro.dev/), ๋๋ |
| - AWS SSO (AWS IAM Identity Center, OIDC)๊ฐ ์๋ [Kiro CLI](https://kiro.dev/cli/) - ๋ฌด๋ฃ Builder ID ๋๋ ๊ธฐ์
๊ณ์ |
|
|
| ### ์ค์น |
|
|
| ```bash |
| # ์ ์ฅ์ ํด๋ก (Git ํ์) |
| git clone https://github.com/Jwadow/kiro-gateway.git |
| cd kiro-gateway |
| |
| # ๋๋ ZIP ๋ค์ด๋ก๋: Code โ Download ZIP โ ์์ถ ํด์ โ kiro-gateway ํด๋ ์ด๊ธฐ |
| |
| # ์์กด์ฑ ์ค์น |
| pip install -r requirements.txt |
| |
| # ์ค์ (์ค์ ์น์
์ฐธ์กฐ) |
| cp .env.example .env |
| # .env๋ฅผ ๋ณต์ฌํ๊ณ ์๊ฒฉ ์ฆ๋ช
์ผ๋ก ํธ์ง |
| |
| # ์๋ฒ ์์ |
| python main.py |
| |
| # ๋๋ ์ฌ์ฉ์ ์ ์ ํฌํธ๋ก (8000์ด ์ฌ์ฉ ์ค์ธ ๊ฒฝ์ฐ) |
| python main.py --port 9000 |
| ``` |
|
|
| ์๋ฒ๋ `http://localhost:8000`์์ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค |
|
|
| --- |
|
|
| ## โ๏ธ ์ค์ |
|
|
| ### ์ต์
1: JSON ์๊ฒฉ ์ฆ๋ช
ํ์ผ (Kiro IDE / Enterprise) |
|
|
| ์๊ฒฉ ์ฆ๋ช
ํ์ผ ๊ฒฝ๋ก ์ง์ : |
|
|
| ๋ค์๊ณผ ํจ๊ป ์๋: |
| - **Kiro IDE** (ํ์ค) - ๊ฐ์ธ ๊ณ์ ์ฉ |
| - **Enterprise** - SSO๊ฐ ์๋ ๊ธฐ์
๊ณ์ ์ฉ |
|
|
| ```env |
| KIRO_CREDS_FILE="~/.aws/sso/cache/kiro-auth-token.json" |
| |
| # ํ๋ก์ ์๋ฒ๋ฅผ ๋ณดํธํ๋ ๋น๋ฐ๋ฒํธ (์์ ํ ๋ฌธ์์ด ์ค์ ) |
| # ๊ฒ์ดํธ์จ์ด์ ์ฐ๊ฒฐํ ๋ api_key๋ก ์ฌ์ฉํฉ๋๋ค |
| PROXY_API_KEY="my-super-secret-password-123" |
| ``` |
|
|
| <details> |
| <summary>๐ JSON ํ์ผ ํ์</summary> |
|
|
| ```json |
| { |
| "accessToken": "eyJ...", |
| "refreshToken": "eyJ...", |
| "expiresAt": "2025-01-12T23:00:00.000Z", |
| "profileArn": "arn:aws:codewhisperer:us-east-1:...", |
| "region": "us-east-1", |
| "clientIdHash": "abc123..." // Optional: for corporate SSO setups |
| } |
| ``` |
|
|
| > **์ฐธ๊ณ :** `~/.aws/sso/cache/`์ ๋ ๊ฐ์ JSON ํ์ผ์ด ์๋ ๊ฒฝ์ฐ (์: `kiro-auth-token.json` ๋ฐ ํด์ ์ด๋ฆ์ ํ์ผ), `KIRO_CREDS_FILE`์์ `kiro-auth-token.json`์ ์ฌ์ฉํ์ธ์. ๊ฒ์ดํธ์จ์ด๊ฐ ๋ค๋ฅธ ํ์ผ์ ์๋์ผ๋ก ๋ก๋ํฉ๋๋ค. |
|
|
| </details> |
|
|
| ### ์ต์
2: ํ๊ฒฝ ๋ณ์ (.env ํ์ผ) |
|
|
| ํ๋ก์ ํธ ๋ฃจํธ์ `.env` ํ์ผ ์์ฑ: |
|
|
| ```env |
| # ํ์ |
| REFRESH_TOKEN="your_kiro_refresh_token" |
| |
| # ํ๋ก์ ์๋ฒ๋ฅผ ๋ณดํธํ๋ ๋น๋ฐ๋ฒํธ (์์ ํ ๋ฌธ์์ด ์ค์ ) |
| PROXY_API_KEY="my-super-secret-password-123" |
| |
| # ์ ํ ์ฌํญ |
| PROFILE_ARN="arn:aws:codewhisperer:us-east-1:..." |
| KIRO_REGION="us-east-1" |
| ``` |
|
|
| ### ์ต์
3: AWS SSO ์๊ฒฉ ์ฆ๋ช
(kiro-cli / Enterprise) |
|
|
| AWS SSO (AWS IAM Identity Center)์ ํจ๊ป `kiro-cli` ๋๋ Kiro IDE๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ๊ฒ์ดํธ์จ์ด๊ฐ ์๋์ผ๋ก ์ ์ ํ ์ธ์ฆ์ ๊ฐ์งํ๊ณ ์ฌ์ฉํฉ๋๋ค. |
|
|
| ๋ฌด๋ฃ Builder ID ๊ณ์ ๊ณผ ๊ธฐ์
๊ณ์ ๋ชจ๋์์ ์๋ํฉ๋๋ค. |
|
|
| ```env |
| KIRO_CREDS_FILE="~/.aws/sso/cache/your-sso-cache-file.json" |
| |
| # ํ๋ก์ ์๋ฒ๋ฅผ ๋ณดํธํ๋ ๋น๋ฐ๋ฒํธ |
| PROXY_API_KEY="my-super-secret-password-123" |
| |
| # ์ฐธ๊ณ : AWS SSO (Builder ID ๋ฐ ๊ธฐ์
๊ณ์ ) ์ฌ์ฉ์๋ PROFILE_ARN ๋ถํ์ |
| # ๊ฒ์ดํธ์จ์ด๋ ๊ทธ๊ฒ ์์ด๋ ์๋ํฉ๋๋ค |
| ``` |
|
|
| <details> |
| <summary>๐ AWS SSO JSON ํ์ผ ํ์</summary> |
|
|
| AWS SSO ์๊ฒฉ ์ฆ๋ช
ํ์ผ (`~/.aws/sso/cache/`์์)์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค: |
|
|
| ```json |
| { |
| "accessToken": "eyJ...", |
| "refreshToken": "eyJ...", |
| "expiresAt": "2025-01-12T23:00:00.000Z", |
| "region": "us-east-1", |
| "clientId": "...", |
| "clientSecret": "..." |
| } |
| ``` |
|
|
| **์ฐธ๊ณ :** AWS SSO (Builder ID ๋ฐ ๊ธฐ์
๊ณ์ ) ์ฌ์ฉ์๋ `profileArn`์ด ํ์ ์์ต๋๋ค. ๊ฒ์ดํธ์จ์ด๋ ๊ทธ๊ฒ ์์ด๋ ์๋ํฉ๋๋ค (์ง์ ๋ ๊ฒฝ์ฐ ๋ฌด์๋จ). |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ ์๋ ๋ฐฉ์</summary> |
|
|
| ๊ฒ์ดํธ์จ์ด๋ ์๊ฒฉ ์ฆ๋ช
ํ์ผ์ ๊ธฐ๋ฐ์ผ๋ก ์ธ์ฆ ์ ํ์ ์๋ ๊ฐ์งํฉ๋๋ค: |
|
|
| - **Kiro Desktop Auth** (๊ธฐ๋ณธ๊ฐ): `clientId`์ `clientSecret`์ด ์์ ๋ ์ฌ์ฉ |
| - ์๋ํฌ์ธํธ: `https://prod.{region}.auth.desktop.kiro.dev/refreshToken` |
| |
| - **AWS SSO (OIDC)**: `clientId`์ `clientSecret`์ด ์์ ๋ ์ฌ์ฉ |
| - ์๋ํฌ์ธํธ: `https://oidc.{region}.amazonaws.com/token` |
|
|
| ์ถ๊ฐ ์ค์ ๋ถํ์ โ ์๊ฒฉ ์ฆ๋ช
ํ์ผ๋ง ์ง์ ํ๋ฉด ๋ฉ๋๋ค! |
|
|
| </details> |
|
|
| ### ์ต์
4: kiro-cli SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค |
|
|
| `kiro-cli`๋ฅผ ์ฌ์ฉํ๊ณ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ง์ ์ฌ์ฉํ๋ ค๋ ๊ฒฝ์ฐ: |
|
|
| ```env |
| KIRO_CLI_DB_FILE="~/.local/share/kiro-cli/data.sqlite3" |
| |
| # ํ๋ก์ ์๋ฒ๋ฅผ ๋ณดํธํ๋ ๋น๋ฐ๋ฒํธ |
| PROXY_API_KEY="my-super-secret-password-123" |
| |
| # ์ฐธ๊ณ : AWS SSO (Builder ID ๋ฐ ๊ธฐ์
๊ณ์ ) ์ฌ์ฉ์๋ PROFILE_ARN ๋ถํ์ |
| # ๊ฒ์ดํธ์จ์ด๋ ๊ทธ๊ฒ ์์ด๋ ์๋ํฉ๋๋ค |
| ``` |
|
|
| <details> |
| <summary>๐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์น</summary> |
|
|
| | CLI ๋๊ตฌ | ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฒฝ๋ก | |
| |----------|------------------| |
| | kiro-cli | `~/.local/share/kiro-cli/data.sqlite3` | |
| | amazon-q-developer-cli | `~/.local/share/amazon-q/data.sqlite3` | |
|
|
| ๊ฒ์ดํธ์จ์ด๋ `auth_kv` ํ
์ด๋ธ์์ ์๊ฒฉ ์ฆ๋ช
์ ์ฝ์ต๋๋ค: |
| - `kirocli:odic:token` ๋๋ `codewhisperer:odic:token` โ ์ก์ธ์ค ํ ํฐ, ๋ฆฌํ๋ ์ ํ ํฐ, ๋ง๋ฃ ์๊ฐ |
| - `kirocli:odic:device-registration` ๋๋ `codewhisperer:odic:device-registration` โ ํด๋ผ์ด์ธํธ ID์ ์ํฌ๋ฆฟ |
|
|
| ๋ค์ํ kiro-cli ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ํด ๋ ํค ํ์ ๋ชจ๋ ์ง์๋ฉ๋๋ค. |
|
|
| </details> |
|
|
| ### ์๊ฒฉ ์ฆ๋ช
์ป๊ธฐ |
|
|
| **Kiro IDE ์ฌ์ฉ์:** |
| - Kiro IDE์ ๋ก๊ทธ์ธํ๊ณ ์์ ์ต์
1 (JSON ์๊ฒฉ ์ฆ๋ช
ํ์ผ) ์ฌ์ฉ |
| - ์๊ฒฉ ์ฆ๋ช
ํ์ผ์ ๋ก๊ทธ์ธ ํ ์๋ ์์ฑ๋ฉ๋๋ค |
|
|
| **Kiro CLI ์ฌ์ฉ์:** |
| - `kiro-cli login`์ผ๋ก ๋ก๊ทธ์ธํ๊ณ ์์ ์ต์
3 ๋๋ 4 ์ฌ์ฉ |
| - ์๋ ํ ํฐ ์ถ์ถ ๋ถํ์! |
|
|
| <details> |
| <summary>๐ง ๊ณ ๊ธ: ์๋ ํ ํฐ ์ถ์ถ</summary> |
|
|
| ๋ฆฌํ๋ ์ ํ ํฐ์ ์๋์ผ๋ก ์ถ์ถํด์ผ ํ๋ ๊ฒฝ์ฐ (์: ๋๋ฒ๊น
์ฉ), Kiro IDE ํธ๋ํฝ์ ๊ฐ๋ก์ฑ ์ ์์ต๋๋ค: |
| - ๋ค์์ผ๋ก์ ์์ฒญ ์ฐพ๊ธฐ: `prod.us-east-1.auth.desktop.kiro.dev/refreshToken` |
|
|
| </details> |
|
|
| --- |
|
|
| ## ๐ VPN/ํ๋ก์ ์ง์ |
|
|
| **์ค๊ตญ, ๊ธฐ์
๋คํธ์ํฌ ๋๋ AWS ์๋น์ค ์ฐ๊ฒฐ์ ๋ฌธ์ ๊ฐ ์๋ ์ง์ญ์ ์ฌ์ฉ์๋ฅผ ์ํ ๊ฒ์
๋๋ค.** |
|
|
| ๊ฒ์ดํธ์จ์ด๋ ๋ชจ๋ Kiro API ์์ฒญ์ VPN ๋๋ ํ๋ก์ ์๋ฒ๋ฅผ ํตํด ๋ผ์ฐํ
ํ๋ ๊ฒ์ ์ง์ํฉ๋๋ค. AWS ์๋ํฌ์ธํธ์ ๋ํ ์ฐ๊ฒฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฑฐ๋ ๊ธฐ์
ํ๋ก์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒฝ์ฐ ํ์์
๋๋ค. |
|
|
| ### ์ค์ |
|
|
| `.env` ํ์ผ์ ์ถ๊ฐ: |
|
|
| ```env |
| # HTTP ํ๋ก์ |
| VPN_PROXY_URL=http://127.0.0.1:7890 |
| |
| # SOCKS5 ํ๋ก์ |
| VPN_PROXY_URL=socks5://127.0.0.1:1080 |
| |
| # ์ธ์ฆ ํฌํจ (๊ธฐ์
ํ๋ก์) |
| VPN_PROXY_URL=http://username:password@proxy.company.com:8080 |
| |
| # ํ๋กํ ์ฝ ์์ (๊ธฐ๋ณธ๊ฐ http://) |
| VPN_PROXY_URL=192.168.1.100:8080 |
| ``` |
|
|
| ### ์ง์๋๋ ํ๋กํ ์ฝ |
|
|
| - โ
**HTTP** โ ํ์ค ํ๋ก์ ํ๋กํ ์ฝ |
| - โ
**HTTPS** โ ๋ณด์ ํ๋ก์ ์ฐ๊ฒฐ |
| - โ
**SOCKS5** โ ๊ณ ๊ธ ํ๋ก์ ํ๋กํ ์ฝ (VPN ์ํํธ์จ์ด์์ ์ผ๋ฐ์ ) |
| - โ
**์ธ์ฆ** โ URL์ ํฌํจ๋ ์ฌ์ฉ์๋ช
/๋น๋ฐ๋ฒํธ |
|
|
| ### ํ์ํ ๊ฒฝ์ฐ |
|
|
| | ์ํฉ | ํด๊ฒฐ์ฑ
| |
| |------|--------| |
| | AWS ์ฐ๊ฒฐ ํ์์์ | VPN/ํ๋ก์๋ฅผ ์ฌ์ฉํ์ฌ ํธ๋ํฝ ๋ผ์ฐํ
| |
| | ๊ธฐ์
๋คํธ์ํฌ ์ ํ | ํ์ฌ ํ๋ก์ ๊ตฌ์ฑ | |
| | ์ง์ญ ์ฐ๊ฒฐ ๋ฌธ์ | ํ๋ก์ ์ง์์ด ์๋ VPN ์๋น์ค ์ฌ์ฉ | |
| | ๊ฐ์ธ์ ๋ณด ๋ณดํธ ์๊ตฌ์ฌํญ | ์์ ์ ํ๋ก์ ์๋ฒ๋ฅผ ํตํด ๋ผ์ฐํ
| |
|
|
| ### ํ๋ก์ ์ง์์ด ์๋ ์ธ๊ธฐ VPN ์ํํธ์จ์ด |
|
|
| ๋๋ถ๋ถ์ VPN ํด๋ผ์ด์ธํธ๋ ๋ก์ปฌ ํ๋ก์ ์๋ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค: |
| - **Sing-box** โ HTTP/SOCKS5 ํ๋ก์ ์ง์์ด ์๋ ์ต์ VPN ํด๋ผ์ด์ธํธ |
| - **Clash** โ ์ผ๋ฐ์ ์ผ๋ก `http://127.0.0.1:7890`์์ ์คํ |
| - **V2Ray** โ ๊ตฌ์ฑ ๊ฐ๋ฅํ SOCKS5/HTTP ํ๋ก์ |
| - **Shadowsocks** โ SOCKS5 ํ๋ก์ ์ง์ |
| - **๊ธฐ์
VPN** โ ํ๋ก์ ์ค์ ์ ๋ํด IT ๋ถ์์ ๋ฌธ์ |
|
|
| ํ๋ก์ ์ง์์ด ํ์ํ์ง ์์ผ๋ฉด `VPN_PROXY_URL`์ ๋น์๋์ธ์ (๊ธฐ๋ณธ๊ฐ). |
|
|
| --- |
|
|
| ## ๐ก API ๋ ํผ๋ฐ์ค |
|
|
| ### ์๋ํฌ์ธํธ |
|
|
| | ์๋ํฌ์ธํธ | ๋ฉ์๋ | ์ค๋ช
| |
| |-----------|--------|------| |
| | `/` | GET | ํฌ์ค ์ฒดํฌ | |
| | `/health` | GET | ์์ธ ํฌ์ค ์ฒดํฌ | |
| | `/v1/models` | GET | ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ธ ๋ชฉ๋ก | |
| | `/v1/chat/completions` | POST | OpenAI Chat Completions API | |
| | `/v1/messages` | POST | Anthropic Messages API | |
|
|
| --- |
|
|
| ## ๐ก ์ฌ์ฉ ์์ |
|
|
| ### OpenAI API |
|
|
| <details> |
| <summary>๐น ๊ฐ๋จํ cURL ์์ฒญ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/chat/completions \ |
| -H "Authorization: Bearer my-super-secret-password-123" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "messages": [{"role": "user", "content": "์๋
ํ์ธ์!"}], |
| "stream": true |
| }' |
| ``` |
|
|
| > **์ฐธ๊ณ :** `my-super-secret-password-123`์ `.env` ํ์ผ์ ์ค์ ํ `PROXY_API_KEY`๋ก ๊ต์ฒดํ์ธ์. |
|
|
| </details> |
|
|
| <details> |
| <summary>๐น ์คํธ๋ฆฌ๋ฐ ์์ฒญ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/chat/completions \ |
| -H "Authorization: Bearer my-super-secret-password-123" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "messages": [ |
| {"role": "system", "content": "๋น์ ์ ๋์์ด ๋๋ ์ด์์คํดํธ์
๋๋ค."}, |
| {"role": "user", "content": "2+2๋ ์ผ๋ง์ธ๊ฐ์?"} |
| ], |
| "stream": true |
| }' |
| ``` |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ ๏ธ ๋๊ตฌ ํธ์ถ ํฌํจ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/chat/completions \ |
| -H "Authorization: Bearer my-super-secret-password-123" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "messages": [{"role": "user", "content": "๋ฐ๋ ๋ ์จ๋ ์ด๋์?"}], |
| "tools": [{ |
| "type": "function", |
| "function": { |
| "name": "get_weather", |
| "description": "์์น์ ๋ ์จ ๊ฐ์ ธ์ค๊ธฐ", |
| "parameters": { |
| "type": "object", |
| "properties": { |
| "location": {"type": "string", "description": "๋์ ์ด๋ฆ"} |
| }, |
| "required": ["location"] |
| } |
| } |
| }] |
| }' |
| ``` |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ Python OpenAI SDK</summary> |
|
|
| ```python |
| from openai import OpenAI |
| |
| client = OpenAI( |
| base_url="http://localhost:8000/v1", |
| api_key="my-super-secret-password-123" # .env์ PROXY_API_KEY |
| ) |
| |
| response = client.chat.completions.create( |
| model="claude-sonnet-4-5", |
| messages=[ |
| {"role": "system", "content": "๋น์ ์ ๋์์ด ๋๋ ์ด์์คํดํธ์
๋๋ค."}, |
| {"role": "user", "content": "์๋
ํ์ธ์!"} |
| ], |
| stream=True |
| ) |
| |
| for chunk in response: |
| if chunk.choices[0].delta.content: |
| print(chunk.choices[0].delta.content, end="") |
| ``` |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ฆ LangChain</summary> |
|
|
| ```python |
| from langchain_openai import ChatOpenAI |
| |
| llm = ChatOpenAI( |
| base_url="http://localhost:8000/v1", |
| api_key="my-super-secret-password-123", # .env์ PROXY_API_KEY |
| model="claude-sonnet-4-5" |
| ) |
| |
| response = llm.invoke("์๋
ํ์ธ์, ์ด๋ป๊ฒ ์ง๋ด์ธ์?") |
| print(response.content) |
| ``` |
|
|
| </details> |
|
|
| ### Anthropic API |
|
|
| <details> |
| <summary>๐น ๊ฐ๋จํ cURL ์์ฒญ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/messages \ |
| -H "x-api-key: my-super-secret-password-123" \ |
| -H "anthropic-version: 2023-06-01" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "max_tokens": 1024, |
| "messages": [{"role": "user", "content": "์๋
ํ์ธ์!"}] |
| }' |
| ``` |
|
|
| > **์ฐธ๊ณ :** Anthropic API๋ `Authorization: Bearer` ๋์ `x-api-key` ํค๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ ๋ค ์ง์๋ฉ๋๋ค. |
|
|
| </details> |
|
|
| <details> |
| <summary>๐น ์์คํ
ํ๋กฌํํธ ํฌํจ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/messages \ |
| -H "x-api-key: my-super-secret-password-123" \ |
| -H "anthropic-version: 2023-06-01" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "max_tokens": 1024, |
| "system": "๋น์ ์ ๋์์ด ๋๋ ์ด์์คํดํธ์
๋๋ค.", |
| "messages": [{"role": "user", "content": "์๋
ํ์ธ์!"}] |
| }' |
| ``` |
|
|
| > **์ฐธ๊ณ :** Anthropic API์์ `system`์ ๋ฉ์์ง๊ฐ ์๋ ๋ณ๋์ ํ๋์
๋๋ค. |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ก ์คํธ๋ฆฌ๋ฐ</summary> |
|
|
| ```bash |
| curl http://localhost:8000/v1/messages \ |
| -H "x-api-key: my-super-secret-password-123" \ |
| -H "anthropic-version: 2023-06-01" \ |
| -H "Content-Type: application/json" \ |
| -d '{ |
| "model": "claude-sonnet-4-5", |
| "max_tokens": 1024, |
| "stream": true, |
| "messages": [{"role": "user", "content": "์๋
ํ์ธ์!"}] |
| }' |
| ``` |
|
|
| </details> |
|
|
| <details> |
| <summary>๐ Python Anthropic SDK</summary> |
|
|
| ```python |
| import anthropic |
| |
| client = anthropic.Anthropic( |
| api_key="my-super-secret-password-123", # .env์ PROXY_API_KEY |
| base_url="http://localhost:8000" |
| ) |
| |
| # ๋น์คํธ๋ฆฌ๋ฐ |
| response = client.messages.create( |
| model="claude-sonnet-4-5", |
| max_tokens=1024, |
| messages=[{"role": "user", "content": "์๋
ํ์ธ์!"}] |
| ) |
| print(response.content[0].text) |
| |
| # ์คํธ๋ฆฌ๋ฐ |
| with client.messages.stream( |
| model="claude-sonnet-4-5", |
| max_tokens=1024, |
| messages=[{"role": "user", "content": "์๋
ํ์ธ์!"}] |
| ) as stream: |
| for text in stream.text_stream: |
| print(text, end="", flush=True) |
| ``` |
|
|
| </details> |
|
|
| --- |
|
|
| ## ๐ง ๋๋ฒ๊น
|
|
|
| ๋๋ฒ๊ทธ ๋ก๊น
์ **๊ธฐ๋ณธ์ ์ผ๋ก ๋นํ์ฑํ**๋์ด ์์ต๋๋ค. ํ์ฑํํ๋ ค๋ฉด `.env`์ ์ถ๊ฐ: |
|
|
| ```env |
| # ๋๋ฒ๊ทธ ๋ก๊น
๋ชจ๋: |
| # - off: ๋นํ์ฑํ (๊ธฐ๋ณธ๊ฐ) |
| # - errors: ์คํจํ ์์ฒญ๋ง ๋ก๊ทธ ์ ์ฅ (4xx, 5xx) - ๋ฌธ์ ํด๊ฒฐ์ ๊ถ์ฅ |
| # - all: ๋ชจ๋ ์์ฒญ ๋ก๊ทธ ์ ์ฅ (์์ฒญ๋ง๋ค ๋ฎ์ด์ฐ๊ธฐ) |
| DEBUG_MODE=errors |
| ``` |
|
|
| ### ๋๋ฒ๊ทธ ๋ชจ๋ |
|
|
| | ๋ชจ๋ | ์ค๋ช
| ์ฉ๋ | |
| |------|------|------| |
| | `off` | ๋นํ์ฑํ (๊ธฐ๋ณธ๊ฐ) | ํ๋ก๋์
| |
| | `errors` | ์คํจํ ์์ฒญ๋ง ๋ก๊ทธ ์ ์ฅ (4xx, 5xx) | **๋ฌธ์ ํด๊ฒฐ์ ๊ถ์ฅ** | |
| | `all` | ๋ชจ๋ ์์ฒญ ๋ก๊ทธ ์ ์ฅ | ๊ฐ๋ฐ/๋๋ฒ๊น
| |
|
|
| ### ๋๋ฒ๊ทธ ํ์ผ |
|
|
| ํ์ฑํ๋๋ฉด ์์ฒญ์ด `debug_logs/` ํด๋์ ๊ธฐ๋ก๋ฉ๋๋ค: |
|
|
| | ํ์ผ | ์ค๋ช
| |
| |------|------| |
| | `request_body.json` | ํด๋ผ์ด์ธํธ๋ก๋ถํฐ์ ์์ ์์ฒญ (OpenAI ํ์) | |
| | `kiro_request_body.json` | Kiro API๋ก ์ ์ก๋ ์์ฒญ | |
| | `response_stream_raw.txt` | Kiro๋ก๋ถํฐ์ ์์ ์คํธ๋ฆผ | |
| | `response_stream_modified.txt` | ๋ณํ๋ ์คํธ๋ฆผ (OpenAI ํ์) | |
| | `app_logs.txt` | ์์ฒญ์ ๋ํ ์ ํ๋ฆฌ์ผ์ด์
๋ก๊ทธ | |
| | `error_info.json` | ์ค๋ฅ ์ธ๋ถ ์ ๋ณด (์ค๋ฅ ์์๋ง) | |
|
|
| --- |
|
|
| ## ๐ ๋ผ์ด์ ์ค |
|
|
| ์ด ํ๋ก์ ํธ๋ **GNU Affero General Public License v3.0 (AGPL-3.0)**์ผ๋ก ๋ผ์ด์ ์ค๋ฉ๋๋ค. |
|
|
| ์ด๊ฒ์ ๋ค์์ ์๋ฏธํฉ๋๋ค: |
| - โ
์ด ์ํํธ์จ์ด๋ฅผ ์ฌ์ฉ, ์์ , ๋ฐฐํฌํ ์ ์์ต๋๋ค |
| - โ
์์
์ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค |
| - โ ๏ธ ์ํํธ์จ์ด๋ฅผ ๋ฐฐํฌํ ๋ **์์ค ์ฝ๋๋ฅผ ๊ณต๊ฐํด์ผ ํฉ๋๋ค** |
| - โ ๏ธ **๋คํธ์ํฌ ์ฌ์ฉ์ ๋ฐฐํฌ์
๋๋ค** โ ์์ ๋ ๋ฒ์ ์ ์๋ฒ์์ ์คํํ๊ณ ๋ค๋ฅธ ์ฌ๋์ด ์ํธ ์์ฉํ ์ ์๊ฒ ํ๋ฉด ์์ค ์ฝ๋๋ฅผ ๊ทธ๋ค์๊ฒ ์ ๊ณตํด์ผ ํฉ๋๋ค |
| - โ ๏ธ ์์ ์ฌํญ์ ๋์ผํ ๋ผ์ด์ ์ค๋ก ๋ฆด๋ฆฌ์คํด์ผ ํฉ๋๋ค |
|
|
| ์ ์ฒด ๋ผ์ด์ ์ค ํ
์คํธ๋ [LICENSE](../../LICENSE) ํ์ผ์ ์ฐธ์กฐํ์ธ์. |
|
|
| ### ์ AGPL-3.0์ธ๊ฐ? |
|
|
| AGPL-3.0์ ์ด ์ํํธ์จ์ด์ ๋ํ ๊ฐ์ ์ด ์ ์ฒด ์ปค๋ฎค๋ํฐ์ ์ด์ต์ด ๋๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด ๊ฒ์ดํธ์จ์ด๋ฅผ ์์ ํ๊ณ ์๋น์ค๋ก ๋ฐฐํฌํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ์์ ๊ฐ์ ์ฌํญ์ ๊ณต์ ํด์ผ ํฉ๋๋ค. |
|
|
| ### ๊ธฐ์ฌ์ ๋ผ์ด์ ์ค ๊ณ์ฝ (CLA) |
|
|
| ์ด ํ๋ก์ ํธ์ ๊ธฐ์ฌ๋ฅผ ์ ์ถํจ์ผ๋ก์จ [๊ธฐ์ฌ์ ๋ผ์ด์ ์ค ๊ณ์ฝ (CLA)](../../CLA.md)์ ์กฐ๊ฑด์ ๋์ํ๊ฒ ๋ฉ๋๋ค. ์ด๊ฒ์ ๋ค์์ ๋ณด์ฅํฉ๋๋ค: |
| - ๊ธฐ์ฌ๋ฅผ ์ ์ถํ ๊ถ๋ฆฌ๊ฐ ์์ |
| - ๋ฉ์ธํ
์ด๋์๊ฒ ๊ธฐ์ฌ๋ฅผ ์ฌ์ฉํ๊ณ ์ฌ๋ผ์ด์ ์คํ ๊ถ๋ฆฌ๋ฅผ ๋ถ์ฌํจ |
| - ํ๋ก์ ํธ๊ฐ ๋ฒ์ ์ผ๋ก ๋ณดํธ๋จ |
|
|
| --- |
|
|
| ## ๐ ํ๋ก์ ํธ ํ์ |
|
|
| <div align="center"> |
|
|
| <img src="https://raw.githubusercontent.com/Tarikul-Islam-Anik/Animated-Fluent-Emojis/master/Emojis/Smilies/Smiling%20Face%20with%20Hearts.png" alt="Love" width="80" /> |
|
|
| **์ด ํ๋ก์ ํธ๊ฐ ์๊ฐ์ด๋ ๋์ ์ ์ฝํด ์ฃผ์๋ค๋ฉด ํ์์ ๊ณ ๋ คํด ์ฃผ์ธ์!** |
|
|
| ๋ชจ๋ ๊ธฐ์ฌ๊ฐ ์ด ํ๋ก์ ํธ๋ฅผ ์ ์งํ๊ณ ์ฑ์ฅ์ํค๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค |
|
|
| <br> |
|
|
| ### ๐ค ๊ธฐ๋ถ |
|
|
| [**โ ์ผํ์ฑ ๊ธฐ๋ถ**](https://app.lava.top/jwadow?tabId=donate) โข [**๐ ์๊ฐ ํ์**](https://app.lava.top/jwadow?tabId=subscriptions) |
|
|
| <br> |
|
|
| ### ๐ช ๋๋ ์ํธํํ ์ ์ก |
|
|
| | ํตํ | ๋คํธ์ํฌ | ์ฃผ์ | |
| |:----:|:-------:|:-----| |
| | **USDT** | TRC20 | `TSVtgRc9pkC1UgcbVeijBHjFmpkYHDRu26` | |
| | **BTC** | Bitcoin | `12GZqxqpcBsqJ4Vf1YreLqwoMGvzBPgJq6` | |
| | **ETH** | Ethereum | `0xc86eab3bba3bbaf4eb5b5fff8586f1460f1fd395` | |
| | **SOL** | Solana | `9amykF7KibZmdaw66a1oqYJyi75fRqgdsqnG66AK3jvh` | |
| | **TON** | TON | `UQBVh8T1H3GI7gd7b-_PPNnxHYYxptrcCVf3qQk5v41h3QTM` | |
|
|
| </div> |
|
|
| --- |
|
|
| ## โ ๏ธ ๋ฉด์ฑ
์กฐํญ |
|
|
| ์ด ํ๋ก์ ํธ๋ Amazon Web Services (AWS), Anthropic ๋๋ Kiro IDE์ ์ ํด, ์น์ธ ๋๋ ํ์๋์ง ์์ต๋๋ค. ์์ ์ ์ฑ
์ ํ์ ์ฌ์ฉํ๊ณ ๊ธฐ๋ณธ API์ ์๋น์ค ์ฝ๊ด์ ์ค์ํ์ธ์. |
|
|
| --- |
|
|
| <div align="center"> |
|
|
| **[โฌ ๋งจ ์๋ก](#-kiro-gateway)** |
|
|
| </div> |
|
|