66일차 교안/실습 추가

This commit is contained in:
mcchae committed 2026-10-15 22:45:16 +09:00
1 parent 787d7d8514
commit d7dc9dd68a
52 files changed
+6144

No files matched your search

@@ -0,0 +1,14 @@
{
"name": "01 LLM only",
"description": "입력 → LLM → 출력. 가장 단순한 AI 워크플로우",
"inputs": ["text"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "summarize", "type": "llm",
"system": "You are a helpful assistant that writes concise Korean summaries.",
"prompt": "다음 글을 3줄 이내의 한국어로 요약해 주세요.\n\n{{input.text}}",
"mock": {"template": "(Mock 응답) 실제 LLM을 연결하면 아래 글이 3줄로 요약됩니다.\n원문: {{input.text}}"}},
{"id": "result", "type": "output", "value": "{{nodes.summarize.output}}"}
],
"edges": [["start", "summarize"], ["summarize", "result"]]
}
@@ -0,0 +1,15 @@
{
"name": "02 LLM + Tool",
"description": "Tool이 가져온 데이터를 LLM이 근거로 사용해 답변",
"inputs": ["city", "question"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "weather", "type": "tool", "tool": "get_weather", "args": {"city": "{{input.city}}"}},
{"id": "answer", "type": "llm",
"system": "Answer only from the given weather data. Reply in Korean.",
"prompt": "날씨 데이터: {{nodes.weather.output}}\n질문: {{input.question}}",
"mock": {"template": "{{nodes.weather.output.city}}의 오늘 날씨는 {{nodes.weather.output.condition}}, 기온 {{nodes.weather.output.temp_c}}도, 강수 확률 {{nodes.weather.output.rain_chance}}%입니다."}},
{"id": "result", "type": "output", "value": "{{nodes.answer.output}}"}
],
"edges": [["start", "weather"], ["weather", "answer"], ["answer", "result"]]
}
@@ -0,0 +1,12 @@
{
"name": "03 Save profile to memory",
"description": "사용자 선호를 Memory에 저장 (다음 실행에서 다시 사용)",
"inputs": ["user", "preference"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "remember", "type": "memory_write", "key": "user:{{input.user}}",
"value": {"preference": "{{input.preference}}"}},
{"id": "result", "type": "output", "value": {"saved_for": "{{input.user}}", "memory": "{{nodes.remember.output}}"}}
],
"edges": [["start", "remember"], ["remember", "result"]]
}
@@ -0,0 +1,19 @@
{
"name": "04 LLM + Tool + Memory",
"description": "Memory(선호) + Tool(날씨) → LLM 추천 → Memory(방문 기록) 갱신",
"inputs": ["user", "city"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "recall", "type": "memory_read", "key": "user:{{input.user}}"},
{"id": "weather", "type": "tool", "tool": "get_weather", "args": {"city": "{{input.city}}"}},
{"id": "recommend", "type": "llm",
"system": "You are a travel assistant. Use the user's memory and the weather. Reply in Korean, 2 sentences.",
"prompt": "사용자 기억: {{nodes.recall.output}}\n날씨: {{nodes.weather.output}}\n오늘 {{input.city}}에서 할 일을 추천해 주세요.",
"mock": {"template": "{{input.user}}님은 '{{nodes.recall.output.preference}}'을(를) 좋아하시죠. {{input.city}}은(는) 오늘 {{nodes.weather.output.condition}}이니 그에 맞는 일정을 추천합니다."}},
{"id": "remember", "type": "memory_write", "key": "user:{{input.user}}",
"value": {"last_city": "{{input.city}}", "last_recommendation": "{{nodes.recommend.output}}"}},
{"id": "result", "type": "output", "value": "{{nodes.recommend.output}}"}
],
"edges": [["start", "recall"], ["start", "weather"], ["recall", "recommend"], ["weather", "recommend"],
["recommend", "remember"], ["remember", "result"]]
}
@@ -0,0 +1,30 @@
{
"name": "05 Tech support ticket",
"description": "업무 자동화 시나리오: 문의 접수 → 분류 → FAQ 검색 → 답변 초안 → 이력 저장",
"inputs": ["user", "ticket"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "history", "type": "memory_read", "key": "ticket:{{input.user}}"},
{"id": "classify", "type": "llm",
"system": "Classify the ticket into one of: account, network, device, software, other. Reply with the label only.",
"prompt": "문의: {{input.ticket}}",
"mock": {"rules": [
{"if_contains": ["비밀번호", "계정", "로그인", "잠김"], "then": "account"},
{"if_contains": ["vpn", "인터넷", "와이파이", "접속"], "then": "network"},
{"if_contains": ["프린터", "모니터", "키보드"], "then": "device"},
{"if_contains": ["설치", "프로그램", "메일"], "then": "software"}
], "default": "other"}},
{"id": "faq", "type": "tool", "tool": "search_faq", "args": {"query": "{{input.ticket}}", "top_k": 2}},
{"id": "draft", "type": "llm",
"system": "Write a polite Korean reply using only the FAQ results. Mention the FAQ id.",
"prompt": "문의: {{input.ticket}}\n분류: {{nodes.classify.output}}\n이전 문의: {{nodes.history.output}}\nFAQ 검색 결과: {{nodes.faq.output}}",
"mock": {"template": "안녕하세요 {{input.user}}님. 문의하신 내용은 [{{nodes.faq.output.0.title}}]에 해당합니다. {{nodes.faq.output.0.answer}} (참고: {{nodes.faq.output.0.id}})"}},
{"id": "log", "type": "memory_write", "key": "ticket:{{input.user}}",
"value": {"last_ticket": "{{input.ticket}}", "last_category": "{{nodes.classify.output}}"}},
{"id": "result", "type": "output",
"value": {"category": "{{nodes.classify.output}}", "faq_id": "{{nodes.faq.output.0.id}}", "reply": "{{nodes.draft.output}}"}}
],
"edges": [["start", "history"], ["start", "classify"], ["start", "faq"],
["history", "draft"], ["classify", "draft"], ["faq", "draft"],
["draft", "log"], ["log", "result"]]
}
@@ -0,0 +1,38 @@
{
"name": "06 Request flow with condition",
"description": "Trigger(입력) → 분류·FAQ 검색 → Condition(FAQ 있음?) → Action(자동 답변 또는 담당자 전달)",
"inputs": ["user", "text"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "history", "type": "memory_read", "key": "request:{{input.user}}"},
{"id": "classify", "type": "llm",
"system": "Classify the IT request into exactly one of: account, network, device, software, other. Reply with the label only.",
"prompt": "문의: {{input.text}}",
"mock": {"rules": [
{"if_contains": ["비밀번호", "계정", "로그인", "잠김", "잠겨"], "then": "account"},
{"if_contains": ["vpn", "인터넷", "와이파이", "접속"], "then": "network"},
{"if_contains": ["프린터", "모니터", "키보드"], "then": "device"},
{"if_contains": ["설치", "프로그램", "메일"], "then": "software"}
], "default": "other"}},
{"id": "faq", "type": "tool", "tool": "search_faq", "args": {"query": "{{input.text}}", "top_k": 1}},
{"id": "log", "type": "memory_write", "key": "request:{{input.user}}",
"value": {"last_text": "{{input.text}}", "last_category": "{{nodes.classify.output}}"}},
{"id": "has_faq", "type": "condition", "check": {"left": "{{nodes.faq.output}}", "op": "not_empty"}},
{"id": "draft", "type": "llm",
"system": "Write a polite 2-sentence Korean reply using only the FAQ answer. End with the FAQ id in parentheses.",
"prompt": "문의: {{input.text}}\n이전 문의: {{nodes.history.output}}\nFAQ: {{nodes.faq.output}}",
"mock": {"template": "{{input.user}}님, {{nodes.faq.output.0.answer}} ({{nodes.faq.output.0.id}})"}},
{"id": "auto_reply", "type": "output",
"value": {"category": "{{nodes.classify.output}}", "faq_id": "{{nodes.faq.output.0.id}}", "route": "자동 답변", "reply": "{{nodes.draft.output}}"}},
{"id": "hand_off", "type": "output",
"value": {"category": "{{nodes.classify.output}}", "faq_id": "", "route": "담당자 확인", "reply": "관련 안내를 찾지 못해 담당자가 확인 후 답변드리겠습니다."}}
],
"edges": [
["start", "history"], ["start", "classify"], ["start", "faq"],
["classify", "log"],
["faq", "has_faq"], ["classify", "has_faq"],
["has_faq", "draft", "true"], ["history", "draft"],
["draft", "auto_reply"],
["has_faq", "hand_off", "false"]
]
}
@@ -0,0 +1,29 @@
{
"name": "07 Route by category",
"description": "LLM 분류 결과로 Switch 분기 → 담당 팀 배정 (정해진 값이 아니면 default)",
"inputs": ["text"],
"nodes": [
{"id": "start", "type": "input"},
{"id": "classify", "type": "llm",
"system": "Classify the IT request into exactly one of: account, network, device, software, other. Reply with the label only.",
"prompt": "문의: {{input.text}}",
"mock": {"rules": [
{"if_contains": ["비밀번호", "계정", "로그인", "잠김", "잠겨"], "then": "account"},
{"if_contains": ["vpn", "인터넷", "와이파이", "접속"], "then": "network"},
{"if_contains": ["프린터", "모니터", "키보드"], "then": "device"},
{"if_contains": ["설치", "프로그램", "메일"], "then": "software"}
], "default": "other"}},
{"id": "route", "type": "switch", "value": "{{nodes.classify.output}}", "cases": ["account", "network", "device", "software"]},
{"id": "team_account", "type": "output", "value": {"category": "account", "team": "계정 관리 담당"}},
{"id": "team_network", "type": "output", "value": {"category": "network", "team": "네트워크 담당"}},
{"id": "team_device", "type": "output", "value": {"category": "device", "team": "장비 지원 담당"}},
{"id": "team_software", "type": "output", "value": {"category": "software", "team": "소프트웨어 담당"}},
{"id": "team_default", "type": "output", "value": {"category": "{{nodes.classify.output}}", "team": "IT 문의 접수 창구"}}
],
"edges": [
["start", "classify"], ["classify", "route"],
["route", "team_account", "account"], ["route", "team_network", "network"],
["route", "team_device", "device"], ["route", "team_software", "software"],
["route", "team_default", "default"]
]
}
@@ -0,0 +1,168 @@
{
"name": "08 Meeting notes to action items",
"description": "회의록 → (병렬) 할 일 추출·요약 → 할 일이 있으면 정리, 없으면 '할 일 없음'",
"inputs": [
"title",
"notes"
],
"nodes": [
{
"id": "start",
"type": "input"
},
{
"id": "has_notes",
"type": "condition",
"check": {
"left": "{{input.notes}}",
"op": "not_empty"
}
},
{
"id": "extract",
"type": "llm",
"system": "Extract action items from the meeting notes. Answer in JSON: {\"actions\": [{\"task\": str, \"owner\": str, \"due\": str}]}. Write task in Korean. Use \"미정\" when the owner or due date is not stated. Return {\"actions\": []} when there is no action item.",
"prompt": "회의록:\n{{input.notes}}",
"temperature": 0,
"json_schema": {
"type": "object",
"properties": {
"actions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"task": {
"type": "string"
},
"owner": {
"type": "string"
},
"due": {
"type": "string"
}
},
"required": [
"task",
"owner",
"due"
]
}
}
},
"required": [
"actions"
]
},
"mock": {
"rules": [
{
"if_contains": [
"결정 사항은 없습니다"
],
"then": "{\"actions\": []}"
}
],
"default": "{\"actions\": [{\"task\": \"신규 고객 문의 응답 템플릿 정리\", \"owner\": \"이준호\", \"due\": \"금요일\"}, {\"task\": \"VPN 장애 보고서 작성\", \"owner\": \"박서연\", \"due\": \"다음 주 월요일\"}, {\"task\": \"서버 점검 일정 공지\", \"owner\": \"김민지\", \"due\": \"오늘\"}, {\"task\": \"회의실 예약 규칙 개선 담당자 지정\", \"owner\": \"\", \"due\": \"\"}]}"
}
},
{
"id": "parse",
"type": "tool",
"tool": "parse_actions",
"args": {
"text": "{{nodes.extract.output}}"
}
},
{
"id": "summarize",
"type": "llm",
"system": "You summarize meeting notes. Reply only with the summary in Korean, at most 2 sentences. No English, no comments.",
"prompt": "다음 회의록을 요약하세요.\n\n회의록:\n{{input.notes}}",
"mock": {
"template": "(Mock 요약) {{input.title}}의 주요 내용을 정리했습니다."
}
},
{
"id": "any_actions",
"type": "condition",
"check": {
"left": "{{nodes.parse.output.count}}",
"op": "gt",
"right": 0
}
},
{
"id": "report",
"type": "output",
"value": {
"title": "{{input.title}}",
"route": "할 일 정리",
"count": "{{nodes.parse.output.count}}",
"summary": "{{nodes.summarize.output}}",
"actions": "{{nodes.parse.output.actions}}"
}
},
{
"id": "no_actions",
"type": "output",
"value": {
"title": "{{input.title}}",
"route": "할 일 없음",
"count": 0,
"summary": "{{nodes.summarize.output}}",
"actions": []
}
},
{
"id": "reject",
"type": "output",
"value": {
"error": "notes is required"
}
}
],
"edges": [
[
"start",
"has_notes"
],
[
"has_notes",
"extract",
"true"
],
[
"has_notes",
"summarize",
"true"
],
[
"has_notes",
"reject",
"false"
],
[
"extract",
"parse"
],
[
"parse",
"any_actions"
],
[
"summarize",
"any_actions"
],
[
"any_actions",
"report",
"true"
],
[
"any_actions",
"no_actions",
"false"
]
]
}