File size: 8,945 Bytes
b4c9cb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172064c
 
 
 
 
 
 
 
 
 
 
 
b4c9cb7
172064c
 
 
 
 
 
 
 
 
b4c9cb7
172064c
 
 
 
 
 
 
 
 
 
 
 
b4c9cb7
172064c
 
 
 
 
 
 
 
 
b4c9cb7
172064c
 
 
 
 
 
 
 
 
b4c9cb7
172064c
 
 
 
 
 
 
 
b4c9cb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172064c
 
 
 
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# from langchain_core.prompts import ChatPromptTemplate
# from src.config.llm import llm_2_0 as llm, llm_2_5_flash_preview
# from pydantic import BaseModel, Field
# from langchain_community.tools import DuckDuckGoSearchResults
# from langgraph.prebuilt import create_react_agent

# duckduckgo_search = DuckDuckGoSearchResults(max_results=10, output_format="json")

# script_structure_analyzer_prompt = ChatPromptTemplate.from_messages(
#     [
#         (
#             "system",
#             """
# Vai trò: Bạn là Script Structure Analyzer trong một workflow của một nhóm các agent.
# Instruction:
# - Tự động phân tích kịch bản gốc, tách các phần (Mở bài, Thân bài, Điểm chốt, CTA)
# - Xác định công thức cấu trúc (AIDA, PAS, BFB,...)
# - Trích xuất hook, câu chuyển đoạn, CTA
# - Phát hiện điểm mạnh/yếu/chỗ lạc nhịp

# Input: Script gốc
# Output:
# - Outline:
#     - Mở bài
#     - Thân bài
#     - Điểm chốt
#     - CTA
# - Công thức cấu trúc
#     - AIDA: Attention, Interest, Desire, Action
#     - PAS: Problem, Agitation, Solution
#     - BFB: Belief, Feeling, Behavior
# - Hook
# - Câu chuyển đoạn
# - CTA
# - Điểm mạnh/yếu/chỗ lạc nhịp
# """,
#         ),
#         ("user", "input script: {script}"),
#     ]
# )

# comment_insight_extractor_prompt = ChatPromptTemplate.from_messages(
#     [
#         (
#             "system",
#             """
# Vai trò: Bạn là Comment Insight Extractor trong một workflow của một nhóm các agent phân tích youtube video.
# Instruction:
# - Đọc, phân tích tất cả comment, trích xuất insight
# - lọc ra các câu hỏi lặp lại, nỗi sợ/mong muốn/lợi ích/ngôn ngữ quen thuộc
# - So sánh insight với script gốc và xác định thiếu sót.

# Input:
# - Output từ Script Structure Analyzer Agent Youtube Video
# - Comment

# Output:
# - Insights Table:
#     - Insight
#     - Original Comment
#     - Pain or Benefit
#     - Suggest for Script
# - Missing From Script
# - Repeated Questions
# - Audience Language

# """,
#         ),
#         ("user", "input comment: {comment}"),
#         (
#             "user",
#             "input script_structure_analyzer_response: {script_structure_analyzer_response}",
#         ),
#     ]
# )
# scientific_fact_finder_prompt = ChatPromptTemplate.from_messages(
#     [
#         (
#             "system",
#             """
# Vai trò: Bạn là Scientific Fact Finder trong một workflow của một nhóm các agent phân tích youtube video.
# Instruction:
# - Tự động research 3-5 nghiên cứu khoa học thực tế (PubMed, JAMA, Circulation, Nutrients…), tóm tắt số liệu, trích nguồn, gợi ý số liệu phù hợp cho từng đoạn trong script mới.
# - So sánh fact science với script gốc và xác định thiếu sót.

# Input:
# - Output từ Script Structure Analyzer Agent Youtube Video
# - Output từ Comment Insight Extractor Agent Youtube Video

# Output List:
# - Title: Tên nghiên cứu
# - Summary: Tóm tắt nghiên cứu
# - Source: Nguồn nghiên cứu
# - Relevant for Section: Relevant cho section nào trong script mới
# """,
#         ),
#         ("placeholder", "{messages}"),
#     ]
# )

# script_re_outline_prompt = ChatPromptTemplate.from_messages(
#     [
#         (
#             "system",
#             """
# Vai trò: Bạn là Script Re-Outline Agent trong một workflow của một nhóm các agent.
# Instruction:
# Kết hợp outline cũ, insight từ comment, fact từ research để lập outline mới: Hook mới, thứ tự section mới, CTA mới, các ý chuyển mạch rõ ràng, phân bổ fact/nghiên cứu vào các section.

# Input:
# - Output từ Script Structure Analyzer Agent
# - Output từ Comment Insight Extractor Agent
# - Output từ Scientific Fact Finder Agent

# Output:

# - Outline mới: (Section, summary, suggested length, facts to include)
#     - Hook mở bài
#     - Thân bài 1
#     - Thân bài 2
#     - Điểm chốt
#     - CTA
# - CTA position
# - Transitions
# - Order Logic
# """,
#         ),
#         ("placeholder", "{messages}"),
#     ]
# )

# script_writer_prompt = ChatPromptTemplate.from_messages(
#     [
#         (
#             "system",
#             """
# Vai trò: Bạn là Script Writer dựa trên các nội dung, insight được cung cấp.
# Instruction:
# - Viết lại từng phần dựa theo outline mới, dữ liệu nghiên cứu, insight comment, giữ văn liền mạch - cảm xúc - kể chuyện, format cho video YouTube (dạng văn nói, không dùng icon, chỉ text).
# - Viết theo hội thoại chỉ có một người nói, không có người khác.

# Input:
# - Output từ Script Re-Outline Agent (Important)
# - Output từ Scientific Fact Finder Agent
# - Output từ Comment Insight Extractor Agent

# Processing:
# - Sau khi viết 1 phần, ngừng ngay.
# - Output phải liền mạch, không có gạch đầu dòng.
# - Tone giọng thân thiện, kể truyện, truyền cảm xúc, không dùng icon, chỉ dùng text.
# - Cài hook cảm xúc, ví dụ thực tế
# - Kể mở ra CTA hoặc dẫn sang phần tiếp theo.
# - Có câu hỏi tu từ nhẹ nhàng
# - Nhắc lại lợi ích quan trọng
# - So sánh "thay vì... thì..." để khán giả thấy rõ "why"
# - Không dùng icon, emoji
# - Kết thúc phải là kết thúc mở đề người dùng có thể yêu cầu viết tiếp thay vì kết thúc sau khi hoàn thành đủ hook, thân bài, điểm chốt, CTA.
# Output:
# - Title: Tên của phần nội dung
# - Content: Script content

# Lưu ý:
# - Chỉ gen ra một phần nội dung.
# - Script được gen phả bám sát cấu trúc và có tính liền mạch, không được lủng củng, lăp lại nội dung.
# - Nếu user nhập 'ok, viết cho tôi phần tiếp theo, bám sát cấu trúc, số lượng từ cho mỗi mục trong outline, các công thức tạo cảm xúc và đừng quên đối tượng khán giả là người Mỹ,giới tính nữ, trên 20 tuổi, bắt đầu, trình bày thành dạng câu văn liền mạch, dùng để làm văn nói cho video YouTube, không dùng icon' thì tiếp tục viết tiếp.

# """,
#         ),
#         ("placeholder", "{messages}"),
#     ]
# )


# chain_script_structure_analyzer = script_structure_analyzer_prompt | llm
# chain_comment_insight_extractor = comment_insight_extractor_prompt | llm
# scientific_fact_agent = create_react_agent(
#     model=llm,
#     tools=[duckduckgo_search],
#     prompt=scientific_fact_finder_prompt,
# )


# chain_script_re_outline = script_re_outline_prompt | llm
# chain_script_writer = script_writer_prompt | llm_2_5_flash_preview
from langchain_core.prompts import ChatPromptTemplate
from src.config.llm import llm_2_0 as llm, llm_2_5_flash_preview
from pydantic import BaseModel, Field
from langchain_community.tools import DuckDuckGoSearchResults
from langgraph.prebuilt import create_react_agent

duckduckgo_search = DuckDuckGoSearchResults(max_results=10, output_format="json")

script_structure_analyzer_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "{prompt}",
        ),
        ("user", "input script: {script}"),
    ]
)

comment_insight_extractor_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "{prompt}",
        ),
        ("user", "input comment: {comment}"),
        (
            "user",
            "input script_structure_analyzer_response: {script_structure_analyzer_response}",
        ),
    ]
)
scientific_fact_finder_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "{prompt}",
        ),
        ("placeholder", "{messages}"),
    ]
)

script_re_outline_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "{prompt}",
        ),
        ("placeholder", "{messages}"),
    ]
)

script_writer_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "{prompt}",
        ),
        ("placeholder", "{messages}"),
    ]
)


chain_script_structure_analyzer = script_structure_analyzer_prompt | llm
chain_comment_insight_extractor = comment_insight_extractor_prompt | llm


def scientific_fact_finder_agent(prompt: str):
    prompt_template = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                "{prompt}",
            ),
            ("placeholder", "{messages}"),
        ]
    ).partial(prompt=prompt)
    return create_react_agent(
        model=llm,
        tools=[duckduckgo_search],
        prompt=prompt_template,
    )


chain_script_re_outline = script_re_outline_prompt | llm
chain_script_writer = script_writer_prompt | llm_2_5_flash_preview