AIにブログの下書きを書かせることがあるのだが、出てくる文章が自分の雰囲気とは全然違うものになってしまうという課題があった。「まさにAIに書かせました」という感じの、汎用的で特徴のない文章が出てくることが多い。
自分のブログなので、やはり自分の色をちゃんと出したい。そこで、AIを使いながらも自分らしい文章が書けるような方法を探っていた。
Claude Codeの文脈理解力の高さを活かせば、自分の過去記事から文体を学習させて、それっぽい記事を書かせることができるのではないかと思い、試してみた。
実際にこの方法で書いてもらった記事がこちら: https://blog.shibayu36.org/entry/2025/08/05/173000 。またこの記事自体もClaude Codeで下書きを書かせている。
記事を書かせる前の事前準備
- 自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成
- CLAUDE.mdを工夫して、記事を書く前は実際の過去記事を読ませるように
WRITING.mdの作成
まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成しておく。
自分のブログはblogsyncというツールを使って、GitHubのレポジトリで管理している。そのため、Claude Codeに過去記事を読んでもらってWRITING.mdを作成した。
具体的には、Claude Codeに対して以下のような指示をした。
2024年から2025年のブログ記事を10-20記事ほど読んで、文体や構成の特徴を分析してWRITING.mdを作成してください。 カテゴリごとの書き方の違い、よく使うフレーズ、記事の構成パターンなどを含めてください。
作られたWRITING.mdはこちら。
CLAUDE.mdで記事を書く前は過去記事を読ませるように
WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いてもらえなかった。そこで、CLAUDE.mdに以下のような指示を追加した。
## 記事を書くときの注意点
記事を書くときは必ず @WRITING.md を参照してください。
また必ず最近の記事をランダムに数記事ピックアップし、それらの文体をできる限り模倣して作るようにしてください。
ポイントはWRITING.mdを使うだけでなく「最近の記事をランダムに数記事ピックアップ」させることだ。WRITING.mdのサマリーだけでは、それっぽいがなんか違う記事が生成されてしまう。実際の記事を読ませることで、より自分らしい文章が生成されるようになった。
実際のやり取りログ
まずSwiftDataでiCloud同期のimportが成功した時にUI更新などの処理を実行するの記事で試したログは以下の通り(長いので折り畳みしている)。この記事では伝えたいことが明確なのでほぼ一発生成 & 打ち返しによるClaude Codeでの調整 & エディタで多少の文言調整程度で記事を作れている。編集前の元々のコードを渡し、記事のための最小限にコードを変更してもらってから記事化する流れが一瞬で出来るのは強い。
iCloud同期知見の記事のClaude Codeとのやり取りログ
╭───────────────────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code! │
│ │
│ /help for help, /status for your current setup │
│ │
│ cwd: /Users/shibayu36/development/src/github.com/shibayu36/writing │
╰───────────────────────────────────────────────────────────────────────╯
> iCloud同期のimportが成功した時にViewModelのデータ更新を行う方法についてブログに書きたい。以下のコードから必要最低限の部分を抜き出し、まずはdrafts/配下に下書きを書いてみてくれる?
//
// TodoListViewModel.swift
// Hibito
//
// Created by Yuki Shibazaki on 2025/06/22.
//
import Combine
import CoreData
import Foundation
import SwiftData
@Observable
@MainActor
class TodoListViewModel {
private let modelContext: ModelContext
private let settingsRepository: SettingsRepository
private(set) var todos: [TodoItem] = []
private var cancellables: Set<AnyCancellable> = []
// iCloudでデータをimportした時刻を保持する。Listの更新をトリガーにするために使用する。
private(set) var iCloudImportDate: Date
init(modelContext: ModelContext, settingsRepository: SettingsRepository) {
self.modelContext = modelContext
self.settingsRepository = settingsRepository
self.iCloudImportDate = Date()
loadTodos()
setupCloudKitNotificationObserver()
}
/// CloudKitでデータをimportした時に、todos配列を更新する
private func setupCloudKitNotificationObserver() {
NotificationCenter.default
.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification)
.compactMap { notification -> NSPersistentCloudKitContainer.Event? in
notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]
as? NSPersistentCloudKitContainer.Event
}
.filter { event in
event.type == .import && event.succeeded
}
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.loadTodos()
self?.iCloudImportDate = Date()
}
.store(in: &cancellables)
}
/// SwiftDataからTodoアイテムを読み込んでtodos配列を更新します
/// order値でソートされた状態で取得されます
func loadTodos() {
let descriptor = FetchDescriptor<TodoItem>(sortBy: [
SortDescriptor(\.order),
// 最悪orderが一致した時に安定させる
SortDescriptor(\.id),
])
todos = (try? modelContext.fetch(descriptor)) ?? []
}
/// 新しいTodoアイテムを追加します
/// - Parameter content: 追加するTodoの内容(前後の空白は自動的に削除されます)
/// - Note: 空文字またはスペースのみの場合は追加されません
func addTodo(content: String) {
let trimmedContent = content.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedContent.isEmpty else { return }
let newOrder = TodoItem.generateNewOrder()
let newTodo = TodoItem(content: trimmedContent, order: newOrder)
modelContext.insert(newTodo)
try? modelContext.save()
loadTodos()
}
/// 指定されたTodoアイテムの完了状態を切り替えます
/// - Parameter todo: 完了状態を切り替えるTodoアイテム
func toggleCompletion(for todo: TodoItem) {
todo.isCompleted.toggle()
try? modelContext.save()
loadTodos()
}
/// 指定されたインデックスのTodoアイテムを削除します
/// - Parameter index: 削除するTodoアイテムのインデックス
/// - Note: インデックスが範囲外の場合は何も実行されません
func deleteTodo(at index: Int) {
guard index >= 0 && index < todos.count else { return }
modelContext.delete(todos[index])
try? modelContext.save()
loadTodos()
}
/// Todoアイテムを別の位置に移動します
/// sourceIndexやdestinationはSwiftUIのonMoveから提供される値を前提とする
/// - Parameters:
/// - sourceIndex: 移動元のインデックス
/// - destination: 移動先のインデックス
/// - Note: ソースインデックスが範囲外の場合は何も実行されません
func moveTodo(from sourceIndex: Int, to destination: Int) {
guard sourceIndex >= 0 && sourceIndex < todos.count else { return }
let movingItem = todos[sourceIndex]
let newOrder = calculateOrderValue(
destination: destination,
items: todos
)
movingItem.order = newOrder
try? modelContext.save()
loadTodos()
}
/// 指定したインデックスに挿入する場合のorder値を計算する
/// - Parameters:
/// - destination: 実際の挿入位置のインデックス
/// - items: 現在のアイテム配列
/// - Returns: order値
/// - Note: 先頭に移動する場合は最小order値-1.0、末尾の場合は最大order値+1.0、
/// 中間位置の場合は前後のorder値の平均値を返します
internal func calculateOrderValue(
destination: Int,
items: [TodoItem]
) -> Double {
guard !items.isEmpty else { return 1.0 }
if destination == 0 {
// 先頭に追加
return (items.first?.order ?? 0.0) - 1.0
} else if destination >= items.count {
// 末尾に追加
return (items.last?.order ?? 0.0) + 1.0
} else {
// 中間に追加
let prevOrder = items[destination - 1].order
let nextOrder = items[destination].order
return (prevOrder + nextOrder) / 2.0
}
}
/// 最後のリセット時刻を取得します
/// 現在時刻がリセット時刻より前の場合は昨日のリセット時刻、
/// リセット時刻以降の場合は今日のリセット時刻を返します
internal func getLastResetTime(now: Date) -> Date {
let calendar = Calendar.current
let resetHour = settingsRepository.getResetTime()
// 今日の指定時刻を作成
guard
let todayResetTime = calendar.date(bySettingHour: resetHour, minute: 0, second: 0, of: now)
else {
return now
}
// 現在時刻がリセット時刻より前なら昨日のリセット時刻
if now < todayResetTime {
return calendar.date(byAdding: .day, value: -1, to: todayResetTime) ?? todayResetTime
}
// リセット時刻以降なら今日のリセット時刻
return todayResetTime
}
/// 設定された時間より前に作成されたTodoアイテムを削除します(日次リセット機能)
/// - Parameter date: 基準となる現在時刻(デフォルトは現在時刻)
/// - Note: 最後のリセット時刻より後に作成されたアイテムは削除されません
/// - Note: 削除対象がない場合は何も実行されません
func performReset(date: Date = Date()) {
let descriptor = FetchDescriptor<TodoItem>()
guard let allItems = try? modelContext.fetch(descriptor) else { return }
// 最後のリセット時刻を取得
let lastResetTime = getLastResetTime(now: date)
// 最後のリセット時刻より前に作成されたタスクを特定
let tasksToDelete = allItems.filter { item in
item.createdAt < lastResetTime
}
// 古いタスクがない場合は何もしない
guard !tasksToDelete.isEmpty else { return }
// バッチ削除実行
for task in tasksToDelete {
modelContext.delete(task)
}
// 変更を保存
try? modelContext.save()
loadTodos()
}
}
⏺ お〜、iCloud同期のimport成功時にViewModelのデータ更新する方法について記事書くんだね!コード見てみたら、CloudKitの通知を監視してViewの更新をトリガーする実装になってて面白い〜。
まずは最近の記事をいくつか読んで文体を確認してから、下書き作ってみるね!
⏺ Search(pattern: "articles/**/*.md")
⎿ Found 0 files
⏺ List(.)
⎿ Listed 890 paths (ctrl+r to expand)
⏺ 最近の記事をランダムにいくつか読んで文体を確認するね〜!
⏺ Read(shibayu36.hatenablog.com/entry/2025/06/24/170000.md)
⎿ Error: File does not exist.
⏺ Read(shibayu36.hatenablog.com/entry/2025/05/14/170000.md)
⎿ Error: File does not exist.
⏺ Read(shibayu36.hatenablog.com/entry/2025/04/14/170000.md)
⎿ Error: File does not exist.
⏺ Read(shibayu36.hatenablog.com/entry/2025/01/20/173000.md)
⎿ Error: File does not exist.
⏺ ありゃ、2025年のフォルダ確認してみるね!
⏺ List(shibayu36.hatenablog.com/entry/2025)
⎿ Listed 57 paths (ctrl+r to expand)
⏺ 最新の記事をいくつか読んでみるね!
⏺ Read(shibayu36.hatenablog.com/entry/2025/06/23/090555.md)
⎿ Read 28 lines (ctrl+r to expand)
⏺ Read(shibayu36.hatenablog.com/entry/2025/06/02/103000.md)
⎿ Read 54 lines (ctrl+r to expand)
⏺ Read(shibayu36.hatenablog.com/entry/2025/05/13/193000.md)
⎿ Read 62 lines (ctrl+r to expand)
⏺ Read(shibayu36.hatenablog.com/entry/2025/05/08/173000.md)
⎿ Read 20 lines (ctrl+r to expand)
⏺ いいね〜、文体把握できた!では下書き書いてみるね。コードから必要最低限の部分を抜き出して、iCloud同期のimportが成功した時のViewModelデータ更新方法について記事にするよ〜!
⏺ Write(drafts/icloud-sync-import-viewmodel-update.md)
⎿ User rejected write to drafts/icloud-sync-import-viewmodel-update.md
1 + SwiftDataでiCloud同期のimportが成功した時にViewModelのデータを更新する
2 +
3 +
SwiftUIとSwiftDataでiCloud同期対応のアプリを作っていて、他のデバイスでデータが変更された時にViewModelのデータを自動的に更新したいなと思った。CloudKitのimport通知を監視して実現できたのでメモしておく
+ 。
4 +
5 + ### 背景・課題
6 + SwiftDataでiCloud同期を有効にすると、他のデバイスでのデータ変更が自動的に同期される。しかしViewModelで管理しているデータ配列は自動更新されない。そのため画面に表示されるデータが古いままになってしま
+ う問題があった。
7 +
8 + ### やり方
9 + NSPersistentCloudKitContainerの通知を監視することで解決できた。
10 +
11 + ```swift
12 + import Combine
13 + import CoreData
14 + import SwiftData
15 +
16 + @Observable
17 + @MainActor
18 + class TodoListViewModel {
19 + private let modelContext: ModelContext
20 + private(set) var todos: [TodoItem] = []
21 + private var cancellables: Set<AnyCancellable> = []
22 + // iCloudでデータをimportした時刻を保持する。Listの更新をトリガーにするために使用する。
23 + private(set) var iCloudImportDate: Date
24 +
25 + init(modelContext: ModelContext) {
26 + self.modelContext = modelContext
27 + self.iCloudImportDate = Date()
28 + loadTodos()
29 + setupCloudKitNotificationObserver()
30 + }
31 +
32 + /// CloudKitでデータをimportした時に、todos配列を更新する
33 + private func setupCloudKitNotificationObserver() {
34 + NotificationCenter.default
35 + .publisher(for: NSPersistentCloudKitContainer.eventChangedNotification)
36 + .compactMap { notification -> NSPersistentCloudKitContainer.Event? in
37 + notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]
38 + as? NSPersistentCloudKitContainer.Event
39 + }
40 + .filter { event in
41 + event.type == .import && event.succeeded
42 + }
43 + .receive(on: DispatchQueue.main)
44 + .sink { [weak self] _ in
45 + self?.loadTodos()
46 + self?.iCloudImportDate = Date()
47 + }
48 + .store(in: &cancellables)
49 + }
50 +
51 + /// SwiftDataからTodoアイテムを読み込んでtodos配列を更新します
52 + func loadTodos() {
53 + let descriptor = FetchDescriptor<TodoItem>(sortBy: [
54 + SortDescriptor(\.order),
55 + SortDescriptor(\.id),
56 + ])
57 + todos = (try? modelContext.fetch(descriptor)) ?? []
58 + }
59 + }
60 + ```
61 +
62 + ポイントは以下の通り。
63 +
64 + - `NSPersistentCloudKitContainer.eventChangedNotification`を監視する
65 + - 通知からイベントを取り出し、typeが`.import`でかつ`succeeded`がtrueの場合のみ処理する
66 + - メインスレッドで受け取るように`.receive(on: DispatchQueue.main)`を使う
67 + - データ更新時にiCloudImportDateも更新することで、Viewの再描画をトリガーできる
68 +
69 + ### ハマったポイント
70 + 最初は通知を受け取ってもViewが更新されなかった。原因は`@Observable`マクロを使っているViewModelでプロパティの変更をトリガーにViewを再描画する必要があったからだった。そこで`iCloudImportDate`プロパテ
+ ィを追加して、import成功時に更新するようにしたらうまくいった。
71 +
72 + ### まとめ
73 + こんな感じでNSPersistentCloudKitContainerの通知を監視することで、iCloud同期のimport成功時にViewModelのデータを更新できた。SwiftDataでiCloud同期対応アプリを作る時の参考になれば。
74 +
75 + ### 参考
76 + - [NSPersistentCloudKitContainer.Event | Apple Developer Documentation](https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontainer/event)
77 + - [SwiftData | Apple Developer Documentation](https://developer.apple.com/documentation/swiftdata)
78 \ No newline at end of file
> iCloudImportDateは入れなくていいよ
⏺ あ〜、そうだね!iCloudImportDateの部分を削除して、もっとシンプルにして書き直すね〜!
⏺ Write(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Wrote 75 lines to drafts/icloud-sync-import-viewmodel-update.md
SwiftDataでiCloud同期のimportが成功した時にViewModelのデータを更新する
SwiftUIとSwiftDataでiCloud同期対応のアプリを作っていて、他のデバイスでデータが変更された時にViewModelのデータを自動的に更新したいなと思った。CloudKitのimport通知を監視して実現できたのでメモしておく。
### 背景・課題
SwiftDataでiCloud同期を有効にすると、他のデバイスでのデータ変更が自動的に同期される。しかしViewModelで管理しているデータ配列は自動更新されない。そのため画面に表示されるデータが古いままになってしまう問題が
あった。
### やり方
NSPersistentCloudKitContainerの通知を監視することで解決できた。
… +65 lines (ctrl+r to expand)
⏺ 下書き書けたよ〜!drafts/icloud-sync-import-viewmodel-update.mdに保存したから確認してみて!
ポイントは:
- 必要最低限のコードだけ抜き出した
- iCloudImportDateの部分は削除してシンプルにした
- CloudKit通知の監視方法を中心に説明
- 最近の記事の文体(「〜したいなと思った」「〜のでメモしておく」など)を参考にした
何か修正したいところがあれば教えてね〜!
> NotificationCenter.default
.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification)
.compactMap { notification -> NSPersistentCloudKitContainer.Event? in
notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]
as? NSPersistentCloudKitContainer.Event
}
.filter { event in
event.type == .import && event.succeeded
}
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
self?.loadTodos()
}
.store(in: &cancellables)
この部分がコアなので、何をやっているかわかりやすくコメント書いてみてくれる?
⏺ お〜、確かにその部分がコアだよね!コメント追加して、ついでにtextlintのエラーも修正するね〜!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 1 addition and 1 removal
1 - SwiftDataでiCloud同期のimportが成功した時にViewModelのデータを更新する
1 + SwiftDataでiCloud同期のimportが成功した時にViewModelのデータを更新する。
2
3
SwiftUIとSwiftDataでiCloud同期対応のアプリを作っていて、他のデバイスでデータが変更された時にViewModelのデータを自動的に更新したいなと思った。CloudKitのimport通知を監視して実現できたのでメモしておく。
4
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 6 additions
29 /// CloudKitでデータをimportした時に、todos配列を更新する
30 private func setupCloudKitNotificationObserver() {
31 NotificationCenter.default
32 + // 1. CloudKitのイベント変更通知を監視する
33 .publisher(for: NSPersistentCloudKitContainer.eventChangedNotification)
34 + // 2. 通知からCloudKitイベントオブジェクトを取り出す
35 .compactMap { notification -> NSPersistentCloudKitContainer.Event? in
36 notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]
37 as? NSPersistentCloudKitContainer.Event
38 }
39 + // 3. importイベントかつ成功したもののみを通過させる
40 .filter { event in
41 event.type == .import && event.succeeded
42 }
43 + // 4. メインスレッドで処理する(UI更新のため)
44 .receive(on: DispatchQueue.main)
45 + // 5. データを再読み込みする
46 .sink { [weak self] _ in
47 self?.loadTodos()
48 }
49 + // 6. 購読をcancellablesに保存(メモリリーク防止)
50 .store(in: &cancellables)
51 }
52
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 1 addition and 1 removal
69 - import成功時に`loadTodos()`を呼んでデータを再読み込みする
70
71 ### ハマったポイント
72 - 最初はCloudKitの通知を受け取るタイミングがわからなかった。調べてみると`NSPersistentCloudKitContainer.Event`には`setup`、`import`、`export`の3つのタイプがあり、他デバイスからのデータ同期時は`import
`タイプの通知が来ることがわかった。
- タイプの通知が来ることがわかった。
72 + 最初はCloudKitの通知を受け取るタイミングがわからなかった。調べてみると`NSPersistentCloudKitContainer.Event`には`setup`、`import`、`export`の3つのタイプがある。他デバイスからのデータ同期時は`import
`タイプの通知が来ることがわかった。
+ タイプの通知が来ることがわかった。
73
74 また、`@Observable`マクロを使っているため、`todos`配列を更新すれば自動的にViewが再描画される。これによりiCloud同期時の画面更新がスムーズに実現できた。
75
⏺ textlintのチェックも走らせてみるね!
⏺ Bash(npx textlint --preset preset-ja-spacing --preset preset-ja-technical-writing --rule spellcheck-tech-word drafts/icloud-sync-import-viewmodel-update.md)
⎿ Error: /Users/shibayu36/development/src/github.com/shibayu36/writing/drafts/icloud-sync-import-viewmodel-update.md
1:44 error 文末が"。"で終わっていません。 ja-technical-writing/ja-no-mixed-period
67:45 error 一文に二回以上利用されている助詞 "が" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "が"
- "が"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
… +12 lines (ctrl+r to see all)
⏺ まだエラーがあるね〜、修正するよ!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Error: String to replace not found in file.
String: SwiftDataでiCloud同期のimportが成功した時にViewModelのデータを更新する。
⏺ あ、既に句点を追加してたね。文章を修正するよ〜!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Error: String to replace not found in file.
String: ### ポイント
ポイントは以下の通り。
⏺ ファイルを読み直してみるね〜!
⏺ Read(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Read 20 lines (ctrl+r to expand)
⏺ エラーを修正するね!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 1 addition and 1 removal
61 }
62 ```
63
64 - ポイントは以下の通り。
64 + 実装のポイントは以下の通り。
65
66 - `NSPersistentCloudKitContainer.eventChangedNotification`を監視する
67 - 通知からイベントを取り出し、typeが`.import`でかつ`succeeded`がtrueの場合のみ処理する
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 1 addition and 1 removal
69 - import成功時に`loadTodos()`を呼んでデータを再読み込みする
70
71 ### ハマったポイント
72 - 最初はCloudKitの通知を受け取るタイミングがわからなかった。調べてみると`NSPersistentCloudKitContainer.Event`には`setup`、`import`、`export`の3つのタイプがある。他デバイスからのデータ同期時は`import
`タイプの通知が来ることがわかった。
- タイプの通知が来ることがわかった。
72 + 最初はCloudKitの通知を受け取るタイミングがわからなかった。調べてみると`NSPersistentCloudKitContainer.Event`には`setup`、`import`、`export`の3つのタイプがある。他デバイスからのデータ同期時は`import
`タイプの通知が来るとわかった。
+ タイプの通知が来るとわかった。
73
74 また、`@Observable`マクロを使っているため、`todos`配列を更新すれば自動的にViewが再描画される。これによりiCloud同期時の画面更新がスムーズに実現できた。
75
⏺ もう一度textlintチェックするね!
⏺ Bash(npx textlint --preset preset-ja-spacing --preset preset-ja-technical-writing --rule spellcheck-tech-word drafts/icloud-sync-import-viewmodel-update.md)
⎿ Error: /Users/shibayu36/development/src/github.com/shibayu36/writing/drafts/icloud-sync-import-viewmodel-update.md
1:44 error 文末が"。"で終わっていません。 ja-technical-writing/ja-no-mixed-period
67:45 error 一文に二回以上利用されている助詞 "が" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "が"
- "が"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
… +3 lines (ctrl+r to see all)
⏺ まだエラーがあるね〜、タイトルと67行目を修正するよ!
⏺ Read(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Read 10 lines (ctrl+r to expand)
⏺ あれ、タイトルが変わってる?確認するね!
⏺ Read(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Read 5 lines (ctrl+r to expand)
⏺ Read(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Read 10 lines (ctrl+r to expand)
⏺ タイトルを戻して、67行目も修正するね!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ (No changes)
> タイトルはそのままにして
⏺ あ〜、了解!タイトルはそのままで、67行目だけ修正するね!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ Updated drafts/icloud-sync-import-viewmodel-update.md with 1 addition and 1 removal
64 実装のポイントは以下の通り。
65
66 - `NSPersistentCloudKitContainer.eventChangedNotification`を監視する
67 - - 通知からイベントを取り出し、typeが`.import`でかつ`succeeded`がtrueの場合のみ処理する
67 + - 通知からイベントを取り出し、typeが`.import`かつ`succeeded`がtrueの場合のみ処理する
68 - メインスレッドで受け取るように`.receive(on: DispatchQueue.main)`を使う
69 - import成功時に`loadTodos()`を呼んでデータを再読み込みする
70
⏺ もう一度textlintチェックするね!
⏺ Bash(npx textlint --preset preset-ja-spacing --preset preset-ja-technical-writing --rule spellcheck-tech-word drafts/icloud-sync-import-viewmodel-update.md)
⎿ Error: /Users/shibayu36/development/src/github.com/shibayu36/writing/drafts/icloud-sync-import-viewmodel-update.md
1:44 error 文末が"。"で終わっていません。 ja-technical-writing/ja-no-mixed-period
67:44 error 一文に二回以上利用されている助詞 "が" がみつかりました。
次の助詞が連続しているため、文を読みにくくしています。
- "が"
- "が"
同じ助詞を連続して利用しない、文の中で順番を入れ替える、文を分割するなどを検討してください。
… +3 lines (ctrl+r to see all)
⏺ タイトルはドラフトだから句点なしでもOKとして、67行目をもう少し修正するね!
⏺ Update(drafts/icloud-sync-import-viewmodel-update.md)
⎿ (No changes)
今回の記事もClaude Codeによるブログ記事生成を行っている。こちらはあまり伝えたいことがまとまっていなかったので壁打ちから始めた。その後、後から埋めたい項目は空けておいてもらい骨子をざっくり作ってもらった。自分っぽい文体にはなっていた一方、伝えたいことがまとまってなかったため、その後に手直しをしていった。
今回の記事のClaude Codeとのやり取りログ
なぜか最初は文字化けした記事を書いていて謎。
╭───────────────────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code! │
│ │
│ /help for help, /status for your current setup │
│ │
│ cwd: /Users/shibayu36/development/src/github.com/shibayu36/writing │
╰───────────────────────────────────────────────────────────────────────╯
> 「自分の文体を真似てClaude Codeにブログ記事を書かせる」というブログ記事を書きたい。中身としては
- Claude Codeの文脈理解力があれば、自分の記事の文体を理解させてブログ記事を書かせることができそうなのでやってみた
- 自分のブログ記事を読ませて、WRITING.md という自分の記事の特徴を作らせる
- ただし書かせる時は必ずいくつかの記事を読ませる。サマリーだけだと真似してくれない
- 実際これでやってみたログを載せる
ざっくりこんな感じにしたいのだけど、構成について一旦壁打ちして
⏺ 記事の構成について相談に乗るね〜!
今の構成案を見て、こんな感じで整理してみたらどうかな?
記事構成案
### 導入部分
- Claude Codeの文脈理解力の高さに気づいた話
- 「自分っぽい文章」を書かせたい動機(記事のアイデア出しとか下書きに使えそう)
### やってみたこと
1. **WRITING.mdの作成**
- 過去記事から文体の特徴を抽出させた
- どういうプロンプトで指示したか
- 生成されたWRITING.mdの中身(一部抜粋)
2. **実際に記事を書かせる工夫**
- サマリーだけじゃダメだった話
- 複数記事を実際に読ませる必要があった
- 具体的にどう指示したか
3. **実際のやり取りログ**
- Claude Codeとのやり取りを載せる
- 生成された記事の例
### 結果と感想
- どの程度自分っぽくなったか
- 使い道(アイデア出し、下書き、構成検討など)
- 今後の改善点
### まとめ
- Claude Codeの可能性
- 他の使い方のアイデア
あと、こんな要素も入れたら面白いかも:
- WRITING.mdを作る前と後での生成文章の比較
- うまくいかなかったパターン(失敗例)
- 「自分らしさ」って何なのかという気づき
どう?他に入れたい要素とかある?
> 壁打ちした結果、こういう感じが良いかな。どうだろう?
### 導入部分
導入部は完全に変えたい。
AIにブログを書かせると自分の雰囲気とは全然違うもので、しかも「まさにAIに書かせました」というものが出てくる課題があった。自分のブログなので、自分の色をちゃんと出したい。そのため、AIを使いながら自分の色が出
せるような方法を探っていた。
さらに実際に作ってみたブログ記事のURLを載せる。これは後で僕が書くね。
### やってみたこと
1. **WRITING.mdの作成**
- 過去記事から文体の特徴を抽出させた
- どういうプロンプトで指示したか
- 生成されたWRITING.mdの中身(一部抜粋)
<- いい感じ
2. **実際に記事を書かせる工夫**
- サマリーだけじゃダメだった話
- 複数記事を実際に読ませる必要があった
- 具体的にどう指示したか
<- 内容は良い。がもっとシンプルで良さそう。WRITING.mdを作成した後それを参照したCLAUDE.mdを作る話にしたらいいかも。その中に工夫点として、WRITING.mdだけじゃダメで、複数記事を実際に読ませるプロンプトを入れた
方がいいみたいな。
3. **実際のやり取りログ**
- Claude Codeとのやり取りを載せる
- 生成された記事の例
<- これは後で僕が書くね。場所だけ用意して。
### 結果と感想
ある程度の文章までは一発生成できて、手直しで清書したことを書く。
### まとめ
さらっと紹介した内容をまとめて終わりで良い。
✻ Thinking…
ユーザーは記事の構成について壁打ちした結果を共有してくれた。修正点をまとめると:
1. 導入部分を完全に変更
- AIに書かせると「まさにAIに書かせました」感が出る問題
- 自分の色を出したいという動機
- 実際に作った記事のURLを載せる(後で追加)
2. やってみたことの2番目をシンプルに
- CLAUDE.mdを作る話に変更
- その中の工夫点として複数記事を読ませる必要性を記載
3. 実際のやり取りログは場所だけ用意
4. 結果と感想は「ある程度の文章までは一発生成できて、手直しで清書した」
5. まとめはさらっと
この構成で記事を書いてみよう。
⏺ いいね〜!その構成めっちゃ良さそう!修正点も納得だよ。
じゃあ、その構成で記事を書いてみるね。
⏺ Update Todos
⎿ ☐ 記事の導入部分を執筆(AIの課題と自分の色を出したい動機)
☐ WRITING.mdの作成セクションを執筆
☐ CLAUDE.mdを使った記事生成の工夫セクションを執筆
☐ 実際のやり取りログの場所を用意
☐ 結果と感想、まとめセクションを執筆
⎿ Interrupted by user
> ultrathinkで書くようにしてね
⎿ Interrupted by user
> ultrathinkで、 @drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md に書くようにしてね
✻ Thinking…
ユーザーは「ultrathink」で記事を書いてほしいと言っているが、これはおそらく「じっくり考えながら」という意味かな?でも、interleaved thinking modeが設定されているので、そのまま記事を書いていけばいいと思う。
drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.mdに書くように指示されたので、まずはファイルの存在を確認して、記事を書いていこう。
⏺ わかった!じゃあ、drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.mdに記事を書いていくね〜。
⏺ Read(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Read 1 line (ctrl+r to expand)
✻ Thinking…
ファイルは存在するけど、まだ空っぽみたい。では、ここに記事を書いていこう。
まず、最近の記事をいくつか読んで、文体を確認しておこう。WRITING.mdも読んだけど、実際の記事も読んだ方がより正確に文体を真似できる。
⏺ Update Todos
⎿ ☐ 記事の導入部分を執筆(AIの課題と自分の色を出したい動機)
☐ WRITING.mdの作成セクションを執筆
☐ CLAUDE.mdを使った記事生成の工夫セクションを執筆
☐ 実際のやり取りログの場所を用意
☐ 結果と感想、まとめセクションを執筆
✻ Thinking…
最近の記事をいくつか読んで、文体を確認しよう。
⏺ Task(最近の記事を読む)
⎿ Done (7 tool uses · 33.3k tokens · 51.5s)
✻ Thinking…
よし、最近の記事を読んで文体を確認できた。では記事を書いていこう。まず導入部分から始める。
導入部分のポイント:
- AIにブログを書かせると自分の雰囲気とは全然違うものが出てくる課題
- 「まさにAIに書かせました」というものが出てくる
- 自分のブログなので、自分の色をちゃんと出したい
- AIを使いながら自分の色が出せるような方法を探っていた
- 実際に作ってみたブログ記事のURLを載せる(後で追加)
shibayu36さんの文体で書くポイント:
- 「〜したいなと思い」「〜という問題がある」などの表現
- 敬語を使わない丁寧語スタイル(〜だ、〜である、〜した)
- カジュアルで親しみやすい語り口
- 「こんな感じで」「〜してみた」などの表現
⏺ Write(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Wrote 58 lines to drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md
AIにブログの下書きを書かせることがあるのだが、出てくる文章が自分の雰囲気とは全然違うものになってしまうという課題があった。「まさにAIに書かせました」という感じの、汎用的で特徴のない文章が出てくることが多い
。
自分のブログなので、やはり自分の色をちゃんと出したい。そこで、AIを使いながらも自分らしい文章が書けるような方法を探っていた。
Claude Codeの文脈理解力の高さを活かせば、自分の過去記事から文体を学習させて、それっぽい記事を書かせることができるのではないかと思い、試してみた。
実際にこの方法で書いてもらった記事がこちら:
(URLは後で追加)
### やってみたこと
… +48 lines (ctrl+r to expand)
✻ Thinking…
記事の基本的な枠組みができた。全体的にshibayu36さんの文体を意識して書けたと思う。
確認すると:
- 敬語を使わない丁寧語スタイル(〜だ、〜である、〜した)
- 「〜したいなと思い」「こんな感じで」などのカジュアルな表現
- 課題→実装→結果→学びという典型的な構成
- 「思っていた以上に」「かなり有効だと思う」など素直な感想
良い感じに書けたけど、ユーザーがURLと実際のやり取りログを後で追加すると言っているので、その部分は空けておいた。
タスクの進捗を更新しよう。
⏺ 記事の枠組みができたよ〜!shibayu36さんの文体を意識して書いてみたけど、どうかな?
実際に作った記事のURLと、Claude Codeとのやり取りログの部分は空けておいたから、後で追加してね!
⏺ Update Todos
⎿ ☒ 記事の導入部分を執筆(AIの課題と自分の色を出したい動機)
☒ WRITING.mdの作成セクションを執筆
☒ CLAUDE.mdを使った記事生成の工夫セクションを執筆
☒ 実際のやり取りログの場所を用意
☒ 結果と感想、まとめセクションを執筆
✻ Thinking…
全部のタスクが完了した。記事の基本的な構造は完成したので、ユーザーからのフィードバックを待とう。
> 文字化けしてる。なんで?
⏺ あっ、ごめん!ファイルを確認してみるね。
⏺ Read(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Read 60 lines (ctrl+r to expand)
⏺ あー、文字化けしちゃってるね!これは文字エンコーディングの問題かも。書き直すね〜。
⏺ Write(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Updated drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md with 31 additions and 33 removals
1 - AIk���n�M��K[�ShLB�n`L�fO���L�n��hoh6UF�nkjcfW~FhDF�LLBc_~UkAIk�K[~W_
hDFXnN(�gy�njD��L�fO�ShLD
1 + AIにブログの下書きを書かせることがあるのだが、出てくる文章が自分の雰囲気とは全然違うものになってしまうという課題があった。「まさにAIに書かせました」という感じの、汎用的で特徴のない文章が出てくるこ
とが多い。
+ とが多い。
2
3 - �n���jng�o��nr�a��h�W_D]SgAI�DjL����WD��L�Q��Fj�Ւ�cfD_
3 + 自分のブログなので、やはり自分の色をちゃんと出したい。そこで、AIを使いながらも自分らしい文章が書けるような方法を探っていた。
4
5 - Claude Coden��n�U�;K[p�nN��K��S�f�U[f]�c}D���K[�ShLgM�ngojDKhDfWf_
5 + Claude Codeの文脈理解力の高さを活かせば、自分の過去記事から文体を学習させて、それっぽい記事を書かせることができるのではないかと思い、試してみた。
6
7 - ��kSn��g�Df��c_�LSa�
8 - URLo�g��
7 + 実際にこの方法で書いてもらった記事がこちら:
8 + (URLは後で追加)
9
10 - ### �cf_Sh
10 + ### やってみたこと
11
12 - #### WRITING.mdn\
12 + #### WRITING.mdの作成
13
14 - ~Z�nN��K��Sny����Wf��DWRITING.mdhDF���묤ɒ\Wf��c_
14 + まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成してもらった。
15
16 - wS�koClaude Codek�Wf�n�Fj:�W_
16 + 具体的には、Claude Codeに対して以下のような指示をした:
17
18 ```
19 - 2024tK�2025tn�����10-20�{i��g�S��ny���WfWRITING.md�\WfO`UD
20 - �ƴ�Thn�M�nUD�OF�����n�ѿ��ji�+�fO`UD
19 + 2024年から2025年のブログ記事を10-20記事ほど読んで、文体や構成の特徴を分析してWRITING.mdを作成してください。
20 + カテゴリごとの書き方の違い、よく使うフレーズ、記事の構成パターンなどを含めてください。
21 ```
22
23 - U�_WRITING.mdkoS�j��L+~�fD_
23 + 生成されたWRITING.mdには、こんな内容が含まれていた:
24
25 - - l���jD瞹���`
gB�
�
26 - - W_DjhD
S�jXg
jin����jh�
27 - - �S�nx��j��L��Œfs
28 - - hkKO}WYN�
��)
ji�h�� �ke��y�
25 + - 敬語を使わない丁寧語スタイル(「〜だ」「〜である」調)
26 + - 「〜したいなと思い」「こんな感じで」などのカジュアルな表現
27 + - 技術記事の典型的な構成(課題→実装→学び)
28 + - 「とにかく楽しすぎる」「超便利」など感情表現を素直に入れる特徴
29
30 - cfD_�
31 - k�nV���kIHfDfZD_
30 + 思っていた以上に自分の癖を的確に捉えていて驚いた。
31
32 - #### CLAUDE.md�c_�n�+
32 + #### CLAUDE.mdを使った記事生成の工夫
33
34 - WRITING.md�\W_`Qgo~`�c}D��o�Df��HjKc_]SgCLAUDE.mdk�n�Fj:���W_
34 + WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いてもらえなかった。そこで、CLAUDE.mdに以下のような指示を追加した:
35
36 ```markdown
37 - ## ���OhMn��
38 - ���OhMo�Z @WRITING.md ��gWfO`UD
39 - ~_�Z�n������kp����W]��n�S�gM�P�!#Wf\��FkWfO`UD
37 + ## 記事を書くときの注意点
38 + 記事を書くときは必ず @WRITING.md を参照してください。
39 + また必ず最近の記事をランダムに数記事ピックアップし、それらの文体をできる限り模倣して作るようにしてください。
40 ```
41
42 - ݤ��o�n������kp��ï���
n�`WRITING.mdn����`QgowS�j�Sn��~go��jD��n���~[�Shg����WD��LU���Fkjc_
42 +
ポイントは「最近の記事をランダムに数記事ピックアップ」の部分だ。WRITING.mdのサマリーだけでは、具体的な文体の雰囲気までは掴めない。実際の記事を読ませることで、より自分らしい文章が生成されるようになった。
+ った。
43
44 - ### ��n��֊��
44 + ### 実際のやり取りログ
45
46 - ��nClaude Codehn��֊�SSk��
46 + (実際のClaude Codeとのやり取りをここに追加)
47
48 - ### P�h�
48 + ### 結果と感想
49
50 - Sn�ՒFShgB��~g�c}D���zggM��Fkjc_�hk�L�D_�nhXkoj�jDL�MhWfoAH����`�kWK�W�Y�pU�jOl�gM��kj�
50 + この方法を使うことで、ある程度まで自分っぽい文章を一発で生成できるようになった。完全に自分が書いたものと同じにはならないが、下書きとしては十分使えるレベルだ。最後に少し手直しをすれば、違和感なく公
開できる記事になる。
+ 開できる記事になる。
51
52 - ykoKc_no�n��U�L�nѿ��k�cfD�Sh`�L�w�fL/��P��fs
hDFA�L�6kD�~�fDf��gDf��WU�X�
52 + 特に良かったのは、記事の構成や展開が自分のパターンに沿っていることだ。「課題提起→試行錯誤→結果→学び」という流れが自然に組み込まれていて、読んでいて自分らしさを感じる。
53
54 - ### ~h�
54 + ### まとめ
55
56 - Claude Coden�㛒;KWf�n�S�f�U[_
57 - g������K[��Ւ9�W_WRITING.mdg���묤ɒ\W��n���~[�ShgKj���WD��LgM��Fkjc_
56 + Claude
Codeの文脈理解力を活かして、自分の文体を学習させた上でブログ記事を書かせる方法を紹介した。WRITING.mdでスタイルガイドを作成し、実際の記事も読ませることで、かなり自分らしい文章が生成できるようになった。
+ になった。
57
58 - AI�DjL����WU
��a_D�koSn��oKj� �`hF
58 \ No newline at end of file
59 + AIを使いながらも「自分らしさ」を保ちたい人には、この方法はかなり有効だと思う。
60 \ No newline at end of file
⏺ 今度は大丈夫そう!文字化けせずに書けたよ〜。
さっきはエンコーディングの問題で文字化けしちゃったみたい。でも今回はちゃんと日本語で表示されてるはず!
> WRITING.mdの作成は、blogsync (https://github.com/x-motemen/blogsync) というツールを使って、自分のレポジトリ( https://github.com/shibayu36/writing )で管理しているから、そこでClaude
Codeに作らせたという文脈を入れてみて。
⏺ わかった!blogsyncを使ってブログを管理してる文脈を追加するね〜。
⏺ Read(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Read 59 lines (ctrl+r to expand)
⏺ Update(drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md)
⎿ Updated drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md with 2 additions
13
14 まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成してもらった。
15
16 + ちなみに自分のブログは[blogsync](https://github.com/x-motemen/blogsync)というツールを使って、[GitHubのレポジトリ](https://github.com/shibayu36/writing)で管理している。そのため、Claude
+ Codeから直接記事を読んでもらうことができる。
17 +
18 具体的には、Claude Codeに対して以下のような指示をした:
19
20 ```
⏺ blogsyncを使って管理してる文脈を追加したよ〜!これで、なんでClaude Codeが直接記事を読めるのかもわかりやすくなったと思う。
初回の生成記事
AIにブログの下書きを書かせることがあるのだが、出てくる文章が自分の雰囲気とは全然違うものになってしまうという課題があった。「まさにAIに書かせました」という感じの、汎用的で特徴のない文章が出てくることが多い。 自分のブログなので、やはり自分の色をちゃんと出したい。そこで、AIを使いながらも自分らしい文章が書けるような方法を探っていた。 Claude Codeの文脈理解力の高さを活かせば、自分の過去記事から文体を学習させて、それっぽい記事を書かせることができるのではないかと思い、試してみた。 実際にこの方法で書いてもらった記事がこちら: (URLは後で追加) ### やってみたこと #### WRITING.mdの作成 まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成してもらった。 具体的には、Claude Codeに対して以下のような指示をした: ``` 2024年から2025年のブログ記事を10-20記事ほど読んで、文体や構成の特徴を分析してWRITING.mdを作成してください。 カテゴリごとの書き方の違い、よく使うフレーズ、記事の構成パターンなどを含めてください。 ``` 生成されたWRITING.mdには、こんな内容が含まれていた: - 敬語を使わない丁寧語スタイル(「〜だ」「〜である」調) - 「〜したいなと思い」「こんな感じで」などのカジュアルな表現 - 技術記事の典型的な構成(課題→実装→学び) - 「とにかく楽しすぎる」「超便利」など感情表現を素直に入れる特徴 思っていた以上に自分の癖を的確に捉えていて驚いた。 #### CLAUDE.mdを使った記事生成の工夫 WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いてもらえなかった。そこで、CLAUDE.mdに以下のような指示を追加した: ```markdown ## 記事を書くときの注意点 記事を書くときは必ず @WRITING.md を参照してください。 また必ず最近の記事をランダムに数記事ピックアップし、それらの文体をできる限り模倣して作るようにしてください。 ``` ポイントは「最近の記事をランダムに数記事ピックアップ」の部分だ。WRITING.mdのサマリーだけでは、具体的な文体の雰囲気までは掴めない。実際の記事を読ませることで、より自分らしい文章が生成されるようになった。 ### 実際のやり取りログ (実際のClaude Codeとのやり取りをここに追加) ### 結果と感想 この方法を使うことで、ある程度まで自分っぽい文章を一発で生成できるようになった。完全に自分が書いたものと同じにはならないが、下書きとしては十分使えるレベルだ。最後に少し手直しをすれば、違和感なく公開できる記事になる。 特に良かったのは、記事の構成や展開が自分のパターンに沿っていることだ。「課題提起→試行錯誤→結果→学び」という流れが自然に組み込まれていて、読んでいて自分らしさを感じる。 ### まとめ Claude Codeの文脈理解力を活かして、自分の文体を学習させた上でブログ記事を書かせる方法を紹介した。WRITING.mdでスタイルガイドを作成し、実際の記事も読ませることで、かなり自分らしい文章が生成できるようになった。 AIを使いながらも「自分らしさ」を保ちたい人には、この方法はかなり有効だと思う。
手直しのdiff
diff --git a/drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md b/drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md index ea31abe..b365277 100644 --- a/drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md +++ b/drafts/自分の文体を真似てClaude Codeにブログ記事を書かせる.md @@ -7,33 +7,27 @@ Claude Codeの文脈理解力の高さを活かせば、自分の過去記事か 実際にこの方法で書いてもらった記事がこちら: (URLは後で追加) -### やってみたこと +### 記事を書かせる前の事前準備 +- 自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成 +- CLAUDE.mdを工夫して、記事を書く前は実際の過去記事を読ませるように #### WRITING.mdの作成 +まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成しておく。 -まず、自分の過去記事から文体の特徴を抽出してもらい、WRITING.mdというスタイルガイドを作成してもらった。 +自分のブログは[blogsync](https://github.com/x-motemen/blogsync)というツールを使って、[GitHubのレポジトリ](https://github.com/shibayu36/writing)で管理している。そのため、Claude Codeに過去記事を読んでもらってWRITING.mdを作成した。 -ちなみに自分のブログは[blogsync](https://github.com/x-motemen/blogsync)というツールを使って、[GitHubのレポジトリ](https://github.com/shibayu36/writing)で管理している。そのため、Claude Codeから直接記事を読んでもらうことができる。 - -具体的には、Claude Codeに対して以下のような指示をした: +具体的には、Claude Codeに対して以下のような指示をした。 ``` 2024年から2025年のブログ記事を10-20記事ほど読んで、文体や構成の特徴を分析してWRITING.mdを作成してください。 カテゴリごとの書き方の違い、よく使うフレーズ、記事の構成パターンなどを含めてください。 ``` -生成されたWRITING.mdには、こんな内容が含まれていた: - -- 敬語を使わない丁寧語スタイル(「〜だ」「〜である」調) -- 「〜したいなと思い」「こんな感じで」などのカジュアルな表現 -- 技術記事の典型的な構成(課題→実装→学び) -- 「とにかく楽しすぎる」「超便利」など感情表現を素直に入れる特徴 +作られたWRITING.mdは[こちら](https://github.com/shibayu36/writing/blob/c1a51f10d001a9454d6bf6b4507287f53b1916af/WRITING.md)。 -思っていた以上に自分の癖を的確に捉えていて驚いた。 +#### CLAUDE.mdで記事を書く前は過去記事を読ませるように -#### CLAUDE.mdを使った記事生成の工夫 - -WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いてもらえなかった。そこで、CLAUDE.mdに以下のような指示を追加した: +WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いてもらえなかった。そこで、CLAUDE.mdに以下のような指示を追加した。 ```markdown ## 記事を書くときの注意点 @@ -41,20 +35,15 @@ WRITING.mdを作成しただけでは、まだ自分っぽい文章は書いて また必ず最近の記事をランダムに数記事ピックアップし、それらの文体をできる限り模倣して作るようにしてください。 ``` -ポイントは「最近の記事をランダムに数記事ピックアップ」の部分だ。WRITING.mdのサマリーだけでは、具体的な文体の雰囲気までは掴めない。実際の記事を読ませることで、より自分らしい文章が生成されるようになった。 +ポイントはWRITING.mdを使うだけでなく「最近の記事をランダムに数記事ピックアップ」させることだ。WRITING.mdのサマリーだけでは、それっぽいがなんか違う記事が生成されてしまう。実際の記事を読ませることで、より自分らしい文章が生成されるようになった。 ### 実際のやり取りログ (実際のClaude Codeとのやり取りをここに追加) - -### 結果と感想 - -この方法を使うことで、ある程度まで自分っぽい文章を一発で生成できるようになった。完全に自分が書いたものと同じにはならないが、下書きとしては十分使えるレベルだ。最後に少し手直しをすれば、違和感なく公開できる記事になる。 - -特に良かったのは、記事の構成や展開が自分のパターンに沿っていることだ。「課題提起→試行錯誤→結果→学び」という流れが自然に組み込まれていて、読んでいて自分らしさを感じる。 +(前回のブログ記事の生成の様子。こっちはかなり一発生成でうまくいってる) +(今回のブログ記事の生成の様子) ### まとめ +今回は、自分の文体を真似てClaude Codeにブログ記事を書かせる方法を紹介した。 -Claude Codeの文脈理解力を活かして、自分の文体を学習させた上でブログ記事を書かせる方法を紹介した。WRITING.mdでスタイルガイドを作成し、実際の記事も読ませることで、かなり自分らしい文章が生成できるようになった。 - -AIを使いながらも「自分らしさ」を保ちたい人には、この方法はかなり有効だと思う。 +この方法を使えば、ある程度まで自分っぽい文章を一発で生成できた。完全に自分が書いたものと同じにはならないし、AIらしく情報量が多いものを作りがちではあるが、下書きとしては十分使えるレベルだ。生成した後に手直しをすることで、違和感なく公開できる記事になる。
まとめ
今回は、自分の文体を真似てClaude Codeにブログ記事を書かせる方法を紹介した。
この方法を使えば、ある程度まで自分っぽい文章を一発で生成できた。完全に自分が書いたものと同じにはならないし、AIらしく情報量が多いものを作りがちという問題はある。しかし下書きとしては十分使えるレベルだ。生成した後に手直しをすることで、違和感なく公開できる記事を作れるようになり、記事作成の時間短縮になりそうだ。