File size: 5,738 Bytes
647040c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import gradio as gr
import google.generativeai as genai
from transformers import pipeline
import os
from typing import IO # ํŒŒ์ผ ํƒ€์ž… ํžŒํŠธ๋ฅผ ์œ„ํ•ด ์ถ”๊ฐ€

# Hugging Face Spaces์˜ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ์„ ๊ณ ๋ คํ•˜์—ฌ ๊ฒฝ๋Ÿ‰ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
# ํ•œ๊ตญ์–ด ์š”์•ฝ์— ํŠนํ™”๋œ ๋ชจ๋ธ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
try:
    summarizer = pipeline("summarization", model="gogamza/kobart-summarization")
except Exception as e:
    print(f"๋ชจ๋ธ ๋กœ๋”ฉ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
    summarizer = None

# Gradio 4.x์— ๋งž์ถฐ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
# progress ์ธ์ž๋ฅผ ํƒ€์ž… ํžŒํŠธ๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.
def generate_blog_post(api_key: str, file1: IO, file2: IO, file3: IO, progress: gr.Progress):
    """
    3๊ฐœ์˜ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์ž…๋ ฅ๋ฐ›์•„ ์š”์•ฝํ•˜๊ณ , Gemini API๋ฅผ ํ†ตํ•ด ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
    """
    # 1. ์ž…๋ ฅ ๊ฐ’ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ
    if not api_key:
        raise gr.Error("Google API ํ‚ค๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.")
    if not (file1 and file2 and file3):
        raise gr.Error("3๊ฐœ์˜ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ๋ชจ๋‘ ์—…๋กœ๋“œํ•ด ์ฃผ์„ธ์š”.")
    if not summarizer:
        raise gr.Error("์š”์•ฝ ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.")

    try:
        # 2. Google Gemini API ์„ค์ •
        progress(0.1, desc="Google API ํ‚ค ์„ค์ • ์ค‘...")
        genai.configure(api_key=api_key)

        # 3. ํ…์ŠคํŠธ ํŒŒ์ผ ์ฝ๊ธฐ
        progress(0.2, desc="ํ…์ŠคํŠธ ํŒŒ์ผ ์ฝ๋Š” ์ค‘...")
        texts = []
        # Gradio 4.x์—์„œ File ๊ฐ์ฒด๋Š” ์ž„์‹œ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ name ์†์„ฑ์œผ๋กœ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
        files = [file1, file2, file3]
        for f in files:
            with open(f.name, 'r', encoding='utf-8') as file:
                texts.append(file.read())

        # 4. ํ—ˆ๊น…ํŽ˜์ด์Šค ๋ชจ๋ธ๋กœ ๊ฐ ํ…์ŠคํŠธ ์š”์•ฝ
        summaries = []
        for i, text in enumerate(texts):
            progress(0.3 + i * 0.1, desc=f"๋ฌธ์„œ {i+1} ์š”์•ฝ ์ค‘...")
            summary = summarizer(text, max_length=200, min_length=50, do_sample=False)
            summaries.append(summary[0]['summary_text'])
        
        # 5. Gemini API๋กœ ์ƒˆ๋กœ์šด ๊ธ€ ์ƒ์„ฑ
        progress(0.6, desc="Gemini API๋กœ ๋ธ”๋กœ๊ทธ ์•„์›ƒ๋ผ์ธ ์ƒ์„ฑ ์ค‘...")
        model = genai.GenerativeModel('gemini-1.5-flash-latest')

        summaries_str = "\n".join([f"- ์š”์•ฝ {i+1}: {s}" for i, s in enumerate(summaries)])
        
        prompt = f"""
        ๋‹น์‹ ์€ IT ์ „๋ฌธ ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ฑฐ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜ 3๊ฐœ์˜ ์š”์•ฝ๋ฌธ์„ ์ฐธ๊ณ ํ•˜์—ฌ, ๋…์ž๋“ค์˜ ํฅ๋ฏธ๋ฅผ ๋Œ ์ˆ˜ ์žˆ๋Š” ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.

        **์ž‘์„ฑ ์กฐ๊ฑด:**
        1.  ๋จผ์ € ๊ธ€์˜ ์ „์ฒด์ ์ธ '์•„์›ƒ๋ผ์ธ'์„ ์„œ๋ก , ๋ณธ๋ก , ๊ฒฐ๋ก  ํ˜•์‹์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์‹œํ•ด ์ฃผ์„ธ์š”.
        2.  ๊ทธ ๋‹ค์Œ, ์œ„์—์„œ ์ œ์‹œํ•œ ์•„์›ƒ๋ผ์ธ์— ๋งž์ถฐ์„œ ์ „์ฒด ๊ธ€์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.
        3.  ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ ์Šคํƒ€์ผ์— ๋งž๊ฒŒ ์นœ๊ทผํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ์–ดํˆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ ์ ˆํžˆ ์ด๋ชจ์ง€๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์„ธ์š”.
        4.  SEO๋ฅผ ๊ณ ๋ คํ•˜์—ฌ '์ธ๊ณต์ง€๋Šฅ', 'AI ๊ธฐ์ˆ ', '๋ฏธ๋ž˜ ์‚ฌํšŒ', 'ํ—ˆ๊น…ํŽ˜์ด์Šค', 'Gemini API'์™€ ๊ฐ™์€ ํ‚ค์›Œ๋“œ๋ฅผ ๋ณธ๋ฌธ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํฌํ•จ์‹œ์ผœ ์ฃผ์„ธ์š”.
        5.  ์ „์ฒด ๊ธ€์ž ์ˆ˜๋Š” ๊ณต๋ฐฑ ํฌํ•จ 3,000์ž ๋‚ด์™ธ๋กœ ๋งž์ถฐ์ฃผ์„ธ์š”.
        6.  ๊ฒฐ๊ณผ๋Š” ๋งˆํฌ๋‹ค์šด ํ˜•์‹์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•ด์„œ ๋ณด์—ฌ์ฃผ์„ธ์š”.

        **[์ฐธ๊ณ ํ•  ์š”์•ฝ๋ฌธ]**
        {summaries_str}

        **[๊ฒฐ๊ณผ ์ถœ๋ ฅ ํ˜•์‹]**
        # [๋ธ”๋กœ๊ทธ ์ œ๋ชฉ]
        
        ## ๐Ÿ“ ์•„์›ƒ๋ผ์ธ
        - **์„œ๋ก **: ...
        - **๋ณธ๋ก **: ...
        - **๊ฒฐ๋ก **: ...

        ---

        ## โœ๏ธ ์™„์„ฑ๋œ ๋ธ”๋กœ๊ทธ ๊ธ€
        (์—ฌ๊ธฐ์— ์™„์„ฑ๋œ ๊ธ€์„ ์ถœ๋ ฅ)
        """

        progress(0.8, desc="Gemini API๋กœ ์ตœ์ข… ๋ธ”๋กœ๊ทธ ๊ธ€ ์ƒ์„ฑ ์ค‘...")
        response = model.generate_content(prompt)
        
        progress(1.0, desc="์™„๋ฃŒ!")
        return response.text

    except Exception as e:
        raise gr.Error(f"์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {e}")


# Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown(
        """
        # ๐Ÿค– AI ๊ธฐ๋ฐ˜ ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ์ž๋™ ์ƒ์„ฑ
        3๊ฐœ์˜ ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ  Google API ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜๋ฉด, AI๊ฐ€ ํŒŒ์ผ ๋‚ด์šฉ์„ ๋ถ„์„ํ•˜๊ณ  ์š”์•ฝํ•˜์—ฌ ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ ํ˜•์‹์˜ ์ƒˆ๋กœ์šด ๊ธ€์„ ๋งŒ๋“ค์–ด ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
        """
    )
    
    with gr.Row():
        with gr.Column(scale=1):
            api_key = gr.Textbox(
                label="Google API ํ‚ค",
                placeholder="์—ฌ๊ธฐ์— Google API ํ‚ค๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.",
                type="password",
                lines=1
            )
            file1 = gr.File(label="ํ…์ŠคํŠธ ํŒŒ์ผ 1")
            file2 = gr.File(label="ํ…์ŠคํŠธ ํŒŒ์ผ 2")
            file3 = gr.File(label="ํ…์ŠคํŠธ ํŒŒ์ผ 3")
            generate_btn = gr.Button("๐Ÿš€ ๋ธ”๋กœ๊ทธ ๊ธ€ ์ƒ์„ฑํ•˜๊ธฐ", variant="primary")

        with gr.Column(scale=2):
            output_text = gr.Markdown(label="โœจ ์ƒ์„ฑ๋œ ๋ธ”๋กœ๊ทธ ๊ธ€")

    generate_btn.click(
        fn=generate_blog_post, 
        inputs=[api_key, file1, file2, file3], 
        outputs=output_text
    )
    
    gr.Markdown(
        """
        ---
        **์‚ฌ์šฉ ๋ฐฉ๋ฒ•:**
        1.  [Google AI Studio](https://aistudio.google.com/app/apikey)์—์„œ API ํ‚ค๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์•„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
        2.  ์ฃผ์ œ๊ฐ€ ์œ ์‚ฌํ•œ 3๊ฐœ์˜ ํ…์ŠคํŠธ ํŒŒ์ผ(.txt)์„ ๊ฐ๊ฐ ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
        3.  '๋ธ”๋กœ๊ทธ ๊ธ€ ์ƒ์„ฑํ•˜๊ธฐ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ณ  ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
        4.  ์˜ค๋ฅธ์ชฝ ์ฐฝ์— ์ƒ์„ฑ๋œ ๊ธ€์˜ ์•„์›ƒ๋ผ์ธ๊ณผ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.
        """
    )

if __name__ == "__main__":
    demo.launch()