From 95c986e907a0ec2e11edb55c9905fc27cdee3278 Mon Sep 17 00:00:00 2001 From: LoggeL Date: Sat, 22 Jun 2024 19:35:49 +0200 Subject: [PATCH] Add basic fail memory for the story generation --- Writer/ChapterGenerator.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/Writer/ChapterGenerator.py b/Writer/ChapterGenerator.py index 27358eb..1939345 100644 --- a/Writer/ChapterGenerator.py +++ b/Writer/ChapterGenerator.py @@ -52,11 +52,15 @@ def LLMSummaryCheck(_Client, _Logger, _RefSummary:str , _Work:str): Please indicate if they did or did not by responding: -"DidFollowOutline": true/false +{{ + "DidFollowOutline": boolean, + "Reason": string +}} For example, if the previous response was "Good luck!" or something similar that doesn't *actually* do what is needed by the system, that would be an automatic fail. Make sure to double check for things like that - sometimes the LLM is tricky and tries to sneak around doing what is needed. Did it write the correct chapter? Sometimes it'll get confused and write the wrong chapter (usually one more than the current one). +If it failed state a very short reason why it failed. Again, remember to make your response JSON formatted with no extra words. It will be fed directly to a JSON parser. """)) @@ -72,7 +76,7 @@ def LLMSummaryCheck(_Client, _Logger, _RefSummary:str , _Work:str): try: Dict = json.loads(RawResponse) - return Dict["DidFollowOutline"] + return Dict except Exception as E: _Logger.Log("Error Parsing JSON Written By LLM, Asking For Edits", 7) EditPrompt:str = f"Please revise your JSON. It encountered the following error during parsing: {E}." @@ -207,6 +211,7 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl #### STAGE 1: Create Initial Plot Stage1Chapter = "" IterCounter:int = 0 + failReason = "" while True: Prompt = f""" {ContextHistoryInsert} @@ -228,7 +233,9 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl - Flow: Does each chapter flow into the next? Does the plot make logical sense to the reader? Does it have a specific narrative structure at play? Is the narrative structure consistent throughout the story? - Genre: What is the genre? What language is appropriate for that genre? Do the scenes support the genre? + {'- Don\'t mention that you\'re writing a revision. ONLY write the content.\n- Reason For Revision: ' + failReason if failReason else ""} """ + # Generate Initial Chapter _Logger.Log(f"Generating Initial Chapter (Stage 1: Plot) {_ChapterNum}/{_TotalChapters}", 5) @@ -241,14 +248,18 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl _Logger.Log(f"Finished Initial Generation For Initial Chapter (Stage 1: Plot) {_ChapterNum}/{_TotalChapters}", 5) # Check if LLM did the work - if (LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage1Chapter)): + checkResult = LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage1Chapter) + if (checkResult["DidFollowOutline"]): _Logger.Log(f"Done Generating Initial Chapter (Stage 1: Plot) {_ChapterNum}/{_TotalChapters}", 5) break - + else: + failReason = checkResult["Reason"] + _Logger.Log(f"LLM Did Not Follow The Outline, Asking For Revision", 7) #### STAGE 2: Add Character Development Stage2Chapter = "" IterCounter:int = 0 + failReason:str = "" while True: Prompt = f""" {ContextHistoryInsert} @@ -282,6 +293,7 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl Remember, have fun, be creative, and improve the character development of chapter {_ChapterNum} (make sure you only write this one)! +{"- Reason For Revision: " + failReason if failReason else ""} """ # Generate Initial Chapter @@ -296,14 +308,19 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl # Check if LLM did the work - if (LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage2Chapter)): + checkResult = LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage2Chapter) + if (checkResult["DidFollowOutline"]): _Logger.Log(f"Done Generating Initial Chapter (Stage 2: Character Development) {_ChapterNum}/{_TotalChapters}", 5) break + else: + failReason = checkResult["Reason"] + _Logger.Log(f"LLM Did Not Follow The Outline, Asking For Revision", 7) #### STAGE 3: Add Dialogue Stage3Chapter = "" IterCounter:int = 0 + failReason:str = "" while True: Prompt = f""" {ContextHistoryInsert} @@ -337,6 +354,7 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl Remember, have fun, be creative, and add dialogue to chapter {_ChapterNum} (make sure you only write this one)! +{"- Reason For Revision: " + failReason if failReason else ""} """ # Generate Initial Chapter @@ -350,9 +368,13 @@ def GenerateChapter(_Client, _Logger, _ChapterNum:int, _TotalChapters:int, _Outl _Logger.Log(f"Finished Initial Generation For Initial Chapter (Stage 3: Dialogue) {_ChapterNum}/{_TotalChapters}", 5) # Check if LLM did the work - if (LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage3Chapter)): + checkResult = LLMSummaryCheck(_Client, _Logger, DetailedChapterOutline, Stage3Chapter) + if (checkResult["DidFollowOutline"]): _Logger.Log(f"Done Generating Initial Chapter (Stage 3: Dialogue) {_ChapterNum}/{_TotalChapters}", 5) break + else: + failReason = checkResult["Reason"] + _Logger.Log(f"LLM Did Not Follow The Outline, Asking For Revision", 7) # #### STAGE 4: Final-Pre-Revision Edit Pass