Files
aio-01d4-stu/Lecture/67/01-STAGE1-VIBE-N8N-AGENT-AND-TOOL.md

11 KiB

1단계 · 바이브 코딩으로 n8n 만들기, Agent와 Tool

  • 교시: 12교시 (09:0010:50)
  • 실습: Lab 01
  • 이 단계가 끝나면: 요청문으로 n8n 워크플로우를 만들고, push·test로 결과를 확인할 수 있다. Agent가 Tool을 써서 근거 있는 답을 하게 만들 수 있다.
flowchart LR
  A["1. 무엇이 바뀌나"] --> B["2. 워크플로우 = JSON"] --> C["3. AGENTS.md · flow.py"] --> D["4. 요청문 쓰기"] --> E["5. Agent와 Tool"] --> F["6. 그럴듯한 답 vs<br/>근거 있는 답"]

1. 무엇이 바뀌나

64·65일차에는 n8n 화면에서 노드를 끌어다 놓고, 설정 칸을 채우고, 선을 이었습니다. 66일차부터는 그 일을 CLI 코딩 에이전트가 합니다. 오늘은 그 방식을 다시 짚고, 정해진 흐름이 아닌 Agent를 만듭니다.

일 64·65일차 66일차부터
무엇을 만들지 정하기 나 나 (요청문)
노드 고르기 · 설정 · 연결 나 (마우스) 에이전트
형식 오류 찾기 실행해 보고 빨간 표시 에이전트 + flow.py check
잘 되는지 확인 눈으로 OUTPUT 보기 나 (테스트 케이스, flow.py test)
실패 원인 판단 나 나 + 에이전트

손이 하던 일은 줄고, "무엇이 맞는 결과인가"를 정하는 일이 늘어납니다. 66일차의 "결과 먼저"와 요청문 다섯 가지를 오늘도 그대로 씁니다.

2. 워크플로우는 JSON 파일이다

n8n 화면의 워크플로우를 Download하면 JSON 파일이 됩니다. 에이전트는 이 파일을 씁니다. Lab 01 예제 1의 워크플로우를 줄이면 이렇습니다.

{
  "name": "67 IT chat agent (my)",
  "nodes": [
    {"name": "IT question webhook", "type": "n8n-nodes-base.webhook", "typeVersion": 2, "parameters": {"path": "my-chat", "...": "..."}},
    {"name": "IT help agent", "type": "@n8n/n8n-nodes-langchain.agent", "typeVersion": 3.1, "parameters": {"...": "..."}},
    {"name": "OpenAI chat model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "typeVersion": 1.2, "credentials": {"openAiApi": {"id": "openAiCourse0001"}}},
    {"name": "Send answer", "type": "n8n-nodes-base.respondToWebhook", "typeVersion": 1.1, "parameters": {"...": "..."}}
  ],
  "connections": {
    "IT question webhook": {"main": [[{"node": "IT help agent", "type": "main", "index": 0}]]},
    "OpenAI chat model": {"ai_languageModel": [[{"node": "IT help agent", "type": "ai_languageModel", "index": 0}]]},
    "IT help agent": {"main": [[{"node": "Send answer", "type": "main", "index": 0}]]}
  }
}
flowchart LR
  W(["IT question webhook"]) -->|main| AG{{"IT help agent"}} -->|main| R["Send answer"]
  M["OpenAI chat model"] -.->|ai_languageModel| AG
JSON 화면에서
nodes[] 하나 노드 상자 하나
type · typeVersion 노드 종류와 버전 (버전이 틀리면 열리지 않음)
parameters 노드를 열었을 때의 설정 칸
credentials.id 고른 Credential (키 자체는 n8n 안에만 있음)
connections 선. 보내는 노드 이름 → 받는 노드 이름

3. 에이전트에게 주는 규칙과 확인 도구

3.1 AGENTS.md: 에이전트가 모르는 것을 알려 준다

CLI 에이전트는 n8n을 일반적으로는 알지만, 우리 교실의 사정은 모릅니다.

에이전트가 모르는 것 AGENTS.md에 적은 것
우리 n8n 버전에서 되는 노드 버전 실행 확인한 노드 JSON 9종 (typeVersion 포함)
데이터 API 주소 n8n 안에서는 http://data-api:8800 (localhost 아님)
Credential openAiCourse0001 id만 사용 (LLM은 OpenAI 하나), 키는 쓰지 않음
일하는 순서 my-work/에 쓰기 → check → 사람이 push·test
하지 말 것 테스트 기대 결과 바꾸기, 도구·데이터 고치기, 키 출력

codex와 agy는 AGENTS.md를, claude는 CLAUDE.md(→ @AGENTS.md)를 읽습니다. 프로젝트마다 이런 파일을 두는 것이 바이브 코딩의 첫 단계입니다.

3.2 flow.py: 만든 것을 확인하는 도구

flowchart LR
  F["my-work/x.json"] --> C["check<br/>형식 · 버전 · 연결 · 키"] --> P["push<br/>가져오기 · 게시 · 재시작"] --> T["test<br/>요청 → 기대 결과 비교"]
  T --> RPT["runs/보고서.json"]
명령 언제 수업 준비 때
check 에이전트가 파일을 쓸 때마다 (에이전트가 직접 실행) 1초 미만
push check 통과 후 (내가 실행) 약 8초
test push 후 (내가 실행) 케이스당 1~4초

push는 화면의 Import → Publish를 대신합니다. 같은 웹훅 경로를 쓰던 다른 워크플로우가 있으면 게시를 해제하고 알려 줍니다.

4. 요청문 쓰기

에이전트는 적힌 것만 압니다. 요청문에 다섯 가지를 넣습니다.

넣을 것 66일차 회의록 워크플로우에서
① 파일 my-work/meeting.json (새로 만듦)
② 입력 POST 웹훅 my-meeting, 본문의 title·notes
③ 처리 LLM이 할 일 목록을 뽑고, 담당자·기한이 없으면 미정, 할 일이 없으면 다른 길
④ 결과 모양 {"title", "summary", "count", "actions": [...], "needs_check_count"}
⑤ 기대 결과 테스트 파일 (예: weekly는 4건, empty는 400)

Lab에서는 이 다섯 가지를 내가 직접 채워 요청문을 씁니다. Lab 문서의 ▶ 가이드는 무엇을 채워야 하는지만 알려 주고, 요청문을 대신 써 주지 않습니다.

나쁜 요청문 무엇이 빠졌나
"IT 문의 챗봇 만들어 줘" 파일 · 입력 · 결과 모양 · 기대 결과 전부
"FAQ 검색도 하게 해 줘" 어느 파일을 고칠지, 결과에 무엇이 추가되는지
"테스트 통과하게 해 줘" 무엇을 바꿔야 하는지 (에이전트가 테스트를 고치려 할 수 있음)

요청문은 한 번에 한 가지 변화만 담습니다. 예제 1 → 예제 2 → 과제처럼 작게 나눠 요청하고, 매번 test로 확인합니다.

5. Agent와 Tool

5.1 정해진 흐름 vs Agent

66일차 회의록 워크플로우 오늘 IT 문의 Agent
다음에 할 일 내가 요청문으로 흐름을 정함 LLM이 질문을 보고 고름
LLM의 역할 한 칸의 일 (할 일 찾기) Tool을 고르고, 결과를 읽고, 답을 씀
좋은 점 늘 같은 순서, 예측 쉬움 질문이 다양해도 대응
조심할 점 새 경우마다 노드 추가 엉뚱한 Tool, 지어낸 답 → 테스트 필요

5.2 AI Agent 노드에 붙는 것

flowchart TB
  AG{{"AI Agent<br/>systemMessage: 역할 · 규칙"}}
  M["Chat Model<br/>gpt-4.1-mini"] -.->|ai_languageModel| AG
  T1["Tool<br/>Search FAQ"] -.->|ai_tool| AG
  AG --> O["output: 답 글자<br/>intermediateSteps: Tool 호출 기록"]
부분 하는 일 오늘
Chat Model 생각하고 답을 쓰는 LLM (Tool 호출 기능 필요) gpt-4.1-mini
Tool Agent가 부를 수 있는 기능. 설명(toolDescription) 을 보고 언제 쓸지 정함 Search FAQ → Tool 이름 Search_FAQ
systemMessage 역할과 규칙 ("Tool을 먼저 쓰고 그 결과로만 답") 에이전트가 영어로 씀
intermediateSteps 어떤 Tool을 어떤 값으로 불렀고 무엇을 받았는지 returnIntermediateSteps: true

6. 그럴듯한 답 vs 근거 있는 답 (Lab 01 예제 1 → 2)

같은 테스트(cases/lab01.json)를 두 워크플로우에 보냈습니다 (수업 준비 때, 3번씩).

예제 1 (Tool 없음) 예제 2 (Search FAQ)
결과 Passed 3/9 Passed 9/9
VPN 질문 "인터넷 연결 상태 확인, 클라이언트 업데이트, 방화벽 점검" "VPN 클라이언트를 최신 버전으로 업데이트하고 인증서 만료 여부를 확인" (FAQ-003 그대로)
비밀번호 질문 "사내 포털의 '비밀번호 찾기'… 이메일이나 휴대폰 번호로 인증" "사내 포털 로그인 화면의 '비밀번호 찾기'에서 휴대폰 인증 후" (FAQ-001)
점심 메뉴 질문 "비빔밥이나 불고기 덮밥을 추천드립니다" "회사 IT FAQ에는 점심 메뉴 추천에 관한 정보가 없습니다"

예제 1의 비밀번호 답은 우연히 거의 맞았습니다. 답 글자만 봐서는 근거가 있는지 알 수 없습니다. 그래서 테스트는 tools_used(어떤 Tool을 썼나)도 확인합니다.

7. Lab 01 과제로 이어지는 질문

"FAQ에 없으면 지어내지 말고, 쓴 FAQ 번호(sources)를 같이 주세요."

sources를 만드는 방법은 두 가지입니다. 66일차 "LLM이 할 일 vs 규칙이 할 일"을 떠올립니다.

방법 어디서 믿을 만한가
LLM에게 "답에 쓴 FAQ 번호도 써"라고 시킴 systemMessage LLM이 번호를 틀리거나 지어낼 수 있음
Tool이 돌려준 글자에서 FAQ-\d{3}를 찾음 Code 노드 (intermediateSteps) 실제로 받은 데이터만 나옴

수업 준비 때 수업 정답은 Code 노드가 Tool 결과에서 찾는 방법을, Codex는 LLM이 번호를 쓰게 하고 Code 노드가 실제로 받은 번호인지 다시 확인하는 방법을 골랐습니다. 둘 다 테스트를 통과했습니다. 에이전트가 무엇을 골랐는지 JSON을 열어 확인하는 것도 나의 일입니다.

8. 자주 하는 실수

실수 증상 고치기
요청문에 파일 이름이 없음 에이전트가 새 파일을 계속 만듦 "my-work/it-agent.json 을 고쳐 줘"로 시작
push 하지 않고 test 예전 버전이 답함 check → push → test 순서
테스트 기대 결과를 에이전트가 고침 통과했지만 의미 없음 AGENTS.md 7절. 기대 결과는 내가 정함
한 번 통과로 끝 다음 실행에서 실패 --repeat 3

9. Q

  1. 예제 1이 비밀번호 질문에 맞는 답을 했는데도 테스트가 실패한 이유는?
  2. 요청문의 다섯 가지 중 빠지면 가장 곤란한 것은 무엇이라고 생각하나요? 이유는?
  3. sources를 LLM이 쓰게 하는 것과 Code가 찾게 하는 것은 어떻게 다른가요?

정리

  • 워크플로우는 JSON 파일이고, 66일차부터 에이전트가 씁니다. 나는 요청문과 기대 결과를 쓰고, 결과를 판단합니다.
  • AGENTS.md는 에이전트가 모르는 우리 환경을 알려 주고, flow.py는 만든 것을 확인합니다.
  • Agent는 Tool을 스스로 고릅니다. 그럴듯한 답과 근거 있는 답은 Tool 호출 기록으로 구분합니다.