前回まで、RSSフィードからX投稿のコメント生成をLLMで自動化する取り組みを進めてきました。
今回は、前回立てた方針に沿ってコード管理の準備を進めますが、ChatGPTでのVibe codingの難しさに直面します。
どういった問題が起こるか、傾向とその対策を見ていきましょう。
仕様に基づくコード生成
今回は、前回の記事で作成したドキュメントを基に、コード生成を行います。
ChatGPTには、前回の記事内容をそのまま与えています。
ドキュメントの渡し方は、全文コピペ、アプリ連携や添付ファイルの形式でも良いでしょう。 データフロー等は図で与えてもOKですし、Mermaid記法で渡しても生成AIは理解してくれます。
こちらの記述を元に、前半のMarkdown生成部1つめの.pyを生成してください。
import json
import os
import feedparser
import requests
from datetime import datetime
from typing import Dict, List
# =====================
# 設定
# =====================
RSS_URL = "https://example.com/rss"
ARTICLES_JSON = "articles.json"
REVIEW_MD = "review.md"
# =====================
# ユーティリティ
# =====================
def load_articles() -> Dict[str, dict]:
if not os.path.exists(ARTICLES_JSON):
return {}
with open(ARTICLES_JSON, "r", encoding="utf-8") as f:
return json.load(f)
def save_articles(articles: Dict[str, dict]) -> None:
with open(ARTICLES_JSON, "w", encoding="utf-8") as f:
json.dump(articles, f, ensure_ascii=False, indent=2)
def fetch_article_body(url: str) -> str:
# ※ 実運用では newspaper3k / readability 等に差し替え
try:
res = requests.get(url, timeout=10)
res.raise_for_status()
return res.text[:5000] # 仮:全文ではなく上限付き
except Exception as e:
raise RuntimeError(f"本文取得失敗: {e}")
def generate_summary_and_comment(text: str) -> Dict[str, str]:
# ※ Ollama / LLM 呼び出しはここに閉じ込める
# 後で差し替えやすいように責務分離
return {
"summary": "(要約ダミー)この記事は〇〇について述べています。",
"comment": "(コメントダミー)これは重要な動きですね。"
}
# =====================
# メイン処理
# =====================
def collect_rss_entries() -> List[dict]:
feed = feedparser.parse(RSS_URL)
entries = []
for entry in feed.entries:
entries.append({
"title": entry.get("title"),
"link": entry.get("link"),
"published": entry.get("published", "")
})
return entries
def update_articles(entries: List[dict], articles: Dict[str, dict]) -> None:
for entry in entries:
url = entry["link"]
if url in articles:
continue
articles[url] = {
"title": entry["title"],
"url": url,
"published": entry["published"],
"status": "new",
"summary": None,
"comment": None,
"created_at": datetime.utcnow().isoformat()
}
def process_articles(articles: Dict[str, dict]) -> None:
for url, article in articles.items():
if article["status"] != "new":
continue
body = fetch_article_body(url)
article["status"] = "fetched"
article["body"] = body
result = generate_summary_and_comment(body)
article["summary"] = result["summary"]
article["comment"] = result["comment"]
article["status"] = "ready"
def export_review_md(articles: Dict[str, dict]) -> None:
lines = []
lines.append("# レビュー待ち記事一覧\n")
for url, a in articles.items():
if a["status"] != "ready":
continue
lines.extend([
f"## {a['title']}",
f"- URL: {a['url']}",
"",
"### 要約",
a["summary"],
"",
"### Xコメント案",
a["comment"],
"",
"### 操作(いずれかを残す)",
"- [ ] 投稿する",
"- [ ] スキップ",
"",
"---",
""
])
with open(REVIEW_MD, "w", encoding="utf-8") as f:
f.write("\n".join(lines))
def main():
articles = load_articles()
entries = collect_rss_entries()
update_articles(entries, articles)
process_articles(articles)
save_articles(articles)
export_review_md(articles)
print("collect_and_prepare 完了")
if __name__ == "__main__":
main()
生成されたコードは関数定義や全体のフローを実行する枠組みだけで実装がなく、そのままでは動きません。
今回は、既に作成したサンプルやドキュメントが動く形で存在するため、そちらを添付して補完を指示すれば修正は可能です。 この時、設計の変更を提案してきたり、一回では修正がされないケースが多いのですが、根気よく指示を繰り返すことで動くコードに収束します。
設計はドキュメントに従ってください。
設計で新規に追加した要素は維持し、実装は、添付のコードで再利用できる部分を活用し、
RSS・本文記事・要約コメント案については同じ結果が得られるようにしてください。
注意点
Vibe codingでコード生成を行う場合、動くコードを得るまでにいくつかの典型的な問題に遭遇します。
- 具体的な実装の省略: 「ダミー」や「example.com」などで実装が省略され、曖昧な説明が多用される
- 不完全な補完: 動いていたコードを参照しても、文字列やURLが勝手に変更される
- 過度なフォールバック指向: 例外が握りつぶされ、エラーが隠蔽されて問題の発見が困難になる
- ログ過多のアプローチ: 問題解決のためにログを追加し続け、トークンを浪費する
これらの問題を認識し、適切に対処することでVibe codingをより効果的に活用できます。
次回は、これらの問題を踏まえた実装の改善について解説します。



