kyle8581 commited on
Commit
d900245
Β·
1 Parent(s): bab0e26
Files changed (3) hide show
  1. app.py +44 -11
  2. chat/llm_functions.py +44 -2
  3. chat/prompt.yaml +102 -5
app.py CHANGED
@@ -11,7 +11,7 @@ import gradio as gr
11
  import yaml
12
  import json
13
  import re
14
- from chat.llm_functions import get_interviewer_response, get_student_response, generate_cover_letter_response
15
  from utils import parse_json_from_response
16
  from guide_generation.llm_functions import generate_guide as create_guide_from_llm
17
  from answer_flow_generation.llm_functions import generate_answer_flow
@@ -82,6 +82,9 @@ def bot_response(history, shared_info, progress=gr.Progress()):
82
  # word_limit κΈ°λ³Έκ°’ μ„€μ • (ν˜Ήμ‹œ 없을 경우λ₯Ό λŒ€λΉ„)
83
  if 'word_limit' not in format_info:
84
  format_info['word_limit'] = 300
 
 
 
85
 
86
  history[-1][1] = ""
87
  full_response = ""
@@ -128,6 +131,9 @@ def generate_ai_reply(history, shared_info, progress=gr.Progress()):
128
  # word_limit κΈ°λ³Έκ°’ μ„€μ • (ν˜Ήμ‹œ 없을 경우λ₯Ό λŒ€λΉ„)
129
  if 'word_limit' not in format_info:
130
  format_info['word_limit'] = 300
 
 
 
131
 
132
  student_answer_json = ""
133
  history.append(["", None])
@@ -152,7 +158,7 @@ def generate_all_cover_letters(history, shared_info, progress=gr.Progress()):
152
  if not history:
153
  empty_outputs = [gr.update(value="λ©΄μ ‘ λŒ€ν™”κ°€ μ—†μŠ΅λ‹ˆλ‹€.")] * len(shared_info.get('questions', []))
154
  empty_guidelines = [gr.update(value="")] * len(shared_info.get('questions', []))
155
- return empty_outputs + empty_guidelines + [gr.update()]
156
 
157
  # history -> conversation_history ν˜•μ‹ λ³€ν™˜
158
  conversation_str = ""
@@ -169,8 +175,8 @@ def generate_all_cover_letters(history, shared_info, progress=gr.Progress()):
169
 
170
  for i, question in enumerate(shared_info.get('questions', [])):
171
  # 1단계: Answer Flow Generation
172
- progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int((i / total_questions) * 50)}% (λ‹΅λ³€ 흐름 생성 쀑...)"
173
- yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True)]
174
 
175
  flow_result, _ = generate_answer_flow(
176
  question=question,
@@ -184,8 +190,8 @@ def generate_all_cover_letters(history, shared_info, progress=gr.Progress()):
184
  guidelines[i] = flow_text # κ°€μ΄λ“œλΌμΈ μ €μž₯
185
 
186
  # 2단계: Cover Letter Response Generation
187
- progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int((i / total_questions) * 50 + 25)}% (λ‹΅λ³€ 생성 쀑...)"
188
- yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True)]
189
 
190
  full_response = ""
191
  word_limit = shared_info.get('word_limit', 300) # shared_infoμ—μ„œ word_limit κ°€μ Έμ˜€κΈ°
@@ -201,9 +207,9 @@ def generate_all_cover_letters(history, shared_info, progress=gr.Progress()):
201
  cleaned_response = clean_markdown_response(full_response)
202
  outputs[i] = cleaned_response
203
 
204
- overall_progress_val = (i + 0.75) / total_questions
205
  progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int(overall_progress_val*100)}%"
206
- yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True)]
207
 
208
  # μ΅œμ’… νŒŒμ‹± 및 정리
209
  final_data = parse_json_from_response(full_response)
@@ -216,8 +222,29 @@ def generate_all_cover_letters(history, shared_info, progress=gr.Progress()):
216
  cleaned_response = clean_markdown_response(full_response)
217
  outputs[i] = cleaned_response
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  # μ™„λ£Œ
220
- yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(visible=False)]
221
 
222
  def update_guide_and_info(company, position, jd, questions_str, word_limit):
223
  guide_json, _ = create_guide_from_llm(questions_str, jd, company, "μ‹ μž…") # experience_level is hardcoded for now
@@ -234,7 +261,8 @@ def update_guide_and_info(company, position, jd, questions_str, word_limit):
234
  "jd": jd,
235
  "questions": [q.strip() for q in questions_str.strip().split('\n') if q.strip()],
236
  "guide": guide_text,
237
- "word_limit": word_limit
 
238
  })
239
 
240
  # Return new state and update for the guide display
@@ -310,6 +338,11 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
310
  with gr.TabItem("λ‹΅λ³€ κ°€μ΄λ“œλΌμΈ"):
311
  guideline = gr.Markdown(value="κ°€μ΄λ“œλΌμΈμ΄ μƒμ„±λ˜λ©΄ 여기에 ν‘œμ‹œλ©λ‹ˆλ‹€.")
312
  guideline_outputs.append(guideline)
 
 
 
 
 
313
 
314
  # Event Handlers
315
  generate_guide_btn.click(
@@ -322,7 +355,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
322
  msg.submit(user_submit, [msg, chatbot], [msg, chatbot]).then(bot_response, [chatbot, shared_info], [chatbot, progress_display, reason_display])
323
  ai_reply_btn.click(generate_ai_reply, [chatbot, shared_info], [chatbot, progress_display, reason_display])
324
  clear_btn.click(lambda: ([], "μžκΈ°μ†Œκ°œμ„œ 완성도: 0%", ""), None, [chatbot, progress_display, reason_display], queue=False)
325
- generate_btn.click(generate_all_cover_letters, [chatbot, shared_info], cover_letter_outputs + guideline_outputs + [cover_letter_progress_display])
326
 
327
  if __name__ == "__main__":
328
  demo.launch(share=True)
 
11
  import yaml
12
  import json
13
  import re
14
+ from chat.llm_functions import get_interviewer_response, get_student_response, generate_cover_letter_response, generate_memory
15
  from utils import parse_json_from_response
16
  from guide_generation.llm_functions import generate_guide as create_guide_from_llm
17
  from answer_flow_generation.llm_functions import generate_answer_flow
 
82
  # word_limit κΈ°λ³Έκ°’ μ„€μ • (ν˜Ήμ‹œ 없을 경우λ₯Ό λŒ€λΉ„)
83
  if 'word_limit' not in format_info:
84
  format_info['word_limit'] = 300
85
+ # memory κΈ°λ³Έκ°’ μ„€μ •
86
+ if 'memory' not in format_info:
87
+ format_info['memory'] = ""
88
 
89
  history[-1][1] = ""
90
  full_response = ""
 
131
  # word_limit κΈ°λ³Έκ°’ μ„€μ • (ν˜Ήμ‹œ 없을 경우λ₯Ό λŒ€λΉ„)
132
  if 'word_limit' not in format_info:
133
  format_info['word_limit'] = 300
134
+ # memory κΈ°λ³Έκ°’ μ„€μ •
135
+ if 'memory' not in format_info:
136
+ format_info['memory'] = ""
137
 
138
  student_answer_json = ""
139
  history.append(["", None])
 
158
  if not history:
159
  empty_outputs = [gr.update(value="λ©΄μ ‘ λŒ€ν™”κ°€ μ—†μŠ΅λ‹ˆλ‹€.")] * len(shared_info.get('questions', []))
160
  empty_guidelines = [gr.update(value="")] * len(shared_info.get('questions', []))
161
+ return empty_outputs + empty_guidelines + [gr.update(), gr.update()]
162
 
163
  # history -> conversation_history ν˜•μ‹ λ³€ν™˜
164
  conversation_str = ""
 
175
 
176
  for i, question in enumerate(shared_info.get('questions', [])):
177
  # 1단계: Answer Flow Generation
178
+ progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int((i / total_questions) * 40)}% (λ‹΅λ³€ 흐름 생성 쀑...)"
179
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True), gr.update()]
180
 
181
  flow_result, _ = generate_answer_flow(
182
  question=question,
 
190
  guidelines[i] = flow_text # κ°€μ΄λ“œλΌμΈ μ €μž₯
191
 
192
  # 2단계: Cover Letter Response Generation
193
+ progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int((i / total_questions) * 40 + 30)}% (λ‹΅λ³€ 생성 쀑...)"
194
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True), gr.update()]
195
 
196
  full_response = ""
197
  word_limit = shared_info.get('word_limit', 300) # shared_infoμ—μ„œ word_limit κ°€μ Έμ˜€κΈ°
 
207
  cleaned_response = clean_markdown_response(full_response)
208
  outputs[i] = cleaned_response
209
 
210
+ overall_progress_val = (i + 0.75) / total_questions * 0.7 # 70%κΉŒμ§€λ§Œ (λ‚˜λ¨Έμ§€ 30%λŠ” memory 생성)
211
  progress_text = f"μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : {int(overall_progress_val*100)}%"
212
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True), gr.update()]
213
 
214
  # μ΅œμ’… νŒŒμ‹± 및 정리
215
  final_data = parse_json_from_response(full_response)
 
222
  cleaned_response = clean_markdown_response(full_response)
223
  outputs[i] = cleaned_response
224
 
225
+ # 3단계: Memory 생성
226
+ progress_text = "μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : 85% (λŒ€ν™” λ©”λͺ¨λ¦¬ 생성 쀑...)"
227
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True), gr.update()]
228
+
229
+ memory_content = ""
230
+ current_memory = shared_info.get('memory', '')
231
+ for chunk in generate_memory(conversation_str, current_memory):
232
+ memory_content += chunk
233
+
234
+ # Memory JSON νŒŒμ‹±
235
+ memory_text = memory_content
236
+ try:
237
+ parsed_memory = parse_json_from_response(memory_content)
238
+ if parsed_memory and 'memory' in parsed_memory:
239
+ memory_text = parsed_memory['memory']
240
+ except:
241
+ pass
242
+
243
+ progress_text = "μžκΈ°μ†Œκ°œμ„œ 생성 μ§„ν–‰λ₯ : 100% (μ™„λ£Œ)"
244
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(value=progress_text, visible=True), gr.update(value=memory_text)]
245
+
246
  # μ™„λ£Œ
247
+ yield [gr.update(value=o) for o in outputs] + [gr.update(value=g) for g in guidelines] + [gr.update(visible=False), gr.update(value=memory_text)]
248
 
249
  def update_guide_and_info(company, position, jd, questions_str, word_limit):
250
  guide_json, _ = create_guide_from_llm(questions_str, jd, company, "μ‹ μž…") # experience_level is hardcoded for now
 
261
  "jd": jd,
262
  "questions": [q.strip() for q in questions_str.strip().split('\n') if q.strip()],
263
  "guide": guide_text,
264
+ "word_limit": word_limit,
265
+ "memory": ""
266
  })
267
 
268
  # Return new state and update for the guide display
 
338
  with gr.TabItem("λ‹΅λ³€ κ°€μ΄λ“œλΌμΈ"):
339
  guideline = gr.Markdown(value="κ°€μ΄λ“œλΌμΈμ΄ μƒμ„±λ˜λ©΄ 여기에 ν‘œμ‹œλ©λ‹ˆλ‹€.")
340
  guideline_outputs.append(guideline)
341
+
342
+ # Memory ν‘œμ‹œ μ»΄ν¬λ„ŒνŠΈ
343
+ with gr.Accordion("πŸ’­ λŒ€ν™” λ©”λͺ¨λ¦¬", open=False):
344
+ gr.Markdown("λŒ€ν™” λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ μƒμ„±λœ λ©”λͺ¨λ¦¬μž…λ‹ˆλ‹€.")
345
+ memory_display = gr.Markdown(value="λŒ€ν™” λ©”λͺ¨λ¦¬κ°€ μƒμ„±λ˜λ©΄ 여기에 ν‘œμ‹œλ©λ‹ˆλ‹€.", label="λŒ€ν™” λ©”λͺ¨λ¦¬")
346
 
347
  # Event Handlers
348
  generate_guide_btn.click(
 
355
  msg.submit(user_submit, [msg, chatbot], [msg, chatbot]).then(bot_response, [chatbot, shared_info], [chatbot, progress_display, reason_display])
356
  ai_reply_btn.click(generate_ai_reply, [chatbot, shared_info], [chatbot, progress_display, reason_display])
357
  clear_btn.click(lambda: ([], "μžκΈ°μ†Œκ°œμ„œ 완성도: 0%", ""), None, [chatbot, progress_display, reason_display], queue=False)
358
+ generate_btn.click(generate_all_cover_letters, [chatbot, shared_info], cover_letter_outputs + guideline_outputs + [cover_letter_progress_display, memory_display])
359
 
360
  if __name__ == "__main__":
361
  demo.launch(share=True)
chat/llm_functions.py CHANGED
@@ -19,7 +19,8 @@ except Exception as e:
19
  prompts = {
20
  "Interviewer": "You are a job interviewer.",
21
  "Student": "You are a job applicant.",
22
- "CoverLetter": "Write a cover letter based on the conversation."
 
23
  }
24
 
25
  def get_interviewer_response(example_info):
@@ -99,4 +100,45 @@ def generate_cover_letter_response(question, conversation_history, example_info,
99
  stream=True
100
  )
101
  for chunk in response_stream:
102
- yield chunk.choices[0].delta.content or ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  prompts = {
20
  "Interviewer": "You are a job interviewer.",
21
  "Student": "You are a job applicant.",
22
+ "CoverLetter": "Write a cover letter based on the conversation.",
23
+ "Memory": "Create a memory based on the conversation history."
24
  }
25
 
26
  def get_interviewer_response(example_info):
 
100
  stream=True
101
  )
102
  for chunk in response_stream:
103
+ yield chunk.choices[0].delta.content or ""
104
+
105
+ def generate_memory(conversation_history, current_memory=""):
106
+ """
107
+ λŒ€ν™” 기둝을 λ°”νƒ•μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
108
+ """
109
+ # λŒ€ν™” 기둝을 λ¬Έμžμ—΄λ‘œ λ³€ν™˜
110
+ if isinstance(conversation_history, list):
111
+ conversation_text = "\n".join([f"{speaker}: {content}" for speaker, content in conversation_history])
112
+ else:
113
+ conversation_text = conversation_history
114
+
115
+ # Memory ν”„λ‘¬ν”„νŠΈ μ‚¬μš©
116
+ prompt = prompts.get("Memory", "").format(
117
+ conversation=conversation_text,
118
+ memory=current_memory
119
+ )
120
+
121
+ response_stream = client.chat.completions.create(
122
+ model="gpt-4o",
123
+ messages=[{"role": "user", "content": prompt}],
124
+ stream=True
125
+ )
126
+
127
+ full_response = ""
128
+ for chunk in response_stream:
129
+ chunk_content = chunk.choices[0].delta.content or ""
130
+ full_response += chunk_content
131
+ yield chunk_content
132
+
133
+ # μ΅œμ’… μ‘λ‹΅μ—μ„œ JSON νŒŒμ‹± μ‹œλ„
134
+ try:
135
+ import json
136
+ import re
137
+ json_match = re.search(r'\{.*\}', full_response, re.DOTALL)
138
+ if json_match:
139
+ parsed_data = json.loads(json_match.group())
140
+ return parsed_data.get('memory', full_response)
141
+ except:
142
+ pass
143
+
144
+ return full_response
chat/prompt.yaml CHANGED
@@ -1,4 +1,71 @@
1
  Interviewer: >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  당신은 {company_name}에 μ§€μ›ν•˜λ €λŠ” μ·¨μ—… 쀀비생과 λŒ€ν™”λ₯Ό λ‚˜λˆ„λŠ” λ©΄μ ‘ μ€€λΉ„ κ³Όμ™Έμ„ μƒλ‹˜μž…λ‹ˆλ‹€.
3
  λ‹€μŒ λŒ€ν™”λ₯Ό ν†΅ν•΄μ„œ μžκΈ°μ†Œκ°œμ„œμ— ν•„μš”ν•œ λ‚΄μš©μ„ λ„μΆœν•˜λŠ”κ²ƒμ΄ λͺ©ν‘œμž…λ‹ˆλ‹€.
4
  λ©΄μ ‘ μ€€λΉ„ κ³Όμ™Έμ„ μƒλ‹˜μ€ ν•™μƒμ˜ μžκΈ°μ†Œκ°œμ„œλ₯Ό μ™„μ„±ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ **개인 κ²½ν—˜, λ°°κ²½, 동기, κ°€μΉ˜κ΄€, 직무 μ—­λŸ‰**에 λŒ€ν•œ 정보λ₯Ό λŒ€ν™”λ₯Ό 톡해 ν•™μƒμ—κ²Œμ„œ λŒμ–΄λ‚΄μ•Ό ν•©λ‹ˆλ‹€.
@@ -25,9 +92,17 @@ Interviewer: >
25
 
26
 
27
  β˜‘οΈ μ§„ν–‰ 방식:
28
- - λ„ˆλ¬΄ λ§Žμ€ μ§ˆλ¬Έμ„ ν•œ λ²ˆμ— ν•˜μ§€ 말고, ν•˜λ‚˜μ”© μžμ—°μŠ€λŸ½κ²Œ λ¬»μŠ΅λ‹ˆλ‹€. μ§ˆλ¬Έμ€ λ°˜λ“œμ‹œ 10-15 단어 μ΄λ‚΄λ‘œ λ‹΅ν•  수 μžˆλŠ” ꡬ체적이고 μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•˜λ©°, ν•œλ²ˆμ— ν•˜λ‚˜μ˜ 질문만 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
 
 
 
 
 
 
29
  - 학생이 ꡬ체적으둜 λ‹΅ν•˜μ§€ μ•Šμ„ 경우, **후속 질문**을 톡해 더 λ§Žμ€ λ‚΄μš©μ„ μ΄λŒμ–΄λƒ…λ‹ˆλ‹€.
 
30
  - μ•„λž˜ Progressκ°€ 100이라고 예츑되면 λŒ€ν™”κ°€ μ’…λ£Œλ©λ‹ˆλ‹€.
 
31
 
32
 
33
  λŒ€ν™” μ˜ˆμ‹œ:
@@ -83,7 +158,7 @@ Interviewer: >
83
  - 닡변이 λ°”λ‘œ 생각날 수 μžˆλŠ” μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€. open-ended μ§ˆλ¬Έμ€ μ΅œλŒ€ν•œ ν”Όν•΄μ£Όμ„Έμš”. 그리고 닡변이 λ„ˆλ¬΄ 짧을땐 후속 μ§ˆλ¬Έμ„ 톡해 λ””ν…ŒμΌμ„ λŒμ–΄λ‚΄μ„Έμš”.
84
  - μžκΈ°μ†Œκ°œμ„œ λ¬Έμž₯을 λŒ€μ‹  μž‘μ„±ν•˜μ§€ λ§ˆμ„Έμš”.
85
  - μ§ˆλ¬Έμ€ λ°˜λ“œμ‹œ 15 단어 μ΄λ‚΄λ‘œ λ‹΅ν•  수 μžˆλŠ” ꡬ체적이고 μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•˜λ©°, ν•œλ²ˆμ— ν•˜λ‚˜μ˜ 질문만 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
86
- - 질문이 μΆ”μƒμ μ΄κ±°λ‚˜ μ–΄λ €μš΄ μ§ˆλ¬Έμ€ ν”Όν•˜λ˜, μ–΄μ©” 수 없을 κ²½μš°μ—λŠ” μ˜ˆμ‹œλ₯Ό ν†΅ν•΄μ„œ 닡변이 쉽도둝 λ„μ™€μ£Όμ„Έμš”.
87
  - λ‹΅λ³€κ°€μ΄λ“œμ—μ„œ λ‹€μŒ λ‚΄μš©μœΌλ‘œ λ„˜μ–΄κ°ˆλ•ŒλŠ” λŒ€ν™” 연결이 μžμ—°μŠ€λŸ½λ„λ‘ 이전 λ‚΄μš©μ— λŒ€ν•΄μ„œ 닡변이 좩뢄이 λ˜μ—ˆλŠ”μ§€ μ•Œλ €μ£ΌλŠ” 연결말을 μΆ”κ°€ν•΄μ£Όμ„Έμš”.
88
  μ˜ˆμ‹œ: μ™„λ²½μ£Όμ˜ κ°œμ„ ν•˜λ €κ³  μ–΄λ–€ λ…Έλ ₯을 ν–ˆμ–΄?
89
  user μš°μ„ μˆœμœ„ μ„€μ • μ—°μŠ΅μœΌλ‘œ μ‹€νš¨μ„± μžˆλŠ” λͺ©ν‘œ μˆ˜λ¦½μ— μ§‘μ€‘ν–ˆμŠ΅λ‹ˆλ‹€.
@@ -106,6 +181,9 @@ Interviewer: >
106
  ProgressλŠ” 0-100 μ‚¬μ΄μ˜ μ •μˆ˜λ‘œ ν‘œν˜„ν•˜μ„Έμš”.
107
  Progress = λ‚΄μš© μΆ©μ‘± ν•­λͺ© / 전체 ν•­λͺ© * 100
108
 
 
 
 
109
  λŒ€ν™” 기둝:
110
  {conversation}
111
 
@@ -113,9 +191,9 @@ Interviewer: >
113
  λ‹΅λ³€ ν˜•μ‹:
114
  ```json
115
  {{
116
- "reasoning_for_progress": "λ‹΅λ³€ μ§„ν–‰ 상황에 λŒ€ν•œ 이유 μ„€λͺ…, λ‹΅λ³€ κ°€μ΄λ“œμ˜ μ–΄λ–€ ν•­λͺ©μ΄ μ™„λ£ŒλλŠ”μ§€. (1-2λ¬Έμž₯)",
117
  "progress": λ‹΅λ³€ μ§„ν–‰ 상황 (integer, 0-100),
118
- "answer": "AI λ‹΅λ³€ (15단어 이내)",
119
  }}
120
  ```
121
 
@@ -372,4 +450,23 @@ CoverLetter: >
372
  λŒ€ν™” λ‚΄μš©: {conversation}
373
 
374
  λͺ¨λ²”λ‹΅μ•ˆ:
375
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  Interviewer: >
2
+ Role:
3
+ - 당신은 μ·¨μ—… μ€€λΉ„μƒμ˜ μžκΈ°μ†Œκ°œμ„œ μž‘μ„±μ„ λ•λŠ” **λ©΄μ ‘ μ€€λΉ„ κ³Όμ™Έ μ„ μƒλ‹˜**μž…λ‹ˆλ‹€.
4
+ - λŒ€ν™”λ₯Ό 톡해 ν•™μƒμ˜ **개인 κ²½ν—˜, 직무 κ΄€λ ¨ 동기, κ°€μΉ˜κ΄€, μ—­λŸ‰**을 ꡬ체적으둜 μ΄λŒμ–΄λ‚΄λŠ” 것이 λͺ©μ μž…λ‹ˆλ‹€.
5
+ - 학생은 μ‚¬νšŒμ΄ˆλ…„μƒ(20λŒ€ 초반)으둜, 싀무 κ²½ν—˜μ΄ λΆ€μ‘±ν•  수 μžˆμœΌλ‹ˆ λ„ˆκ·ΈλŸ½κ³  ꡬ체적으둜 μ§ˆλ¬Έν•΄μ£Όμ„Έμš”.
6
+
7
+ κΈ°μ—… 정보:
8
+ - νšŒμ‚¬λͺ…: {company_name}
9
+ - μ‚°μ—… λΆ„μ•Ό: {industry}
10
+ - λͺ¨μ§‘ 직무: {position_title}
11
+ - 핡심 μΈμž¬μƒ: {core_values} # 예: μ°½μ˜μ„±, 도전정신, ν˜‘μ—…
12
+ - κΈ°μ—… 규λͺ¨: {company_size}
13
+ - κΈ°μ—… κ΄€λ ¨ μ°Έκ³  λ³΄κ³ μ„œ: {context_report}
14
+
15
+ 학생 정보:
16
+ - 이름: {student_name}
17
+ - 전곡: {student_major}
18
+ - ν•™λ…„/μ‘Έμ—… μ—¬λΆ€: {student_status} # 예: 4ν•™λ…„, 쑸업생
19
+ - 지원 직무: {position_title}
20
+ - κ²½ν—˜ μš”μ•½: {experience_summary}
21
+
22
+ μ§„ν–‰ 방식 (β˜‘οΈ κΌ­ μ§€μΌœμ•Ό ν•  원칙):
23
+ - μ§ˆλ¬Έμ€ 항상 **ν•˜λ‚˜μ”©λ§Œ**, **15단어 이내**둜.
24
+ - λ°˜λ“œμ‹œ **ꡬ체적이고 μ‰¬μš΄ 질문**으둜 λ‹΅ν•˜κΈ° μ‰½κ²Œ λ§Œλ“€μ–΄μ•Ό 함.
25
+ - 좔상적인 μ§ˆλ¬Έμ€ ν”Όν•˜κ³ , ν•„μš”ν•œ κ²½μš°μ—λŠ” μ˜ˆμ‹œλ₯Ό λ“€μ–΄ 질문 λ§₯락을 μ œκ³΅ν•΄μ•Ό 함.
26
+ - 학생이 짧게 λ‹΅ν•˜κ±°λ‚˜ λ‘λ£¨λ­‰μˆ ν•˜κ²Œ 말할 경우, 후속 질문으둜 깊이 μžˆλŠ” λ‚΄μš©μ„ μ΄λŒμ–΄λ‚΄μ•Ό 함.
27
+ - μ§ˆλ¬Έμ„ μ΄μ–΄κ°ˆ λ•ŒλŠ” μžμ—°μŠ€λŸ¬μš΄ μ—°κ²° 말을 μΆ”κ°€ν•˜μ„Έμš”. (λ„ˆλ¬΄ "μ’‹μ•„" 만 λ°˜λ³΅ν•˜μ§€ 말고 μžμ—°μŠ€λŸ½κ²Œ λ‹€μ–‘ν•œ 말투둜 μ—°κ²°ν•΄μ£Όμ„Έμš”.)
28
+ 예: β€œμ’‹μ•„, κ·Έ μ–˜κΈ΄ μΆ©λΆ„νžˆ 된 것 κ°™μ•„. κ·ΈλŸΌβ€¦β€
29
+ - μžκΈ°μ†Œκ°œμ„œλ₯Ό 직접 μž‘μ„±ν•˜μ§€ λ§ˆμ„Έμš”. 정보 μˆ˜μ§‘λ§Œμ΄ λͺ©μ μž…λ‹ˆλ‹€.
30
+ - μ§„ν–‰λ₯ μ΄ 100이 되면 λŒ€ν™”λ₯Ό μ’…λ£Œν•˜λŠ” λ©˜νŠΈμ™€ 인사λ₯Ό ν•˜λ©° λŒ€ν™”λ₯Ό μ’…λ£Œν•΄μ£Όμ„Έμš”. (예: "λŒ€ν™” 끝!")
31
+
32
+ 쒋은 질문 μ˜ˆμ‹œ:
33
+ - β€œμ²˜μŒ μ½”λ”©ν•΄λ³Έ 게 μ–Έμ œμ•Ό?”
34
+ - β€œκ·Έλ•Œ λ§Œλ“  κ±° κΈ°μ–΅λ‚˜?”
35
+ - β€œλ­κ°€ 제일 μž¬λ°Œμ—ˆμ–΄?”
36
+ - β€œκ·Έ κ²½ν—˜μ΄ λ„ˆν•œν…Œ μ–΄λ–€ 영ν–₯을 쀬어?”
37
+ - β€œκ·Έ 이후에도 λΉ„μŠ·ν•œ κ±Έ 또 ν•΄λ΄€μ–΄?”
38
+
39
+ λͺ©ν‘œ:
40
+ - μžκΈ°μ†Œκ°œμ„œ ν•­λͺ©: {questions} # 예: 지원 동기, μ„±μž₯ κ³Όμ •, 직무 μ—­λŸ‰
41
+ - κΈ€μž 수 μ œν•œ: {word_limit}
42
+
43
+ λŒ€ν™” 흐름 κ°€μ΄λ“œ:
44
+ {guide}
45
+ μ§„ν–‰ 상황 νŒλ‹¨:
46
+ - λŒ€ν™” 흐름 κ°€μ΄λ“œλ₯Ό κΈ°μ€€μœΌλ‘œ ν•­λͺ©λ³„ λ‚΄μš©μ΄ μΆ©λΆ„νžˆ μˆ˜μ§‘λ˜μ—ˆλŠ”μ§€ νŒλ‹¨. μΆ©λΆ„νžˆ κΈ€μžμˆ˜ μ œν•œμ— 가깝에 닡변을 μ„œμˆ ν•  수 μžˆμ„ μ •λ„λ‘œ 정보가 μˆ˜μ§‘λ˜μ—ˆλŠ”μ§€ 고렀해야함.
47
+ - 각 ν•­λͺ©μ„ μΆ©μ‘±ν•œ λΉ„μœ¨μ„ 기반으둜 `progress`λ₯Ό 0~100 사이 μ •μˆ˜λ‘œ μ„€μ •.
48
+ - ν•­λͺ©μ΄ λˆ„λ½λ˜μ—ˆκ±°λ‚˜ λ‚΄μš©μ΄ 짧으면 λ°˜λ“œμ‹œ μΆ”κ°€ μ§ˆλ¬Έμ„ ν•΄μ•Ό 함.
49
+
50
+ λŒ€ν™” μ—°κ²° 방식:
51
+ - λŒ€ν™” 기둝과 이전 λ§₯락을 κΈ°μ–΅ν•˜κ³  μžμ—°μŠ€λŸ½κ²Œ μ΄μ–΄μ§ˆ 것.
52
+ - 쀑간에 μ£Όμ œκ°€ λ°”λ€Œλ©΄ β€œκ·Έ μ–˜κΈ΄ μ—¬κΈ°κΉŒμ§€ ν•˜κ³ , μ΄λ²ˆμ—”β€¦β€μ²˜λŸΌ μ—°κ²°.
53
+
54
+ 이전 λŒ€ν™” λ©”λͺ¨λ¦¬:
55
+ {memory}
56
+ λŒ€ν™” 기둝:
57
+ {conversation}
58
+
59
+
60
+ 좜λ ₯ ν˜•μ‹ (JSON):
61
+ ```json
62
+ {{
63
+ "reasoning_for_progress": "μ§„ν–‰ 상황에 λŒ€ν•œ νŒλ‹¨ μ„€λͺ… (μ–΄λ–€ ν•­λͺ©μ΄ μΆ©μ‘±λ˜μ—ˆλŠ”μ§€)",
64
+ "progress": 0~100 μ‚¬μ΄μ˜ μ •μˆ˜,
65
+ "answer": "이전 λŒ€ν™”μ— μ΄μ–΄μ§ˆ λ©΄μ ‘ νŠœν„° μ—­ν• λ‘œ ν•™μƒμ—κ²Œ 던질 μžμ—°μŠ€λŸ¬μš΄ ν•œ λ¬Έμž₯ 질문"
66
+ }}
67
+
68
+ Interviewer_old: >
69
  당신은 {company_name}에 μ§€μ›ν•˜λ €λŠ” μ·¨μ—… 쀀비생과 λŒ€ν™”λ₯Ό λ‚˜λˆ„λŠ” λ©΄μ ‘ μ€€λΉ„ κ³Όμ™Έμ„ μƒλ‹˜μž…λ‹ˆλ‹€.
70
  λ‹€μŒ λŒ€ν™”λ₯Ό ν†΅ν•΄μ„œ μžκΈ°μ†Œκ°œμ„œμ— ν•„μš”ν•œ λ‚΄μš©μ„ λ„μΆœν•˜λŠ”κ²ƒμ΄ λͺ©ν‘œμž…λ‹ˆλ‹€.
71
  λ©΄μ ‘ μ€€λΉ„ κ³Όμ™Έμ„ μƒλ‹˜μ€ ν•™μƒμ˜ μžκΈ°μ†Œκ°œμ„œλ₯Ό μ™„μ„±ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ **개인 κ²½ν—˜, λ°°κ²½, 동기, κ°€μΉ˜κ΄€, 직무 μ—­λŸ‰**에 λŒ€ν•œ 정보λ₯Ό λŒ€ν™”λ₯Ό 톡해 ν•™μƒμ—κ²Œμ„œ λŒμ–΄λ‚΄μ•Ό ν•©λ‹ˆλ‹€.
 
92
 
93
 
94
  β˜‘οΈ μ§„ν–‰ 방식:
95
+ - λ„ˆλ¬΄ λ§Žμ€ μ§ˆλ¬Έμ„ ν•œ λ²ˆμ— ν•˜μ§€ 말고, ν•˜λ‚˜μ”© μžμ—°μŠ€λŸ½κ²Œ λ¬»μŠ΅λ‹ˆλ‹€. μ§ˆλ¬Έμ€ λ°˜λ“œμ‹œ 15 단어 μ΄λ‚΄λ‘œ λ‹΅ν•  수 μžˆλŠ” ꡬ체적이고 μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•˜λ©°, ν•œλ²ˆμ— ν•˜λ‚˜μ˜ 질문만 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄μ„œ "μ•ˆλ…•! μžκΈ°μ†Œκ°œμ„œ μž‘μ„±μ— ν•„μš”ν•œ λ‚΄μš© 같이 μ–˜κΈ°ν•΄λ³΄μž. μ„±μž₯ 과정이 μ–΄λ• μ–΄?" 와 같은 μ§ˆλ¬Έμ€ λ§₯락이 μ—†κ³  ꡬ체적이지 μ•Šμ•„μ„œ 닡변이 μ–΄λ ΅μŠ΅λ‹ˆλ‹€. λ‹€μŒμ€ 쒋은 μ˜ˆμ‹œλ‘œ μ•„λž˜λ₯Ό μ°Έκ³ ν•΄μ„œ 주제λ₯Ό μ‹œμž‘ν•΄μ£Όμ„Έμš”.
96
+ - β€œμ²˜μŒμœΌλ‘œ 코딩을 ν•΄λ³Έ 게 μ–Έμ œμ˜€μ–΄?”→ κ°œλ°œμ— 관심을 κ°–κ²Œ 된 μ‹œμž‘μ μ„ λ– μ˜¬λ¦¬κ²Œ 함
97
+ - β€œκ·Έλ•Œ μ–΄λ–€ κ±Έ λ§Œλ“€μ—ˆλŠ”μ§€ κΈ°μ–΅λ‚˜?”→ ꡬ체적인 κ²½ν—˜ νšŒμƒμ„ μœ λ„ν•¨ (예: κ²Œμž„, μ›Ήμ‚¬μ΄νŠΈ, μ•± λ“±)
98
+ - β€œκ·Έκ±Έ λ§Œλ“€λ©΄μ„œ μ–΄λ–€ 점이 κ°€οΏ½οΏ½οΏ½ μž¬λ°Œμ—ˆμ–΄?”→ ν₯λ―Έ ν¬μΈνŠΈλ‚˜ λͺ°μž… μš”μ†Œλ₯Ό μžμ—°μŠ€λŸ½κ²Œ μ„€λͺ…ν•˜κ²Œ 함
99
+ - β€œκ·Έ κ²½ν—˜μ΄ λ„ˆν•œν…Œ μ–΄λ–€ 영ν–₯을 쀬닀고 생각해?”→ ν˜„μž¬μ˜ κ°œλ°œμžλ‘œμ„œμ˜ μ„±ν–₯μ΄λ‚˜ μ§„λ‘œμ™€ μ—°κ²° κ°€λŠ₯
100
+ - β€œκ·Έ 이후에도 λΉ„μŠ·ν•œ ν”„λ‘œμ νŠΈλ₯Ό 계속 ν•΄λ΄€μ–΄?”→ 지속성, μžλ°œμ„±, μ„±μž₯ 과정을 λ“œλŸ¬λ‚Ό 수 있음
101
+
102
  - 학생이 ꡬ체적으둜 λ‹΅ν•˜μ§€ μ•Šμ„ 경우, **후속 질문**을 톡해 더 λ§Žμ€ λ‚΄μš©μ„ μ΄λŒμ–΄λƒ…λ‹ˆλ‹€.
103
+ - 학생이 λŒ€ν™”μ˜ μ§„ν–‰ 상황에 λŒ€ν•΄μ„œ 인지할 수 μžˆλ„λ‘ λ‹€μŒ μ§ˆλ¬Έμ„ ν•  λ•ŒλŠ” 이전 μ§ˆλ¬Έμ— λŒ€ν•œ 닡변이 μΆ©λΆ„νžˆ λ˜μ—ˆλŠ”μ§€ μ•Œλ €μ£ΌλŠ” 연결말을 μΆ”κ°€ν•΄μ£Όμ„Έμš”.
104
  - μ•„λž˜ Progressκ°€ 100이라고 예츑되면 λŒ€ν™”κ°€ μ’…λ£Œλ©λ‹ˆλ‹€.
105
+ - λŒ€ν™” 쀑간에 μ£Όμ œκ°€ λ°”λ€ŒλŠ” λΆ€λΆ„μ—μ„œλŠ” 연결이 μžμ—°μŠ€λŸ½κ²Œ ν•΄μ£Όμ„Έμš”.
106
 
107
 
108
  λŒ€ν™” μ˜ˆμ‹œ:
 
158
  - 닡변이 λ°”λ‘œ 생각날 수 μžˆλŠ” μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€. open-ended μ§ˆλ¬Έμ€ μ΅œλŒ€ν•œ ν”Όν•΄μ£Όμ„Έμš”. 그리고 닡변이 λ„ˆλ¬΄ 짧을땐 후속 μ§ˆλ¬Έμ„ 톡해 λ””ν…ŒμΌμ„ λŒμ–΄λ‚΄μ„Έμš”.
159
  - μžκΈ°μ†Œκ°œμ„œ λ¬Έμž₯을 λŒ€μ‹  μž‘μ„±ν•˜μ§€ λ§ˆμ„Έμš”.
160
  - μ§ˆλ¬Έμ€ λ°˜λ“œμ‹œ 15 단어 μ΄λ‚΄λ‘œ λ‹΅ν•  수 μžˆλŠ” ꡬ체적이고 μ‰¬μš΄ μ§ˆλ¬Έμ΄μ–΄μ•Ό ν•˜λ©°, ν•œλ²ˆμ— ν•˜λ‚˜μ˜ 질문만 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
161
+ - 질문이 μΆ”μƒμ μ΄κ±°λ‚˜ μ–΄λ €μš΄ μ§ˆλ¬Έμ€ ν”Όν•˜λ˜, μ–΄μ©” 수 없을 κ²½μš°μ—λŠ” μ˜ˆμ‹œλ‚˜ λΆ€μ—°μ„€λͺ…을 ν†΅ν•΄μ„œ 닡변이 쉽도둝 λ„μ™€μ£Όμ„Έμš”.
162
  - λ‹΅λ³€κ°€μ΄λ“œμ—μ„œ λ‹€μŒ λ‚΄μš©μœΌλ‘œ λ„˜μ–΄κ°ˆλ•ŒλŠ” λŒ€ν™” 연결이 μžμ—°μŠ€λŸ½λ„λ‘ 이전 λ‚΄μš©μ— λŒ€ν•΄μ„œ 닡변이 좩뢄이 λ˜μ—ˆλŠ”μ§€ μ•Œλ €μ£ΌλŠ” 연결말을 μΆ”κ°€ν•΄μ£Όμ„Έμš”.
163
  μ˜ˆμ‹œ: μ™„λ²½μ£Όμ˜ κ°œμ„ ν•˜λ €κ³  μ–΄λ–€ λ…Έλ ₯을 ν–ˆμ–΄?
164
  user μš°μ„ μˆœμœ„ μ„€μ • μ—°μŠ΅μœΌλ‘œ μ‹€νš¨μ„± μžˆλŠ” λͺ©ν‘œ μˆ˜λ¦½μ— μ§‘μ€‘ν–ˆμŠ΅λ‹ˆλ‹€.
 
181
  ProgressλŠ” 0-100 μ‚¬μ΄μ˜ μ •μˆ˜λ‘œ ν‘œν˜„ν•˜μ„Έμš”.
182
  Progress = λ‚΄μš© μΆ©μ‘± ν•­λͺ© / 전체 ν•­λͺ© * 100
183
 
184
+ 이전 λŒ€ν™” λ©”λͺ¨λ¦¬:
185
+ {memory}
186
+
187
  λŒ€ν™” 기둝:
188
  {conversation}
189
 
 
191
  λ‹΅λ³€ ν˜•μ‹:
192
  ```json
193
  {{
194
+ "reasoning_for_progress": "λ‹΅λ³€ μ§„ν–‰ 상황에 λŒ€ν•œ 이유 μ„€λͺ…, λ‹΅λ³€ κ°€μ΄λ“œμ˜ μ–΄λ–€ ν•­λͺ©μ΄ μ™„λ£ŒλλŠ”μ§€. (2-3λ¬Έμž₯)",
195
  "progress": λ‹΅λ³€ μ§„ν–‰ 상황 (integer, 0-100),
196
+ "answer": "AI λ‹΅λ³€ (15-20단어 이내)",
197
  }}
198
  ```
199
 
 
450
  λŒ€ν™” λ‚΄μš©: {conversation}
451
 
452
  λͺ¨λ²”λ‹΅μ•ˆ:
453
+
454
+ Memory: >
455
+ μ£Όμ–΄μ§„ λŒ€ν™”μ˜ λ‚΄μš©μ„ μ°Έκ³ ν•΄μ„œ 이전 λŒ€ν™” μš”μ•½μ„ μž‘μ„±ν•΄μ£Όμ„Έμš”. 이전 memoryκ°€ λΉ„μ–΄μžˆλ‹€λ©΄ μƒˆλ‘œ μž‘μ„±ν•΄μ£Όμ‹œκ³ , 이전 memoryκ°€ μžˆλ‹€λ©΄ 이전 memoryλ₯Ό μ°Έκ³ ν•΄μ„œ μ—…λ°μ΄νŠΈ ν•΄μ£Όμ„Έμš”.
456
+
457
+ 좜λ ₯ ν˜•μ‹:
458
+ ```json
459
+ {{
460
+ "memory": "μƒˆλ‘œμš΄ memory λ‚΄μš©"
461
+ }}
462
+ ```
463
+
464
+ 이전 λ©”λͺ¨λ¦¬:
465
+ {memory}
466
+
467
+ λŒ€ν™” λ‚΄μš©:
468
+ {conversation}
469
+
470
+
471
+
472
+