์์ฐ์ด ํฐ๋ฏธ๋ (CLOVA NLP)
1. ๊ฐ์
๋ฐฐ๊ฒฝ
ํฐ๋ฏธ๋ ๋ช
๋ น์ด๋ ๊ฐ๋ฐ์์๊ฒ๋ ์ต์ํ์ง๋ง, ์ผ๋ฐ ์ฌ์ฉ์์๊ฒ๋ ์ง์
์ฅ๋ฒฝ์ด ๋์ต๋๋ค. ์ด์ "user ํด๋ ๋ง๋ค์ด์ค" ๊ฐ์ ์์ฐ์ด๋ฅผ mkdir user๋ก ๋ณํํ๋ ์์ฐ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์ ํ์ต๋๋ค.
๋ชฉ์
์ฌ์ฉ์๊ฐ ์์ฐ์ด๋ก ๋ช
๋ น์ ์
๋ ฅํ๋ฉด ์ด๋ฅผ ์ค์ ํฐ๋ฏธ๋ ๋ช
๋ น์ด๋ก ๋ณํํ์ฌ ์คํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค.
Naver Cloud์ HyperCLOVA X Function Calling API๋ฅผ ํ์ฉํ์ฌ ์ฌ์ฉ์์ ์์ฐ์ด ์
๋ ฅ์ ๋ถ์ํ๊ณ , ์ ์ ํ ์์คํ
๋ช
๋ น์ด๋ฅผ ์์ฑํฉ๋๋ค.
์์
์ฌ์ฉ์ ์
๋ ฅ: "ํ์ฌ ๊ฒฝ๋ก์ user ํด๋๋ฅผ ๋ง๋ค์ด์ค"
→ ์์คํ
ํด์: mkdir user
→ ์คํ ๊ฒฐ๊ณผ: user ๋๋ ํ ๋ฆฌ ์์ฑ ์๋ฃ
์ฃผ์ ๊ธฐ๋ฅ
- ์์ฐ์ด ๋ช
๋ น ํ์ฑ: "user ํด๋ ๋ง๋ค์ด์ค" →
mkdir user - ๋ณตํฉ ๋ช
๋ น์ด ์ฒ๋ฆฌ: "home์ผ๋ก ์ด๋ํ๊ณ TEST ํด๋ ๋ง๋ค์ด์ค" →
cd /home && mkdir TEST - ์คํ ๊ณํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ: ์คํ ์ ์ฌ์ฉ์ ํ์ธ
- Context ๊ธฐ๋ฐ ์ถ๋ก : ํ์ฌ ๊ฒฝ๋ก, ํ์ผ ๋ชฉ๋ก ๋ฑ์ ๊ณ ๋ คํ ๋ช ๋ น์ด ์์ฑ
- ์์ ์ฑ ๊ฒ์ฆ: ์ํํ ๋ช ๋ น์ด ์ฐจ๋จ ๋ฐ ๊ฒ์ฆ
์คํ ํ๋ฉด ( Demo )


๋ณตํฉ ๋ช ๋ น ์๋ต


๋จ์ผ ๋ช ๋ น ์๋ต

ํต์ฌ ๊ธฐ์
- CLOVA AI (HyperCLOVA X): ์์ฐ์ด ์ดํด ๋ฐ ๋ช ๋ น์ด ๋ณํ
- https://clova.ai/tech-blog/skill-function-calling
- ๊ธฐ์กด Syscall ์์คํ : ๋ช ๋ น์ด ์คํ ์ธํ๋ผ ํ์ฉ
CLOVA STUDIO function calling
๋๊ท๋ชจ ์ธ์ด ๋ชจ๋ธ(LLM)์ ์์ฐ์ด ์ฒ๋ฆฌ์์ ๊ฐ๋ ฅํ ์ฑ๋ฅ์ ๋ฐํํ์ง๋ง, ๋ช๊ฐ์ง ํ๊ณ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์ฒซ์งธ, ์ค์๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ ์ต์ ์ ๋ณด๋ฅผ ๋ฐ์ํ๊ธฐ ์ด๋ ต๊ณ ๋์งธ, ์ง์ ์ ์ธ ์ก์ ์ ์ํํ ์ ์๋ค๋ ์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ธฐ์กด์ AI ์ฑ๋ด์ “์ค๋ ๋ ์จ๋ ์ด๋?”๋ผ๋ ์ง๋ฌธ์ ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณํ๊ฑฐ๋, “์ด๋ฒ ์ฃผ ํ ์์ผ 1์์ ์ฒญ์ฒฉ์ฅ ๋ชจ์ ์ผ์ ์ถ๊ฐํด์ค“๋ผ๋ ์์ฒญ์ “์ ๊ฐ ํ ์ ์๋ ์์ฒญ์ด์์.”๋ผ๊ณ ์๋ตํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์ด๋ ๋๋ถ๋ถ์ LLM์ด ์ฌ์ ์ ํ์ต๋ ๋ฐ์ดํฐ๋ง์ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณ์ ์์ฑํ๋ฉฐ, ์ธ๋ถ ๋ฐ์ดํฐ์ ์ฐ๊ฒฐ๋๊ฑฐ๋ ์ค์ ํ๊ฒฝ์์ ๋์ํ๋ ๊ธฐ๋ฅ์ด ๋ถ์กฑํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
HyperCLOVA X๋ ์ด๋ฌํ ํ๊ณ๋ฅผ ๊ทน๋ณตํ๊ธฐ ์ํด ์คํฌ(Skill)๊ณผ Function Calling์ด๋ผ๋ ๋ ๊ฐ์ง ๊ธฐ๋ฅ์ ๋์ ํ์ต๋๋ค. ํนํ Function Calling์ ์คํฌ๋ณด๋ค ๋ ํ์ฅ์ฑ์ด ๋๊ณ ๋ค์ํ ์ก์ ์ ์ํํ ์ ์์ด ๊ฐ๋ฐ์๋ค์๊ฒ ๋ ๋ง์ ๊ฐ๋ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํตํด LLM์ ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ณ , ์ค์ ์ก์ ์ ์ํํ ์ ์๋๋ก ํ์ฅ๋์ด ๋์ฑ ํ๋ถํ๊ณ ์ค์ฉ์ ์ธ AI ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
LLM๊ณผ ์ธ๋ถ ์์คํ ์ ์ฐ๊ฒฐ ๊ณ ๋ฆฌ, ์คํฌ๊ณผ Function Calling
HyperCLOVA X๋ LLM์ด ์ธ๋ถ ์์คํ ๊ณผ ์ํธ์์ฉํ ์ ์๋ ์คํฌ๊ณผ Function Calling ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์คํฌ์ LLM์ด API๋ฅผ ํธ์ถํ์ฌ ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ํ์ฌ CLOVA X์์๋ ์ผํ, ์ฌํ, ๋ง์ผ์ปฌ๋ฆฌ, ์์นด, ํธ๋ฆฌํ ๋ฑ์ ์ธ๋ถ ์๋น์ค ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ํ ์คํฌ์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํ๊ณ ์์ต๋๋ค.
Function Calling์ LLM์ด ์ฌ์ฉ์ ์ง๋ฌธ์ ๋ตํ๊ธฐ ์ํด ํน์ ๊ธฐ๋ฅ์ ํธ์ถํ ์ ์๋ ๊ธฐ๋ฅ์ ๋๋ค. ๋จ์ํ API ํธ์ถ๋ฟ๋ง ์๋๋ผ ์คํฌ๋ฆฝํธ ์คํ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์ ํธ์ถ๊น์ง ๊ฐ๋ฅํ ํ์ฅํ ๊ธฐ๋ฅ์ผ๋ก Function Calling์ ํ์ฉํ๋ฉด ๊ฐ๋ฐ์๊ฐ ์ง์ ํจ์๋ฅผ ํธ์ถํ๊ณ , ํน์ ์ก์ ์ ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ด๋ฉ์ผ์ ์ ์กํ๊ฑฐ๋, ํ์ผ์ ์ ๋ก๋ํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํน์ ์ ๋ณด๋ฅผ ์กฐํํ๋ ๋ฑ ๋ค์ํ ์์ ์ ์๋ํํ ์ ์์ต๋๋ค.
Function Calling์ ํ์ฉํ AI ๊ธฐ๋ฐ ์๋ํ ์์คํ ๊ตฌ์ถ
Function Calling์ ๋จ์ํ ์ ๋ณด ์กฐํ๋ฅผ ๋์ด, ์ธ๋ถ ์์คํ ๊ณผ ์ฐ๋ํ์ฌ ์ค์ ์ก์ ์ ์ํํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฅผ ํ์ฉํ๋ฉด AI๊ฐ ๋จ์ํ ๋ํํ ๋น์๊ฐ ์๋๋ผ, ์ ๋ฌด๋ฅผ ์๋ํํ๊ณ ์ค์ ์์ ์ ์ํํ๋ ๋๊ตฌ๋ก ํ์ฉ๋ ์ ์์ต๋๋ค.

Function Calling์ ๋์ ๋ฐฉ์
AI๊ฐ ์ ์ํ๊ณ , ๊ฐ๋ฐ์๊ฐ ์คํ ์ฌ๋ถ๋ฅผ ์ ์ดํฉ๋๋ค. ๋ชจ๋ธ์ด ์ง์ ํธ์ถํ๋ ๊ฒ์ด ์๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ํจ์ ์คํ์ ์ง์ ์ฒ๋ฆฌํ๊ณ , ์๋ต ๊ฐ์ ๋ชจ๋ธ์ ์ ๋ฌํฉ๋๋ค.

- ์ฌ์ฉ์ ์ฟผ๋ฆฌ ์ ๋ ฅ → AI๊ฐ ์ฌ์ ์ ์ ์๋ ๋๊ตฌ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์ ์ ํ Function์ ์ ํ
- ๋งค๊ฐ๋ณ์ ํฌํจ ์คํ ์์ฒญ ์์ฑ → AI๊ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ์ฌ ์คํ ์์ฒญ ์์ฑ
- ์ฌ์ฉ์๊ฐ Function ์คํ → AI๋ ์คํ์ ์ ์ํ๊ณ , ์ค์ ์คํ์ ์ฌ์ฉ์๊ฐ ์ํ
- ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ํ ๋ต๋ณ ์์ฑ → ์คํ๋ ๊ฒฐ๊ณผ ๊ฐ์ ๋ชจ๋ธ์ด ๋ฐ์ํ์ฌ ์ต์ข ๋ต๋ณ์ ์์ฑ
์ต์ข ๊ธฐ์ ์ ์ : Function Calling
์ด์ธ์๋ Skill ์ด๋ผ๊ณ Chain of Thought(CoT) ๊ณผ์ ์์ ์๋์ผ๋ก API ํธ์ถ์ ๊ฒฐ์ ํ๊ณ ์คํํ๋ ๋ชจ๋ธ์ด ์์ง๋ง, Function Calling ์ AI๊ฐ ์ ์ํ๊ณ , ๊ฐ๋ฐ์๊ฐ ์คํ ์ฌ๋ถ๋ฅผ ์ ์ดํฉ๋๋ค.
๋ณธ ์๋น์ค์์ Function Calling ๊ตฌํ ์๋ฆฌ: ๋ฐ์ดํฐ ์์ง ๋ฐ ํ์ต ๋ฉ์ปค๋์ฆ ์์ฐ์ด ํฐ๋ฏธ๋์ ๊ฐ๋ฐํจ์ ์์ด์ CLOVA ๊ฐ ์ธ๋ถ API ๋ฅผ ํธ์ถํด์ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ด๋ฅผ ์์ฌ๊ฒฐ์ ์ ์ฐธ๊ณ ํ๋ค๊ธฐ ๋ณด๋ค๋, CLOVA ๊ฐ ์ด๋ค ํจ์๋ฅผ ํธ์ถํด์ผํ ์ง ๋งฅ๋ฝ์ ํ์
ํ๊ณ
์ด์ ๋ํ ์คํ์ ์์คํ
์ด ์ํํ๋๊ฒ ๋ ์ ์ ํ๋ค๊ณ ํ๋จํ์ต๋๋ค.

2. ์์คํ ์ํคํ ์ฒ
2.1 ์ ์ฒด ๊ตฌ์กฐ๋ (Mermaid)
2.2 ๋ฐ์ดํฐ ํ๋ฆ๋ (Sequence Diagram)
2.3 ์ปดํฌ๋ํธ ์ํคํ ์ฒ
2.4 NLP ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ
2.5 ํฐ๋ฏธ๋ ๋ชจ๋ ์ํ ๋ค์ด์ด๊ทธ๋จ
์ํคํ ์ฒ
์ ์ฒด ํ๋ฆ๋
[์ฌ์ฉ์]
↓ "user ํด๋ ๋ง๋ค์ด์ค"
[ํ๋ก ํธ์๋ - useTerminal Hook]
↓ POST /api/nlp/parse
[๋ฐฑ์๋ - NlpController]
↓
[NlpService]
โโ collectContext() → ํ์ฌ ๊ฒฝ๋ก, ํ์ผ ๋ชฉ๋ก ์์ง
↓
[ClovaClient]
โโ buildSystemPrompt() → ํ๋กฌํํธ ์์ฑ
โโ filterFunctionSchemas() → ์ง์ ๋ช
๋ น์ด๋ง ํํฐ๋ง
↓ POST to HyperCLOVA X API
[CLOVA API]
↓ Function Calling ์๋ต
[ClovaClient]
โโ parseToolCalls() → Command[] ๋ณํ
↓
[CommandValidator]
โโ validateCommand() → ๋ณด์ ๊ฒ์ฆ
โโ sanitizeArgs() → ์ธ์ ์๋ํ์ด์ง
↓
[NlpService]
โโ ๊ฒ์ฆ๋ ๋ช
๋ น์ด ๋ชฉ๋ก ๋ฐํ
↓
[ํ๋ก ํธ์๋]
โโ ExecutionPlan ํ์ (์ฌ์ฉ์ ํ์ธ)
โโ ์ฌ์ฉ์๊ฐ Enter ์
๋ ฅ
↓ POST /api/nlp/confirm
[NlpController]
↓
[NlpService - executeCommands()]
โโ for each command:
↓
[SyscallService.execute()]
โโ ์ค์ ๋ช
๋ น์ด ์คํ
↓
๊ฒฐ๊ณผ ์์ง ๋ฐ ๋ฐํ
↓
[ํ๋ก ํธ์๋]
โโ ์คํ ๊ฒฐ๊ณผ ํฐ๋ฏธ๋์ ํ์
๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ
apps/
โโโ server/
โ โโโ src/
โ โโโ nlp/
โ โโโ nlp.controller.ts # API ์๋ํฌ์ธํธ
โ โโโ nlp.service.ts # ๋น์ฆ๋์ค ๋ก์ง
โ โโโ clova.client.ts # CLOVA API ํด๋ผ์ด์ธํธ
โ โโโ command.validator.ts # ๋ช
๋ น์ด ๊ฒ์ฆ
โ โโโ function-schemas.ts # Function Calling ์คํค๋ง
โ โโโ nlp.exception.ts # ์ปค์คํ
์์ธ
โ โโโ nlp.module.ts # NestJS ๋ชจ๋
โ โโโ dto/
โ โโโ parse-nlp.dto.ts
โ โโโ nlp-execute.dto.ts
โ โโโ nlp-response.dto.ts
โ
โโโ web/
โโโ src/
โโโ hooks/windows/terminal/
โ โโโ useTerminal.ts # ํฐ๋ฏธ๋ ์ํ ๊ด๋ฆฌ
โโโ components/domain/terminal/
โ โโโ terminal.tsx # ํฐ๋ฏธ๋ UI
โ โโโ executionPlan.tsx # ์คํ ๊ณํ UI
โ โโโ nlpSuggestionPortal.tsx # NLP ์ ์ ํฌํธ
โโโ apis/
โโโ nlp.ts # API ํด๋ผ์ด์ธํธ
์์ธ ์ค๊ณ
1. API ์๋ํฌ์ธํธ
POST /api/nlp/parse
์์ฐ์ด ์ ๋ ฅ์ ๋ถ์ํ์ฌ ๋ช ๋ น์ด ํ๋ณด๋ฅผ ๋ฐํํฉ๋๋ค.
Request:
{
"input": "user ํด๋ ๋ง๋ค์ด์ค"
}
Response:
{
"success": true,
"data": {
"functions": [
{
"command": "mkdir",
"args": "user",
"explanation": "user ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค",
"isValid": true,
"order": 1,
"validationError": null
}
]
},
"error": null
}
POST /api/nlp/confirm
์ฌ์ฉ์๊ฐ ํ์ธํ ๋ช ๋ น์ด๋ฅผ ์ค์ ๋ก ์คํํฉ๋๋ค.
Request:
{
"functions": [
{
"command": "mkdir",
"args": "user",
"explanation": "user ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค",
"isValid": true,
"order": 1
}
]
}
Response (์ฑ๊ณต):
{
"success": true,
"data": {
"allSuccess": true,
"results": [
{
"command": "mkdir",
"args": "user",
"output": "user ํด๋๊ฐ ์์ฑ๋์์ต๋๋ค.",
"success": true
}
],
"successCount": 1,
"totalCount": 1
},
"error": null
}
Response (์คํจ):
{
"success": true,
"data": {
"allSuccess": false,
"results": [
{
"command": "cd",
"args": "/invalid",
"output": "",
"success": false,
"errorMessage": "ํด๋น ๋๋ ํ ๋ฆฌ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค: invalid"
}
],
"successCount": 0,
"totalCount": 1,
"errorMessage": "ํด๋น ๋๋ ํ ๋ฆฌ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค: invalid"
},
"error": null
}
2. Function Calling ์คํค๋ง
์ด 13๊ฐ์ ํฐ๋ฏธ๋ ๋ช ๋ น์ด๋ฅผ Function Schema๋ก ์ ์:
| ๋ช ๋ น์ด | ์ค๋ช | ์ฃผ์ ํ๋ผ๋ฏธํฐ |
|---|---|---|
mkdir |
๋๋ ํ ๋ฆฌ ์์ฑ | title, icon? |
cd |
๋๋ ํ ๋ฆฌ ์ด๋ | path |
ls |
ํ์ผ ๋ชฉ๋ก ํ์ | (์์) |
pwd |
ํ์ฌ ๊ฒฝ๋ก ์ถ๋ ฅ | (์์) |
cat |
ํ์ผ ๋ด์ฉ ์ฝ๊ธฐ | title, extension? |
rm |
ํ์ผ/ํด๋ ์ญ์ | title, extension? |
write |
ํ์ผ ์์ฑ ๋ฐ ์์ฑ | title, extension?, body, icon? |
clear |
ํ๋ฉด ์ง์ฐ๊ธฐ | (์์) |
date |
๋ ์ง/์๊ฐ ํ์ | (์์) |
help |
๋์๋ง ํ์ | (์์) |
uname |
์์คํ ์ ๋ณด ํ์ | (์์) |
exec |
JavaScript ์คํ | filePath (.ejs๋ง) |
log |
๋ก๊ทธ ์กฐํ | level? (error/warn/info/debug) |
๊ฐ ์คํค๋ง๋ apps/server/src/nlp/function-schemas.ts์ ์ ์๋์ด ์์ต๋๋ค.
3. Context ์์ง
CLOVA API์ ์ ๋ฌ๋๋ Context ์ ๋ณด:
{
currentPath: string; // ํ์ฌ ์์
๋๋ ํ ๋ฆฌ (์: "/home/user")
recentCommands: string[]; // ์ต๊ทผ ์คํ ๋ช
๋ น์ด (ํฅํ ๊ตฌํ)
availableFiles: string[]; // ํ์ฌ ๋๋ ํ ๋ฆฌ์ ํ์ผ ๋ชฉ๋ก
supportedCommands: string[]; // ์ง์ํ๋ ๋ช
๋ น์ด ๋ชฉ๋ก
}
์ด๋ฅผ ํตํด CLOVA๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ถ๋ก ์ ํ ์ ์์ต๋๋ค:
- "๋ฆฌํฌํธ ํ์ผ ๋ด์ฉ ๋ณด์ฌ์ค" →
availableFiles์์report.txt๋งค์นญ →cat report.txt - "์์ ํด๋๋ก ์ด๋" →
currentPath๊ณ ๋ ค →cd ..
4. ๋ช ๋ น์ด ๊ฒ์ฆ (CommandValidator)
๋ณด์์ ์ํ ๋ค์ธต ๊ฒ์ฆ:
- ํ์ดํธ๋ฆฌ์คํธ ๊ฒ์ฆ: ์ง์ํ์ง ์๋ ๋ช ๋ น์ด ์ฐจ๋จ
- ์ํ ํจํด ๊ฐ์ง:
- Shell injection ์๋ (
;,&,|, ```,$,(,),<,>) - Directory traversal (
../) - ์์คํ
ํ์ผ ์ ๊ทผ (
/etc/,/root/)
- Shell injection ์๋ (
- ๋ช
๋ น์ด๋ณ ์ถ๊ฐ ๊ฒ์ฆ:
rm: ์ค์ ํ์ผ/๋๋ ํ ๋ฆฌ ๋ณดํธ (/,/home,/root)exec:.ejsํ์ผ๋ง ํ์ฉ
- ์ธ์ ์๋ํ์ด์ง:
- ํน์๋ฌธ์ ์ ๊ฑฐ
- ์ต๋ ๊ธธ์ด ์ ํ (500์)
5. ํ๋ก ํธ์๋ ์ํ ๊ด๋ฆฌ
useTerminal Hook์์ ๊ด๋ฆฌํ๋ ์ํ:
{
// ๊ธฐ๋ณธ ํฐ๋ฏธ๋ ์ํ
currentInput: string;
commandList: Command[];
currentPath: string;
// NLP ๋ชจ๋ ์ํ
isNlpMode: boolean; // CLOVA ๋ชจ๋ ํ์ฑํ ์ฌ๋ถ
nlpPlan: NlpFunction[]; // ์คํ ๊ณํ
isPlanConfirmMode: boolean; // ํ์ธ ๋๊ธฐ ์ค
showPlanDetails: boolean; // ์์ธ๋ณด๊ธฐ ํ ๊ธ
isNlpLoading: boolean; // API ํธ์ถ ์ค
nlpError: string | null; // ์๋ฌ ๋ฉ์์ง
// ๋ก๊ทธ ๋ชจ๋ ์ํ
isLogMode: boolean;
logEntries: string[];
}
6. ์ฌ์ฉ์ ํ๋ก์ฐ
6-1. CLOVA ๋ชจ๋ ์ง์
์ฌ์ฉ์: clova [Enter]
ํฐ๋ฏธ๋: "CLOVA AI ๋ชจ๋ ํ์ฑํ. 'exit'์ผ๋ก ์ข
๋ฃํ์ธ์."
ํ๋กฌํํธ: CLOVA_SHELL > (ํ๋์)
6-2. ์์ฐ์ด ๋ช ๋ น ์ ๋ ฅ
์ฌ์ฉ์: user ํด๋ ๋ง๋ค์ด์ค [Enter]
ํฐ๋ฏธ๋: "CLOVA์๊ฒ ์์ฒญ ์ค..."
↓ (API ํธ์ถ)
ํฐ๋ฏธ๋: [์คํ ๊ณํ ํ์]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLOVA๊ฐ ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ ์ํฉ๋๋ค: โ
โ โ
โ 1. mkdir user โ
โ → user ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค โ
โ โ
โ [Enter] ์คํ [Esc] ์ทจ์ [Space] ์์ธ๋ณด๊ธฐ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
6-3. ์คํ ํ์ธ
์ฌ์ฉ์: [Enter]
ํฐ๋ฏธ๋: "[CLOVA] 1๊ฐ ๋ช
๋ น์ด ์คํ์ ์๋ฒ์ ์์ฒญํฉ๋๋ค..."
↓ (์คํ)
ํฐ๋ฏธ๋:
mkdir user
user ํด๋๊ฐ ์์ฑ๋์์ต๋๋ค.
[CLOVA] ๋ชจ๋ ๋ช
๋ น์ด ์คํ ์๋ฃ (1๊ฐ)
6-4. ๋ณตํฉ ๋ช ๋ น์ด ์์
์ฌ์ฉ์: home์ผ๋ก ์ด๋ํ๊ณ TEST ํด๋ ๋ง๋ค์ด์ค [Enter]
ํฐ๋ฏธ๋: [์คํ ๊ณํ ํ์]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLOVA๊ฐ ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ ์ํฉ๋๋ค: โ
โ โ
โ 1. cd /home โ
โ → /home ๊ฒฝ๋ก๋ก ์ด๋ํฉ๋๋ค โ
โ 2. mkdir TEST โ
โ → TEST ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค โ
โ โ
โ [Enter] ์คํ [Esc] ์ทจ์ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
์ฌ์ฉ์: [Enter]
ํฐ๋ฏธ๋:
cd /home
/home
mkdir TEST
TEST ํด๋๊ฐ ์์ฑ๋์์ต๋๋ค.
[CLOVA] ๋ชจ๋ ๋ช
๋ น์ด ์คํ ์๋ฃ (2๊ฐ)
6-5. CLOVA ๋ชจ๋ ์ข ๋ฃ
์ฌ์ฉ์: exit [Enter]
ํฐ๋ฏธ๋: "[CLOVA] ์์ฐ์ด ๋ชจ๋๊ฐ ์ข
๋ฃ๋์์ต๋๋ค."
ํ๋กฌํํธ: /home > (์ด๋ก์)
์๋ฌ ์ฒ๋ฆฌ
1. CLOVA API ์๋ฌ
| ์ํฉ | HTTP ์ํ | ์์ธ ํด๋์ค | ์ฌ์ฉ์ ๋ฉ์์ง |
|---|---|---|---|
| ์ธ์ฆ ์คํจ | 401 | NlpCommunicationException |
"AI ์๋ฒ ์ธ์ฆ์ ์คํจํ์ต๋๋ค. ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํ์ธ์." |
| Rate Limit | 429 | NlpRateLimitException |
"์์ฒญ ํ๋๋ฅผ ์ด๊ณผํ์ต๋๋ค. ์ ์ ํ ๋ค์ ์๋ํด์ฃผ์ธ์." |
| ํ์์์ | - | NlpTimeoutException |
"AI ์๋ฒ ์๋ต ์๊ฐ์ด ์ด๊ณผ๋์์ต๋๋ค." |
| ์ฐ๊ฒฐ ์คํจ | - | NlpCommunicationException |
"AI ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค." |
| ํ์ฑ ์คํจ | - | NlpParseException |
"AI ์๋ต ํ์์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค." |
| Content Filter | - | NlpParseException |
"๋ถ์ ์ ํ ๋ด์ฉ์ด ๊ฐ์ง๋์์ต๋๋ค." |
2. ๋ช ๋ น์ด ์คํ ์๋ฌ
์คํ ์ค ์๋ฌ ๋ฐ์ ์:
- ํด๋น ๋ช ๋ น์ด์์ ์ค๋จ
- ์ด์ ์ฑ๊ณตํ ๋ช ๋ น์ด๋ ๋กค๋ฐฑํ์ง ์์
- ๋ถ๋ถ ์ฑ๊ณต ์ ๋ณด ์ ๊ณต
์๋ต ์์:
{
"allSuccess": false,
"results": [
{
"command": "cd",
"args": "/home",
"output": "/home",
"success": true
},
{
"command": "mkdir",
"args": "test",
"output": "",
"success": false,
"errorMessage": "์ด๋ฏธ ์กด์ฌํ๋ ๋๋ ํ ๋ฆฌ์
๋๋ค: test"
}
],
"successCount": 1,
"totalCount": 2,
"errorMessage": "์ด๋ฏธ ์กด์ฌํ๋ ๋๋ ํ ๋ฆฌ์
๋๋ค: test"
}
ํ๋ก ํธ์๋ ์ถ๋ ฅ:
cd /home
/home
mkdir test
[ERROR] ์ด๋ฏธ ์กด์ฌํ๋ ๋๋ ํ ๋ฆฌ์
๋๋ค: test
[CLOVA ERROR] ์ด๋ฏธ ์กด์ฌํ๋ ๋๋ ํ ๋ฆฌ์
๋๋ค: test
3. HttpExceptionFilter
๋ชจ๋ NLP ์์ธ๋ HttpExceptionFilter์์ ์ฒ๋ฆฌ๋์ด ์ผ๊ด๋ ํ์์ผ๋ก ๋ฐํ:
{
"success": false,
"data": null,
"error": {
"statusCode": 503,
"message": "AI ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.",
"timestamp": "2024-01-15T12:00:00.000Z",
"path": "/api/nlp/parse"
}
}
๋ณด์ ๊ณ ๋ ค์ฌํญ
- Function Schema ํ์ดํธ๋ฆฌ์คํธ: ๋ฏธ๋ฆฌ ์ ์๋ 13๊ฐ ๋ช ๋ น์ด๋ง ํ์ฉ
- ์ธ์ ๊ฒ์ฆ: Shell injection, Directory traversal ๋ฐฉ์ง
- ์ํ ๋ช
๋ น์ด ์ถ๊ฐ ๊ฒ์ฆ:
rm,exec๋ฑ - ์ธ์ ์๋ํ์ด์ง: ํน์๋ฌธ์ ์ ๊ฑฐ, ๊ธธ์ด ์ ํ
- CLOVA API ์ธ์ฆ: Bearer Token ์ฌ์ฉ
- Timeout ์ค์ : 10์ด๋ก ์ ํํ์ฌ ๋ฌดํ ๋๊ธฐ ๋ฐฉ์ง
ํ๊ฒฝ ๋ณ์
# .env ๋๋ .env.local
CLOVA_API_KEY=your_api_key_here
CLOVA_APP_ID=your_app_id_here
CLOVA_ENDPOINT=https://clovastudio.stream.ntruss.com/v3/chat-completions/HCX-DASH-002
์ฑ๋ฅ ์ต์ ํ
- Token ์ฌ์ฉ๋ ์ต์ํ:
availableFiles๋ก๊ทธ๋ ์ต๋ 10๊ฐ๋ง ์ถ๋ ฅtemperature: 0.3์ผ๋ก ์ผ๊ด๋ ์๋ต ์ ๋maxTokens: 1024์ ํ
- ์๋ต ์๊ฐ ๋ชจ๋ํฐ๋ง:
const startTime = Date.now(); // ... API ํธ์ถ const duration = Date.now() - startTime; this.logger.log(`CLOVA API responded in ${duration}ms`);- Context ์ต์ ํ:
recentCommands๋ ์ต๊ทผ 3๊ฐ๋ง ์ ์ก- ํ์ผ ๋ชฉ๋ก์ด ๋๋ฌด ๋ง์ผ๋ฉด ์์ฝ