Yasu777 commited on
Commit
cf95eb1
·
verified ·
1 Parent(s): c607608

Update article_generator.py

Browse files
Files changed (1) hide show
  1. article_generator.py +168 -200
article_generator.py CHANGED
@@ -47,105 +47,46 @@ class EnhancedTavilySearchTool:
47
  else:
48
  raise Exception(f"Failed to fetch data from Tavily API: {response.status_code}, {response.text}")
49
 
50
- # 実行された指示追跡するリスト
51
- executed_instructions = []
52
- # 調査結果を保存するリスト
53
- research_results = []
54
-
55
- # 生成状態を保存するファイル
56
- state_file = "state.json"
57
-
58
- # 状態を保存する関数
59
- def save_state(state):
60
- with open(state_file, "w", encoding="utf-8") as f:
61
- json.dump(state, f, ensure_ascii=False, indent=4)
62
- print("State saved. Current index:", state.get('current_index', 'Not available')) # インデックス情報をログに出力
63
-
64
- # 状態をロードする関数
65
- def load_state():
66
- if os.path.exists(state_file):
67
- with open(state_file, "r", encoding="utf-8") as f:
68
- state = json.load(f)
69
- print("State loaded. Current index:", state.get('current_index', 'Not available')) # インデックス情報をログに出力
70
- return state
71
- print("No state file found.")
72
- return None
73
-
74
- # 状態をクリアする関数
75
- def clear_state():
76
- if os.path.exists(state_file):
77
- os.remove(state_file)
78
- global executed_instructions, research_results
79
- executed_instructions = []
80
- research_results = []
81
- print("State cleared.")
82
- return "状態がクリアされました"
83
-
84
- # 見出しを処理する関数
85
- def process_heading(agent, h2_text, h3_for_this_h2, cached_responses):
86
- query = f"{h2_text} {' '.join(h3_for_this_h2)}"
87
- if query in cached_responses:
88
- return (query, cached_responses[query])
89
- else:
90
- return (query, "No cached response found for this heading.")
91
-
92
- # 初期データをTavily検索で収集する関数
93
- def perform_initial_tavily_search(h2_texts, h3_texts):
94
- tavily_search_tool = EnhancedTavilySearchTool()
95
- queries = []
96
-
97
- for idx, h2_text in enumerate(h2_texts): # インデックスの取得方法を改善
98
- h3_for_this_h2 = [h3 for h3 in h3_texts if h3.startswith(f"{idx+1}-")]
99
- query = f"{h2_text} {' '.join(h3_for_this_h2)}"
100
- queries.append(query)
101
-
102
- print("Performing Tavily search with queries:", queries) # デバッグ情報追加
103
- response = tavily_search_tool.search(queries)
104
- return {query: response[i] for i, query in enumerate(queries)}
105
-
106
- # キャッシュされたTavilyデータを保存する関数
107
- def save_preloaded_tavily_data(data):
108
- with open("preloaded_tavily_data.json", "w", encoding="utf-8") as f:
109
- json.dump(data, f, ensure_ascii=False, indent=4)
110
- print("Preloaded Tavily data saved.")
111
-
112
- # キャッシュされたTavilyデータをロードする関数
113
- def load_preloaded_tavily_data():
114
- with open("preloaded_tavily_data.json", "r", encoding="utf-8") as f:
115
- print("Preloaded Tavily data loaded.")
116
- return json.load(f)
117
-
118
- # PlanAndExecuteエージェントをセットアップする関数
119
- def setup_plan_and_execute_agent():
120
- google_search_tool = Tool(
121
- name="GoogleSearch",
122
- func=GoogleSearchTool().search,
123
- description="Search tool using Google API"
124
- )
125
 
126
- tools = [google_search_tool]
127
-
128
- model_name = "gpt-3.5-turbo-0125"
129
- llm = ChatOpenAI(model_name=model_name, temperature=0, max_tokens=1000)
130
- planner = load_chat_planner(llm)
131
- executor = load_agent_executor(llm, tools, verbose=True)
 
 
 
 
132
 
133
- agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
134
- print("PlanAndExecute agent setup complete.")
135
- return agent
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- # GPT-4を使用してテキストを生成するヘルパー関数
138
- def generate_text_with_gpt4(prompt):
139
- response = openai.ChatCompletion.create(
140
- model="gpt-4o",
141
- messages=[{"role": "system", "content": "以下についての詳細な情報をまとめ、適宜箇所書き、もしくは表を使ってオリジナルの内容にしてください。"},
142
- {"role": "user", "content": prompt}],
143
- temperature=0.7,
144
- max_tokens=500
145
- )
146
- return response.choices[0]["message"]["content"].strip()
147
 
148
- # 記事のセクションをGPT-4で拡張する関数
149
  def expand_section_with_gpt4(h2_text, h3_texts, preloaded_data):
150
  prompts = []
151
  h3_to_text = {}
@@ -170,7 +111,10 @@ def expand_section_with_gpt4(h2_text, h3_texts, preloaded_data):
170
  with ThreadPoolExecutor(max_workers=max(1, len(prompts))) as executor:
171
  future_to_prompt = {executor.submit(generate_text_with_gpt4, prompt): h3_text for prompt, h3_text in zip(prompts, h3_texts)}
172
  for future in as_completed(future_to_prompt):
173
- h3_text = future_to_prompt[future]
 
 
 
174
  try:
175
  expanded_text = future.result()
176
  expanded_texts.append(expanded_text)
@@ -197,7 +141,17 @@ def process_standalone_h2(soup):
197
  new_paragraph.string = expanded_text
198
  h2.insert_after(new_paragraph)
199
 
200
- def generate_expanded_article(article_html, h3_to_text):
 
 
 
 
 
 
 
 
 
 
201
  print("記事を拡張中...")
202
  soup = BeautifulSoup(article_html, 'html.parser')
203
  process_standalone_h2(soup) # 独立した<h2>セクションを処理
@@ -212,18 +166,95 @@ def generate_expanded_article(article_html, h3_to_text):
212
  if h3.get_text() in h3_to_text:
213
  new_paragraph = soup.new_tag('p')
214
  new_paragraph.string = h3_to_text[h3.get_text()]
215
- h3.insert_after(new_paragraph)
 
 
 
 
 
 
 
 
 
 
216
 
217
  return str(soup)
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  # 記事を生成する関数
220
  def generate_article(editable_output2):
221
  print("Starting article generation...")
222
- # 途中から再開する場合のために状態を読み込み
223
- state = load_state() or {'executed_instructions': [], 'research_results': [], 'current_index': 0}
224
- executed_instructions = state['executed_instructions']
225
- research_results = state['research_results']
226
- current_index = state['current_index']
227
 
228
  # エージェントのセットアップ
229
  agent = setup_plan_and_execute_agent()
@@ -239,6 +270,9 @@ def generate_article(editable_output2):
239
  cached_responses = perform_initial_tavily_search(h2_texts, h3_texts)
240
  save_preloaded_tavily_data(cached_responses)
241
 
 
 
 
242
  with ThreadPoolExecutor(max_workers=5) as executor:
243
  futures = []
244
  for h2_text in h2_texts:
@@ -250,43 +284,43 @@ def generate_article(editable_output2):
250
  if purpose not in executed_instructions:
251
  executed_instructions.append(purpose)
252
  research_results.append(response)
253
- save_state({'executed_instructions': executed_instructions, 'research_results': research_results, 'current_index': h2_texts.index(h2_text) + 1})
254
 
255
  print("Tavily search complete.")
256
 
257
  system_message = {
258
  "role": "system",
259
- "content": "あなたはプロのライターです。すべての回答を日本語でお願いします。"
260
  }
261
 
262
  research_summary = "\n".join([json.dumps(result) for result in research_results])
263
  instructions = []
264
 
 
265
  instructions.append(f"""
266
- <h1>{h1_text}</h1>
267
- "{h1_text}"に関する導入文を日本語で作成してください。直接的なコピーまたは近いフレーズを避けて、オリジナルな内容にしてください。""")
268
 
269
  sentences = research_summary.split('。')
270
-
271
- # 質問の数を制限
272
  max_questions_per_h3 = 2
273
 
274
  for idx, h2_text in enumerate(h2_texts):
275
  h3_for_this_h2 = [h3 for h3 in h3_texts if h3.startswith(f"{idx+1}-")]
276
  instructions.append(f"""
277
- <h2>{h2_text}</h2>
278
- "{h2_text}"に関する導入文を日本語で作成してください。この導入文は、以下の小見出しの内容を考慮してください:{"、".join(h3_for_this_h2)}。直接的なコピーまたは近いフレーズを避けて、オリジナルな内容にしてください。""")
279
- for h3 in h3_for_this_h2:
 
280
  related_sentences = [sentence for sentence in sentences if h3 in sentence][:max_questions_per_h3]
281
  if related_sentences:
282
  content_for_h3 = "。".join(related_sentences) + "。"
283
  instructions.append(f"""
284
- <h3>{h3}</h3>
285
- "{h3}"に関する詳細な内容として、以下の情報を日本語で記述してください:{content_for_h3} ここでも、オリジナルな内容を心がけてください。""")
286
  else:
287
  instructions.append(f"""
288
- <h3>{h3}</h3>
289
- "{h3}"に関する詳細な内容を日本語で記述してください。オリジナルな内容を心がけてください。""")
 
290
 
291
  # トークン数を制限するためにメッセージを分割
292
  split_instructions = []
@@ -316,99 +350,33 @@ def generate_article(editable_output2):
316
  messages=[system_message, user_message],
317
  temperature=0.7,
318
  )
319
- results.append(response.choices[0]["message"]["content"])
 
 
 
320
  except Exception as e:
321
  error_message = f"Error occurred during ChatCompletion: {str(e)}"
322
  print(error_message) # ログにエラーメッセージを出力
323
  results.append(error_message)
324
- # 途中で止まった場合の状態を保存
325
- save_state({
326
- "executed_instructions": executed_instructions,
327
- "research_results": research_results,
328
- "split_instructions": split_instructions,
329
- "results": results,
330
- "current_index": i + 1
331
- })
332
- return error_message
333
 
334
  final_result = "\n".join(results)
 
 
335
 
336
- # 生成された初期記事を拡張
337
- h3_to_text = expand_section_with_gpt4(final_result, h3_texts, cached_responses)
338
- expanded_article = generate_expanded_article(final_result, h3_to_text)
339
-
340
- with open("output3.txt", "w", encoding="utf-8") as f:
341
- f.write(expanded_article)
342
-
343
- print("Article generation complete. Output saved to output3.txt.")
344
- print(expanded_article) # ログに最終結果を出力
345
-
346
- # 生成が完了したら状態ファイルを削除
347
- if os.path.exists("state.json"):
348
- os.remove("state.json")
349
- print("State file removed.")
350
-
351
- return expanded_article
352
-
353
- def continue_generate_article():
354
- print("Continuing article generation...")
355
- state = load_state()
356
- if not state:
357
- return "再開する状態がありません。"
358
-
359
- executed_instructions = state.get("executed_instructions", [])
360
- research_results = state.get("research_results", [])
361
- split_instructions = state.get("split_instructions", [])
362
- results = state.get("results", [])
363
- current_index = state.get("current_index", 0)
364
-
365
- system_message = {
366
- "role": "system",
367
- "content": "あなたはプロのライターです。すべての回答を日本語でお願いします。"
368
- }
369
-
370
- for i in range(current_index, len(split_instructions)):
371
- user_message = {
372
- "role": "user",
373
- "content": f"{i+1}/{len(split_instructions)}: {split_instructions[i]}"
374
- }
375
- try:
376
- print(f"Sending instruction chunk {i+1} of {len(split_instructions)} to GPT-4...")
377
- response = openai.ChatCompletion.create(
378
- model="gpt-4-turbo",
379
- messages=[system_message, user_message],
380
- temperature=0.7,
381
- )
382
- results.append(response.choices[0]["message"]["content"])
383
- except Exception as e:
384
- error_message = f"Error occurred during ChatCompletion: {str(e)}"
385
- print(error_message) # ログにエラーメッセージを出力
386
- results.append(error_message)
387
- # 途中で止まった場合の状態を保存
388
- save_state({
389
- "executed_instructions": executed_instructions,
390
- "research_results": research_results,
391
- "split_instructions": split_instructions,
392
- "results": results,
393
- "current_index": i + 1
394
- })
395
- return error_message
396
 
397
- final_result = "\n".join(results)
 
 
 
398
 
399
- # 生成された初期記事を拡張
400
- h3_to_text = expand_section_with_gpt4(final_result, h3_texts, cached_responses)
401
- expanded_article = generate_expanded_article(final_result, h3_to_text)
402
 
 
403
  with open("output3.txt", "w", encoding="utf-8") as f:
404
- f.write(expanded_article)
405
-
406
- print("Article continuation complete. Output saved to output3.txt.")
407
- print(expanded_article) # ログに最終結果を出力
408
 
409
- # 生成が完了したら状態ファイルを削除
410
- if os.path.exists("state.json"):
411
- os.remove("state.json")
412
- print("State file removed.")
413
-
414
- return expanded_article
 
47
  else:
48
  raise Exception(f"Failed to fetch data from Tavily API: {response.status_code}, {response.text}")
49
 
50
+ # 重複排除するヘルパー関数
51
+ def remove_duplicates(text_list):
52
+ seen = set()
53
+ result = []
54
+ for text in text_list:
55
+ if text not in seen:
56
+ seen.add(text)
57
+ result.append(text)
58
+ return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ # 記事のセクションをGPT-4で拡張する関数
61
+ def expand_h3_sections(soup, preloaded_data):
62
+ h3_elements = soup.find_all('h3')
63
+ for h3 in h3_elements:
64
+ h3_text = h3.get_text(strip=True)
65
+ section_id = h3.get('id', None)
66
+ if section_id is None:
67
+ print(f"Warning: h3 element '{h3_text}' has no ID.")
68
+ continue
69
+ key = f"{h3_text} {section_id}"
70
 
71
+ if key in preloaded_data:
72
+ context = preloaded_data[key]
73
+ prompt = f"「{h3_text}」に続ける文章を生成してください。こちらが背景情報です:\n{context}"
74
+ else:
75
+ prompt = f"「{h3_text}」に続ける文章を生成してください。"
76
+
77
+ expanded_text = generate_text_with_gpt4(prompt)
78
+ new_paragraph = soup.new_tag('p')
79
+ new_paragraph.string = expanded_text
80
+
81
+ # h3タグの次の要素を取得し、その後の要素を探す
82
+ next_sibling = h3.find_next_sibling()
83
+ if next_sibling:
84
+ next_sibling.insert_after(new_paragraph) # 次の要素が存在する場合のみ挿入を行う
85
+ else:
86
+ h3.parent.append(new_paragraph) # h3タグの親が存在する場合、親���直接追加
87
 
88
+ return soup
 
 
 
 
 
 
 
 
 
89
 
 
90
  def expand_section_with_gpt4(h2_text, h3_texts, preloaded_data):
91
  prompts = []
92
  h3_to_text = {}
 
111
  with ThreadPoolExecutor(max_workers=max(1, len(prompts))) as executor:
112
  future_to_prompt = {executor.submit(generate_text_with_gpt4, prompt): h3_text for prompt, h3_text in zip(prompts, h3_texts)}
113
  for future in as_completed(future_to_prompt):
114
+ h3_text = future_to_prompt.get(future)
115
+ if h3_text is None:
116
+ print("Error: Future not found in future_to_prompt")
117
+ continue
118
  try:
119
  expanded_text = future.result()
120
  expanded_texts.append(expanded_text)
 
141
  new_paragraph.string = expanded_text
142
  h2.insert_after(new_paragraph)
143
 
144
+ def process_summary_section(soup, cached_responses):
145
+ summary_section = soup.find('h2', text='まとめ')
146
+ if summary_section:
147
+ # まとめの内容を検索結果やAI生成結果から取得
148
+ summary_key = "まとめ"
149
+ summary_data = cached_responses.get(summary_key, "まとめの具体的な内容は現在利用可能ではありません。")
150
+ new_paragraph = soup.new_tag('p')
151
+ new_paragraph.string = summary_data
152
+ summary_section.insert_after(new_paragraph)
153
+
154
+ def generate_expanded_article(article_html, h3_to_text, cached_responses):
155
  print("記事を拡張中...")
156
  soup = BeautifulSoup(article_html, 'html.parser')
157
  process_standalone_h2(soup) # 独立した<h2>セクションを処理
 
166
  if h3.get_text() in h3_to_text:
167
  new_paragraph = soup.new_tag('p')
168
  new_paragraph.string = h3_to_text[h3.get_text()]
169
+ # h3タグの次の要素を取得し、その後に追加する
170
+ next_sibling = h3.find_next_sibling()
171
+ if next_sibling:
172
+ next_sibling.insert_after(new_paragraph)
173
+ else:
174
+ if h3.parent:
175
+ h3.insert_after(new_paragraph)
176
+ else:
177
+ print(f"Error: h3 element '{h3.get_text()}' has no parent.")
178
+
179
+ process_summary_section(soup, cached_responses) # まとめセクションを特別処理し、キャッシュされたレスポンスを渡す
180
 
181
  return str(soup)
182
 
183
+ # PlanAndExecuteエージェントをセットアップする関数
184
+ def setup_plan_and_execute_agent():
185
+ google_search_tool = Tool(
186
+ name="GoogleSearch",
187
+ func=GoogleSearchTool().search,
188
+ description="Search tool using Google API"
189
+ )
190
+
191
+ tools = [google_search_tool]
192
+
193
+ model_name = "gpt-3.5-turbo-0125"
194
+ llm = ChatOpenAI(model_name=model_name, temperature=0, max_tokens=1000)
195
+ planner = load_chat_planner(llm)
196
+ executor = load_agent_executor(llm, tools, verbose=True)
197
+
198
+ agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
199
+ print("PlanAndExecute agent setup complete.")
200
+ return agent
201
+
202
+ # GPT-4を使用してテキストを生成するヘルパー関数
203
+ def generate_text_with_gpt4(prompt):
204
+ response = openai.ChatCompletion.create(
205
+ model="gpt-4o",
206
+ messages=[{"role": "system", "content": "以下についての詳細な情報をまとめ、適宜箇所書き、もしくは表を使ってオリジナルの内容にしてください。"},
207
+ {"role": "user", "content": prompt}],
208
+ temperature=0.7,
209
+ max_tokens=500
210
+ )
211
+ return response.choices[0]["message"]["content"].strip()
212
+
213
+ # 初期データをTavily検索で収集する関数
214
+ def perform_initial_tavily_search(h2_texts, h3_texts):
215
+ tavily_search_tool = EnhancedTavilySearchTool()
216
+ queries = []
217
+
218
+ for idx, h2_text in enumerate(h2_texts):
219
+ h3_for_this_h2 = [h3 for h3 in h3_texts if h3.startswith(f"{idx+1}-")]
220
+ if not h3_for_this_h2 and h2_text.strip() != "まとめ": # "まとめ" セクションを除外
221
+ print(f"No matching h3 elements found for h2: {h2_text} at index {idx+1}")
222
+ continue
223
+
224
+ query = f"{h2_text} {' '.join(h3_for_this_h2)}"
225
+ queries.append(query)
226
+
227
+ print("Performing Tavily search with queries:", queries)
228
+ responses = tavily_search_tool.search(queries)
229
+ response_dict = {}
230
+ for i, query in enumerate(queries):
231
+ if i < len(responses): # 応答リストの範囲内にあることを確認
232
+ response_dict[query] = responses[i]
233
+ else:
234
+ response_dict[query] = "No response received"
235
+
236
+ return response_dict
237
+
238
+ def save_preloaded_tavily_data(data):
239
+ with open("preloaded_tavily_data.json", "w", encoding="utf-8") as f:
240
+ json.dump(data, f, ensure_ascii=False, indent=4)
241
+ print("Preloaded Tavily data saved.")
242
+
243
+ def load_preloaded_tavily_data():
244
+ with open("preloaded_tavily_data.json", "r", encoding="utf-8") as f:
245
+ print("Preloaded Tavily data loaded.")
246
+ return json.load(f)
247
+
248
+ def process_heading(agent, h2_text, h3_for_this_h2, cached_responses):
249
+ query = f"{h2_text} {' '.join(h3_for_this_h2)}"
250
+ if query in cached_responses:
251
+ return (query, cached_responses[query])
252
+ else:
253
+ return (query, "No cached response found for this heading.")
254
+
255
  # 記事を生成する関数
256
  def generate_article(editable_output2):
257
  print("Starting article generation...")
 
 
 
 
 
258
 
259
  # エージェントのセットアップ
260
  agent = setup_plan_and_execute_agent()
 
270
  cached_responses = perform_initial_tavily_search(h2_texts, h3_texts)
271
  save_preloaded_tavily_data(cached_responses)
272
 
273
+ executed_instructions = []
274
+ research_results = []
275
+
276
  with ThreadPoolExecutor(max_workers=5) as executor:
277
  futures = []
278
  for h2_text in h2_texts:
 
284
  if purpose not in executed_instructions:
285
  executed_instructions.append(purpose)
286
  research_results.append(response)
 
287
 
288
  print("Tavily search complete.")
289
 
290
  system_message = {
291
  "role": "system",
292
+ "content": "あなたはプロのライターです。すべての回答を日本語でお願いします。以下の指示に従ってHTMLコンテンツを生成してください。すべてのセクションは正確なHTMLタグと属性を保持し、id属性を正しく設定してください。"
293
  }
294
 
295
  research_summary = "\n".join([json.dumps(result) for result in research_results])
296
  instructions = []
297
 
298
+ # IDを含むHTMLプロンプトの作成
299
  instructions.append(f"""
300
+ <h1 id="title">{h1_text}</h1>
301
+ <p>「{h1_text}に関する導入文を日本語で作成してください。直接的なコピーまたは近いフレーズを避けて、オリジナルな内容にしてください。</p>""")
302
 
303
  sentences = research_summary.split('。')
 
 
304
  max_questions_per_h3 = 2
305
 
306
  for idx, h2_text in enumerate(h2_texts):
307
  h3_for_this_h2 = [h3 for h3 in h3_texts if h3.startswith(f"{idx+1}-")]
308
  instructions.append(f"""
309
+ <div id="section-{idx+1}">
310
+ <h2 id="h2-{idx+1}">{h2_text}</h2>
311
+ <p>「{h2_text}」に関する導入文を日本語で作成してください。この導入文は、以下の小見出しの内容を考慮してください:{"、".join(h3_for_this_h2)}。</p>""")
312
+ for h3_idx, h3 in enumerate(h3_for_this_h2):
313
  related_sentences = [sentence for sentence in sentences if h3 in sentence][:max_questions_per_h3]
314
  if related_sentences:
315
  content_for_h3 = "。".join(related_sentences) + "。"
316
  instructions.append(f"""
317
+ <h3 id="h3-{idx+1}-{h3_idx+1}">{h3}</h3>
318
+ <p>「{h3}に関する詳細な内容として、以下の情報を日本語で記述してください:{content_for_h3}</p>""")
319
  else:
320
  instructions.append(f"""
321
+ <h3 id="h3-{idx+1}-{h3_idx+1}">{h3}</h3>
322
+ <p>「{h3}に関する詳細な内容を日本語で記述してください。オリジナルな内容を心がけてください。</p>""")
323
+ instructions.append("</div>") # 各セクションの終わりにdivタグを閉じる
324
 
325
  # トークン数を制限するためにメッセージを分割
326
  split_instructions = []
 
350
  messages=[system_message, user_message],
351
  temperature=0.7,
352
  )
353
+ generated_text = response.choices[0]["message"]["content"]
354
+ print(f"Generated content for section {i+1}:") # 生成された各セクションの内容を出力
355
+ print(generated_text)
356
+ results.append(generated_text)
357
  except Exception as e:
358
  error_message = f"Error occurred during ChatCompletion: {str(e)}"
359
  print(error_message) # ログにエラーメッセージを出力
360
  results.append(error_message)
 
 
 
 
 
 
 
 
 
361
 
362
  final_result = "\n".join(results)
363
+ print("Final generated article content:") # 最終的な記事全体の内容を出力
364
+ print(final_result)
365
 
366
+ # 更新されたHTMLの解析
367
+ updated_soup = BeautifulSoup(final_result, 'html.parser')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
 
369
+ # 初期データをTavily検索で収集する関数
370
+ h3_texts = [h3.get_text(strip=True) for h3 in updated_soup.find_all('h3')]
371
+ cached_responses = perform_initial_tavily_search([], h3_texts)
372
+ save_preloaded_tavily_data(cached_responses)
373
 
374
+ # h3タグの拡張を行う
375
+ expanded_soup = expand_h3_sections(updated_soup, cached_responses)
 
376
 
377
+ final_html = str(expanded_soup)
378
  with open("output3.txt", "w", encoding="utf-8") as f:
379
+ f.write(final_html)
 
 
 
380
 
381
+ print("Article generation complete. Output saved to output3.txt.")
382
+ return final_html