dev-yuje commited on
Commit
495d5e7
·
1 Parent(s): 9731058

refactor: 3:7 비율 적용, 고정 브리핑 마크다운 포맷 및 가독성 최적화, 전송 버튼 다크 슬레이트 통일

Browse files
Files changed (2) hide show
  1. app.py +42 -21
  2. src/retrieval/finRetrieval.py +21 -16
app.py CHANGED
@@ -160,18 +160,18 @@ def get_db_stats() -> Dict[str, Any]:
160
  if res_techs:
161
  stats["technologies"] = res_techs["cnt"]
162
 
163
- # 2. 기술 목록 & 설명 조회 (상위 25개)
164
  res_tech_list = session.run(
165
  "MATCH (t:AITechnology) "
166
- "RETURN t.name as name, COALESCE(t.description, 'AI 혁신 기술 인프라') as desc LIMIT 25"
167
  )
168
  stats["techs_list"] = [{"name": r["name"], "desc": r["desc"]} for r in res_tech_list]
169
 
170
- # 3. 최근 기사 목록 조회 (최근 15개)
171
  res_art_list = session.run(
172
  "MATCH (a:Article) "
173
  "RETURN a.title as title, a.published_date as date, a.url as url "
174
- "ORDER BY a.published_date DESC LIMIT 15"
175
  )
176
  stats["recent_articles"] = [
177
  {"title": r["title"], "date": r["date"], "url": r["url"]}
@@ -193,7 +193,7 @@ def build_stats_html(stats: Dict[str, Any]) -> str:
193
  if not keyword_html:
194
  keyword_html = '<div style="font-size:12px; color:#94a3b8;">등록된 키워드가 없습니다.</div>'
195
 
196
- # 2. 최근 기사 리스트 HTML 생성 (최대 3개) - 전체 영역 클릭 시 이동하도록 a 태그로 래핑
197
  news_list_html: str = ""
198
  for a in stats.get("recent_articles", []):
199
  title = a["title"]
@@ -218,28 +218,49 @@ def build_stats_html(stats: Dict[str, Any]) -> str:
218
  <!-- Ambient background elements for beautiful glass effects -->
219
  <div class="ambient-glow"></div>
220
 
221
- <div style="font-size: 16px; font-weight: 850; color: #5b5b7f; margin-bottom: 2px; display: flex; align-items: center; gap: 6px; letter-spacing: -0.02em;">
222
  📊 <span>FinGraph AI Terminal</span>
223
  </div>
224
- <p style="font-size: 11px; color: #47464e; margin-top: -2px; margin-bottom: 12px; font-weight: 500;">GraphRAG 실시간 분석 엔진</p>
225
 
 
226
  <div class="stats-grid">
227
  <div class="stat-card">
228
- <div class="stat-lbl">📰 학습 기사</div>
229
- <div class="stat-val">{stats['articles']}건</div>
 
 
 
 
 
 
 
 
230
  </div>
231
  <div class="stat-card">
 
 
 
 
 
 
 
 
 
 
 
 
232
  <div class="stat-lbl">🧬 지식 노드</div>
233
- <div class="stat-val">{node_count}개</div>
234
  </div>
235
  </div>
236
 
237
- <div class="section-subtitle">💡 최신 뉴스 키워드</div>
238
  <div class="keyword-container">
239
  {keyword_html}
240
  </div>
241
 
242
- <div class="section-subtitle">📰 최신 뉴스 피드</div>
243
  <div class="news-feed-container">
244
  <div class="news-feed">
245
  {news_list_html}
@@ -511,24 +532,24 @@ body {
511
  border-color: rgba(129, 140, 248, 0.6) !important;
512
  }
513
 
514
- /* 챗봇 버튼 퍼플 포인트 스타일 (으로 보이던 현상 해결) */
515
  button.primary,
516
  .primary-btn,
517
  button.lg.primary,
518
  button.sm.primary,
519
  button.variant-primary {
520
- background-color: #5b5b7f !important;
521
  color: white !important;
522
  font-weight: 800 !important;
523
  border: none !important;
524
- box-shadow: 0 4px 6px rgba(91, 91, 127, 0.2) !important;
525
  transition: all 0.2s ease-in-out !important;
526
  }
527
  button.primary:hover,
528
  .primary-btn:hover,
529
  button.variant-primary:hover {
530
- background-color: #434466 !important;
531
- box-shadow: 0 6px 12px rgba(91, 91, 127, 0.3) !important;
532
  transform: translateY(-1px) !important;
533
  }
534
 
@@ -691,14 +712,14 @@ with gr.Blocks(**blocks_kwargs) as demo:
691
  """)
692
 
693
  with gr.Row():
694
- # 2. 왼쪽 컬럼: 사이드바 (대시보드 및 하단 메뉴) - 4:6 split을 위해 scale=4 설정
695
- with gr.Column(scale=4, min_width=350):
696
  stats_data = get_db_stats()
697
  stats_html = build_stats_html(stats_data)
698
  gr.HTML(stats_html)
699
 
700
- # 3. 오른쪽 컬럼: 메인 챗봇 에어리어 - 4:6 split을 위해 scale=6 설정
701
- with gr.Column(scale=6, min_width=500):
702
  # 메인 타이틀 (챗봇 영역 상단 중앙)
703
  gr.HTML("""
704
  <div style="text-align: center; padding: 10px 0 20px 0;">
 
160
  if res_techs:
161
  stats["technologies"] = res_techs["cnt"]
162
 
163
+ # 2. 기술 목록 & 설명 조회 (상위 8개)
164
  res_tech_list = session.run(
165
  "MATCH (t:AITechnology) "
166
+ "RETURN t.name as name, COALESCE(t.description, 'AI 혁신 기술 인프라') as desc LIMIT 8"
167
  )
168
  stats["techs_list"] = [{"name": r["name"], "desc": r["desc"]} for r in res_tech_list]
169
 
170
+ # 3. 최근 기사 목록 조회 (최근 4개)
171
  res_art_list = session.run(
172
  "MATCH (a:Article) "
173
  "RETURN a.title as title, a.published_date as date, a.url as url "
174
+ "ORDER BY a.published_date DESC LIMIT 4"
175
  )
176
  stats["recent_articles"] = [
177
  {"title": r["title"], "date": r["date"], "url": r["url"]}
 
193
  if not keyword_html:
194
  keyword_html = '<div style="font-size:12px; color:#94a3b8;">등록된 키워드가 없습니다.</div>'
195
 
196
+ # 2. 최근 기사 리스트 HTML 생성 (최대 4개) - 전체 영역 클릭 시 이동하도록 a 태그로 래핑
197
  news_list_html: str = ""
198
  for a in stats.get("recent_articles", []):
199
  title = a["title"]
 
218
  <!-- Ambient background elements for beautiful glass effects -->
219
  <div class="ambient-glow"></div>
220
 
221
+ <div style="font-size: 16px; font-weight: 850; color: #334155; margin-bottom: 2px; display: flex; align-items: center; gap: 6px; letter-spacing: -0.02em;">
222
  📊 <span>FinGraph AI Terminal</span>
223
  </div>
224
+ <p style="font-size: 11px; color: #475569; margin-top: -2px; margin-bottom: 12px; font-weight: 600;">GraphRAG 실시간 분석 엔진 상태</p>
225
 
226
+ <!-- 실시간 엔진 텔레메트리 (4개 메트릭) -->
227
  <div class="stats-grid">
228
  <div class="stat-card">
229
+ <div class="stat-lbl">💡 분석 모델</div>
230
+ <div class="stat-val" style="font-size: 13px !important; font-weight: 800 !important; color: #334155;">GPT-4o</div>
231
+ </div>
232
+ <div class="stat-card">
233
+ <div class="stat-lbl">🧬 검색 모드</div>
234
+ <div class="stat-val" style="font-size: 13px !important; font-weight: 800 !important; color: #334155;">Hybrid (Graph+Vector)</div>
235
+ </div>
236
+ <div class="stat-card">
237
+ <div class="stat-lbl">⚡ 응답 방식</div>
238
+ <div class="stat-val" style="font-size: 13px !important; font-weight: 800 !important; color: #334155;">Streaming</div>
239
  </div>
240
  <div class="stat-card">
241
+ <div class="stat-lbl">🔐 DB 연결</div>
242
+ <div class="stat-val" style="font-size: 13px !important; font-weight: 800 !important; color: #10b981;">AuraDB (Active)</div>
243
+ </div>
244
+ </div>
245
+
246
+ <!-- 수집된 데이터 규모 -->
247
+ <div class="stats-grid" style="margin-top: 10px; margin-bottom: 15px;">
248
+ <div class="stat-card" style="padding: 8px 10px;">
249
+ <div class="stat-lbl">📰 학습 기사</div>
250
+ <div class="stat-val" style="color: #334155;">{stats['articles']}건</div>
251
+ </div>
252
+ <div class="stat-card" style="padding: 8px 10px;">
253
  <div class="stat-lbl">🧬 지식 노드</div>
254
+ <div class="stat-val" style="color: #334155;">{node_count}개</div>
255
  </div>
256
  </div>
257
 
258
+ <div class="section-subtitle" style="color: #334155;">💡 최신 뉴스 키워드</div>
259
  <div class="keyword-container">
260
  {keyword_html}
261
  </div>
262
 
263
+ <div class="section-subtitle" style="color: #334155;">📰 최신 뉴스 피드</div>
264
  <div class="news-feed-container">
265
  <div class="news-feed">
266
  {news_list_html}
 
532
  border-color: rgba(129, 140, 248, 0.6) !important;
533
  }
534
 
535
+ /* 챗봇 버튼 다크 슬레이트 스타일 (보라제거 세련된 네이비/슬레이트 통일) */
536
  button.primary,
537
  .primary-btn,
538
  button.lg.primary,
539
  button.sm.primary,
540
  button.variant-primary {
541
+ background-color: #334155 !important;
542
  color: white !important;
543
  font-weight: 800 !important;
544
  border: none !important;
545
+ box-shadow: 0 4px 6px rgba(51, 65, 85, 0.15) !important;
546
  transition: all 0.2s ease-in-out !important;
547
  }
548
  button.primary:hover,
549
  .primary-btn:hover,
550
  button.variant-primary:hover {
551
+ background-color: #1e293b !important;
552
+ box-shadow: 0 6px 12px rgba(51, 65, 85, 0.25) !important;
553
  transform: translateY(-1px) !important;
554
  }
555
 
 
712
  """)
713
 
714
  with gr.Row():
715
+ # 2. 왼쪽 컬럼: 사이드바 (대시보드 및 하단 메뉴) - 3:7 split을 위해 scale=3 설정
716
+ with gr.Column(scale=3, min_width=320):
717
  stats_data = get_db_stats()
718
  stats_html = build_stats_html(stats_data)
719
  gr.HTML(stats_html)
720
 
721
+ # 3. 오른쪽 컬럼: 메인 챗봇 에어리어 - 3:7 split을 위해 scale=7 설정
722
+ with gr.Column(scale=7, min_width=500):
723
  # 메인 타이틀 (챗봇 영역 상단 중앙)
724
  gr.HTML("""
725
  <div style="text-align: center; padding: 10px 0 20px 0;">
src/retrieval/finRetrieval.py CHANGED
@@ -173,40 +173,45 @@ _prompt_template = CustomRagTemplate(
173
  template="""당신은 AI 및 핀테크 기술 트렌드 전문가이자, 취업 준비생의 역량 분석을 돕는 전략 컨설턴트입니다.
174
  반드시 아래 제공된 [컨텍스트(Neo4j 지식 그래프 검색 결과)]에 기반해서만 답변하고, 컨텍스트에 근거하지 않은 사실을 지어내거나 가상의 링크(example.com 등)를 절대 생성하지 마세요.
175
 
176
- 답변은 대중이나 취업 준비생이 실질적으로 트렌드를 깊이 있게 파악하고 자소서/면접 등에 즉각 활용할 수 있도록, 아래의 [미엄 4단계 레이아웃] 구조를 엄격히 준수하여 매우 체계적이고 깔끔한 마크다운 양식으로 정성스럽게 브리핑해 주세요.
177
 
178
- ★ [중요 - 가독성 극대화 규칙]:
179
- 결과가 빽빽하게 붙어 보이지 않도록, (###) 사이에는 무조건 빈 줄을 2줄 이상 추가하고, 개별 글머리 기호(- 및 **) 항목 사이사이에도 반드시 1줄 이상의 빈 줄(개행)을 두어 텍스트가 시각적으로 시원시원하고 쾌적하게 읽히도록 정리 작성해 주세요.
180
 
181
  ---
182
 
183
- ### 📊 [핵심 요약 트렌드 인사이트]
184
 
185
- - **한 줄 요약**: 해당 트렌드의 핵심 요점을 단 한 줄로 명료하게 요약합니다.
186
 
187
- - **주요 인사이트**: 이슈가 현재 IT/AI 및 금융 핀테크 업계 전체에 던지는 핵심 화두가 무엇인지시합니다.
188
 
 
189
 
190
- ### 🔍 [상세 이슈 및 핵심 팩트 분석]
191
 
192
- 컨텍스트를 근거로 구체적인 사실 관계를 일목요연한 글머리기호(bullet points)로 상세히 정리합니다.
193
 
194
- - 예: 이슈의 전개 과정, 련 기업 구체적 움직임, 발생하고 있는 현상(예: 전력난, 반발, 기술적 한계 등).
195
 
 
196
 
197
- ### 💡 [시사점 지원동/자소서 활용 가이드]
198
 
199
- 뉴스가 갖는 거시의미와 핀테크/금융기업 채용 준비생이 서류/면접에 활용할 있는 차별화된 전략 포트를 도출합니다.
200
 
201
- - **업계 시사점**: 기술 발전과 사회적 수용성(ESG, 인프라, 전력망 확보 등) 간의 균형적 관점 제시.
202
 
203
- - **실전 활용 Tip**: 지원동기나 면접 답변 구성 시 해당 트렌드를 어떻게 본인의 역량(예: 지속 능한 기술 기획, 신뢰받는 AI 설계 등)과 연계하여 풀어낼 수 있을지에 대한 맞춤형 가이드라인 제공.
204
 
 
205
 
206
- ### 📰 [출처 자료]
207
 
208
- - 컨텍스트에 포함된사의 실물 제목과 링크를 마크다운 링크 형식으로 투명하고 정밀 표기합니다.
209
- - 예: * [기사 제목](기사 URL) - 보도일자/언론사
 
 
 
 
210
 
211
  ---
212
 
 
173
  template="""당신은 AI 및 핀테크 기술 트렌드 전문가이자, 취업 준비생의 역량 분석을 돕는 전략 컨설턴트입니다.
174
  반드시 아래 제공된 [컨텍스트(Neo4j 지식 그래프 검색 결과)]에 기반해서만 답변하고, 컨텍스트에 근거하지 않은 사실을 지어내거나 가상의 링크(example.com 등)를 절대 생성하지 마세요.
175
 
176
+ 답변은 대중이나 취업 준비생이 실질적으로 트렌드를 깊이 있게 파악하고 자소서/면접 등에 즉각 활용할 수 있도록, 아래의 [고정 브 보고서 포맷] **토씨 하나 틀리지 않고 엄격히 준수**하여 매우 체계적이고 깔끔한 마크다운 양식으로 정성스럽게 브리핑해 주세요.
177
 
178
+ ★ [중요 - 가독성 개행 규칙]:
179
+ 각 주요 섹션(###) 사이에는 무조건 빈 줄을 2줄 이상 추가하고, 모든 개별 목록 기호(- 및 **) 항목 사이사이에도 반드시 1줄 이상의 빈 줄(개행)을 삽입하여 시각적 가독성을 극대화해 주세요.
180
 
181
  ---
182
 
183
+ # 📋 [FinGraph AI 분석 브리핑]
184
 
185
+ ### 1. 📊 한 줄 요약 & 핵심 트렌드
186
 
187
+ - ** 줄 요약**: [해당 트렌드의 핵심 요점을 한 줄로 료하게 요약]
188
 
189
+ - **주요 인사이트**: [이 이슈가 현재 IT/AI 및 금융 핀테크 업계 전체에 던지는 핵심 화두 기재]
190
 
 
191
 
192
+ ### 2. 🔍 상세 분석 팩트 정리
193
 
194
+ [컨텍스트에 기록된 실제 사실 근거로 구체적 사실을 정리]
195
 
196
+ - **이슈 전개**: [구체적인 이슈 발생 배경 및 진행 경과]
197
 
198
+ - **기업 동향**: [관련 핵심업들의 실물 비즈니스 움직임 및 대응 행보]
199
 
200
+ - **인프라/사회요인**: [전력망 부족, 중적 불안감, 하드웨어적 제약 사항 핵심 ]
201
 
 
202
 
203
+ ### 3. 💡 취업/자소서/면접 실전 가이드
204
 
205
+ [지원자가 면접이나 자기소개서에서 차별화된 통찰을 보여줄 수 있는 방법 제시]
206
 
207
+ - **금융/IT 업계 시사점**: [시적인 파급효과와 지속가능성 관점 제시]
208
 
209
+ - **실전 자소서/면접 활용 Tip**: [지원동 역량 기술서 작성 본인의 역량과 어떻게 연계 풀어낼지에 대한 맞춤 가이드]
210
+
211
+
212
+ ### 📰 4. 근거 뉴스 출처
213
+
214
+ - *[기사 제목](기사 URL)* - 보도일자/언론사
215
 
216
  ---
217