פיתוח כלי כתיבה מבוסס AI באמצעות Wordcraft

אנחנו אוהבים סיפורים. לספר סיפורים ולעשות צורות אחרות של כתיבה יצירתית יכולים להיות מאתגרים ומתגמלים. עם זאת, בניית סיפורים מדף ריק יכולה להיראות מרתיעה ואפילו קשה לפעמים. מודלים גנרטיביים של בינה מלאכותית (AI) יכולים לעזור לכם לעבור את הדף הריק וליצור את הנרטיב.

המדריך הזה מסביר איך להרחיב את Wordcraft, כלי מבוסס-AI לכתיבת סיפורים שפותח על ידי צוות המחקר של Google בנושא אנשים ו-AI. אפליקציית האינטרנט הזו משתמשת ב-Gemini API כדי לעזור לך ליצור סיפורים, קצת אחר חלק, על ידי יצירת רעיונות, כתיבת חלקים מהסיפורים שלך ותיקון תוכן כדי להוסיף פרטים נוספים. אתם יכולים לשנות את Wordcraft כך שיתאים יותר לסגנון הכתיבה שלכם, וליצור פקדי כתיבה חדשים לתמיכה טובה יותר בתהליך העבודה.

לקבלת סקירה כללית של הפרויקט והסבר איך להרחיב אותו, כולל תובנות מהאנשים שבונים אותו, קראו את המאמר הכלי לכתיבה ב-AI – פיתוח באמצעות Google AI. אחרת, תוכלו להתחיל להרחיב את הפרויקט לפי ההוראות שבהמשך.

הגדרת הפרויקט

בהוראות האלה מוסבר איך להגדיר את פרויקט Wordcraft לפיתוח ולבדיקה. עליכם להתקין את התוכנה הנדרשת, לשכפל את הפרויקט ממאגר הקוד, להפעיל את התקנת ההגדרות האישיות ולהגדיר כמה משתני סביבה. כדי לבדוק את ההגדרה, תוכלו להריץ את הפרויקט אחרי שתשלימו את השלבים האלה.

התקנת הדרישות המוקדמות

הפרויקט Wordcraft משתמש ב-Node וב-npm כדי לנהל חבילות ולהריץ את האפליקציה. הוראות ההתקנה הבאות מיועדות למכונה מארחת של Linux.

כדי להתקין את התוכנה הנדרשת:

שכפול והגדרה של הפרויקט

מורידים את קוד הפרויקט ומשתמשים בפקודת ההתקנה npm כדי להוריד את יחסי התלות הנדרשים ולהגדיר את הפרויקט. כדי לאחזר את קוד המקור של הפרויקט, נדרשת תוכנה לבקרת מקור של git.
כדי להוריד ולהגדיר את קוד הפרויקט:

  1. משכפלים את מאגר ה-Git באמצעות הפקודה הבאה.
    git clone https://github.com/PAIR-code/wordcraft
    
  2. עוברים לספריית הבסיס של פרויקט Wordcraft.
    cd wordcraft/
    
  3. מריצים את פקודת ההתקנה כדי להוריד את יחסי התלות ולהגדיר את הפרויקט:
    npm install
    

הגדרה של משתני סביבה

מגדירים את משתני הסביבה שנדרשים כדי לאפשר את ההפעלה של פרויקט הקוד של Wordcraft, במיוחד מפתח Google Gemini API. הוראות ההתקנה הבאות מיועדות למכונה מארחת של Linux.

כך מגדירים את משתני הסביבה:

  1. מקבלים מפתח Google Gemini API ומעתיקים את מחרוזת המפתח.
  2. עוברים לספריית השורש של פרויקט Wordcraft.
    cd wordcraft/
    
  3. מגדירים את מפתח ה-API כמשתנה סביבה. במארחים של Linux, משתמשים בפקודות הבאות.
    touch .env
    echo "API_KEY="<YOUR_API_KEY>"" > .env
    

בדיקת ההגדרה

עכשיו אמורה להיות אפשרות לבדוק את הגדרת הפרויקט על ידי הרצת Wordcraft במכשיר. השלב הזה הוא אופציונלי, אבל מומלץ.

מסך הפתיחה של Wordcraft

כדי לבדוק את ההתקנה וההגדרה:

  1. עוברים לספריית הבסיס של פרויקט Wordcraft.
    cd wordcraft/
    
  2. הפעלת הפרויקט במצב פיתוח:
    npm run dev
    
  3. בדפדפן האינטרנט, נכנסים לממשק המשתמש של Wordcraft. הכתובת הספציפית מופיעה בפלט של הפקודה הקודמת, לדוגמה:
    http://localhost:3000/
    

שינוי הטקסט לדוגמה של ההנחיה

ממשק משתמש לפקודות Wordcraft Wordcraft יוצר הנחיות למודל הגנרטיבי של AI באמצעות סדרת דוגמאות לכל פעולה של סיוע בכתיבה, כמו start new story ופקודות generate text. הדוגמאות מניעות את המודל הגנרטיבי ליצירת טקסט לסיפור שלכם, ובאמצעות שינוי הדוגמאות של פעולה אפשר לשנות את הפלט כך שיתאים לדפוס או לסגנון אחרים של כתיבה. הגישה הזו היא דרך פשוטה לגרום ל-Wordcraft לכתוב איך שרוצים.

הדוגמה הבאה מציגה שינוי של הדוגמאות של new_story ב-Wordcraft. מטרת השינוי הזה היא להנחות את המודל הגנרטיבי של ה-AI לכתוב הצגת סיפורים בגישת מונולוגיה פנימית ולהשתמש בסגנון שמתאים יותר לספר מסתורי. תוכלו לכתוב כמה דוגמאות להקדמה לסיפור, כדי שהמודל הגנרטיבי יהיה תואם לדפוס הכללי, אבל יהיה אפשר ליצור הקדמה לנושא אחר.

כדי לשנות את הדוגמאות של סיפורים חדשים ב-Wordcraft:

  1. פותחים את הקובץ wordcraft/app/context/json/new_story.json.
  2. משנים את הדוגמאות תוך שמירה על המבנה הכולל של קובץ ה-JSON. הנה דוגמה לשינוי להצגת סיפור מסתורי באמצעות סגנון מונולוגי פנימי.
    [
      {
        "topic": "scientist disappears and their research into a new technology is gone",
        "target": "I got the call from the chief early Tuesday morning, before I'd even had a second sip of coffee. Terrible timing. Something about a researcher disappearing from the local university. Unusual for the research lab to ask for assistance, so I headed over to main lab building."
      },
      {
        "topic": "a young woman wakes up with no memory",
        "target": "An unfamiliar ceiling with harsh, white lights greeted my eyes as I opened them. I looked around. White walls, medical equipment, a hospital? Wait. Where am I? How did I get here?!"
      },
      {
        "topic": "old man tries to recall an important task as his memories gradually fade away",
        "target": "What was I supposed to do today? Feels like it was important. I stared into the kitchen cabinet full of mismatched mugs, mirroring my own confusion. What was it? Like someone is...in danger? A chill shot down my spine, but the details skittered off and hid in some dark corner of my head."
      },
      {
        "topic": "billionaire is found dead in a hotel room",
        "target": "People meet their end every day, some naturally, some unnaturally. After 17 years of working as a homicide detective in Seattle, I'd seen a lot more of the unnatural variety than most. Comes with the job, along with a hard-learned sense of what side of the line any given incident sat on. This...was murder."
      },
      {
        "topic": "retired covert operative gets dragged back into an old mission",
        "target": "Steam rose gently off the cup of Earl Grey sitting in front of me as I sat at the cafe, pedestrians and light traffic rolling by. The city was slowly waking up around me and my perfect Paris morning routine was shaping up nicely. Then I noticed that old familiar and unwelcome tingling on the back of my neck. I was being watched."
      }
    ]
  3. שומרים את השינויים בקובץ 'new_story.json'.

כדי לבדוק את פעולת הסיפור החדש שהשתנה:

  1. עוברים לספריית הבסיס של פרויקט Wordcraft.
    cd wordcraft/
    
  2. מריצים את הפרויקט במצב פיתוח. אם היא כבר פועלת, יכול להיות שתצטרכו לעצור את האפליקציה ולהפעיל אותה מחדש.
    npm run dev
    
  3. בדפדפן האינטרנט, נכנסים לממשק המשתמש של Wordcraft. הכתובת הספציפית מופיעה בפלט של הפקודה הקודמת, לדוגמה:
    http://localhost:3000/
    
  4. עוברים לתפריט הראשי של Wordcraft ובוחרים באפשרות Start a New Story (התחלת סיפור חדש).
  5. מעדכנים את ההנחיה לסטורי החדש או משנים אותה למה שרוצים, ולוחצים על התחלת סטורי חדש.

אתם יכולים לשנות את כל אמצעי הבקרה הקיימים על כתיבת סיפורים ב-Wordcraft באמצעות השיטה הזו. כדי לשנות את אמצעי הבקרה האחרים של הסטורי על ידי עדכון הדוגמאות בספרייה wordcraft/app/context/json/.

יצירת בקרת כתיבה חדשה

ממשק משתמש להצגת דמויות של Wordcraft אפליקציית Wordcraft תוכננה להרחבה כדי שתוכלו להוסיף פקדי כתיבה חדשים שיעזרו לכם, בדומה ללחצנים יצירת טקסט או שכתוב משפט בכרטיסייה 'פקדים' בצד ימין של האפליקציה. ביצוע שינויים אלה הוא קצת יותר מאמץ, אבל מאפשר לכם לעצב את התכונות של Wordcraft בהתאם לתהליך העבודה וליעדים שלכם.

השינוי בדוגמה הבאה יוצר בקרת תווים חדשה ל-Wordcraft. אפשר להשתמש בו כדי להציג דמות חדשה בסיפור עם תיאור של המאפיינים של אותה דמות. הבסיס של אמצעי הבקרה הזה זהה לשימוש באמצעי הבקרה האחרים של Wordcraft, כמו אמצעי הבקרה התחלת הסיפור החדש. אתם יוצרים קובץ JSON עם כמה דוגמאות שממחישות איך להציג את התווים. בשאר השינויים יתווסף ממשק המשתמש ופונקציות ניהול ההנחיות של AI.

יצירת דוגמאות

כתבו כמה דוגמאות איך אתם רוצים שהמודל הגנרטיבי יציג דמויות. לדוגמה, האם ברצונך לתאר אותן כמו קריינים, או האם ברצונך להציג אותן דרך החוויה של הדמות הראשית שלך? בדוגמאות הבאות נעשה שימוש בגישה השנייה, ומציג דמויות חדשות מנקודת המבט של הדמות הראשית. את הדוגמאות האלה מוסיפים באמצעות קובץ JSON חדש:

כדי להוסיף דוגמאות לפקד החדש:

  1. יצירת קובץ wordcraft/app/context/json/new_character.json.
  2. יוצרים את הדוגמאות בקובץ ה-JSON. בדוגמה הזו, בכל דוגמה יש שדה תיאור character שמייצג את טקסט הפרומפטים, ושדה target שמציג את הפלט הצפוי.
    [
      {
        "character": "A character who is helpful and modest.",
        "target": "\"You lost, buddy?\" came a voice from behind me. Turning, I discovered a man dressed in a simple but presentable outfit. Small signs of age and loose threads hinted that these clothes, and the man himself, had seen better days."
      },
      {
        "character": "A character who is attractive and devious.",
        "target": "Stepping out of the alley a little too quickly, I collided with something solidly muscular and surprisingly delicately scented. \"Sorry.\" I managed, regaining my balance. \"Easy there, buddy, you're gonna hurt yourself,\" came the reply from a man with an almost feline grace, further reinforced by a stare that reminded me of a hunting cat assessing its potential prey."
      },
      {
        "character": "A character who is old and hesitant.",
        "target": "\"Excuse me. Do you know the way to the train station from here?\" I looked up from my phone to see a elderly woman in a threadbare coat, purse clutched with two hands in front of her. \"I-I'm supposed to meet my nephew there. Do... do you think you can help me?\""
      },
      {
        "character": "A character who is intelligent and aloof.",
        "target": "Bookish. That was my immediate reaction to this person I now saw in front of me. \"You're finally here. Did you read the notes I sent you?\" The voice sat squarely in between feminine and masculine intonation. \"No, of course you didn't.\" Dismissing my answer before I'd even formulated one. Annoyance immediately flushed through me."
      },
      {
        "character": "A character who is clumsy and energetic.",
        "target": "\"Whoa!\" was the only warning I had before someone slammed into my back, almost knocking me off my feet. \"I'm so sorry! WOOO! These skates are a RUSH!\" The apology came from a rather loud redhead wearing rollerblades, dark glasses and a very beefy-looking pair of headphones. That explained the volume of the apology."
      }
    ]
  3. שומרים את השינויים בקובץ new_character.json.

אחרי יצירת הדוגמאות, משנים את הקבצים app/context/schema.ts ו-index.ts כך שישקפו את תוכן ההנחיות של פקד התווים החדש.

כדי להוסיף את הדוגמאות לקובץ schema.ts:

  • משנים את הקובץ wordcraft/app/context/schema.ts כך שיכלול את מבנה הנתונים החדש לדוגמה.
    export const newStorySchema = z.object({
      topic: z.string(),
      target: z.string(),
    });
    
    // add the following:
    export const newCharacterSchema = z.object({
      character: z.string(),
      target: z.string(),
    });

מגדירים סוג פעולה שמשויך לדוגמאות החדשות האלה. בעזרת הסוג החדש, אפשר לחבר את הדוגמאות של ההנחיות לממשק המשתמש ולקוד בניית ההנחיות, שמשנים בהמשך.

כדי ליצור סוג פעולה חדש:

  • משנים את הקובץ wordcraft/app/core/shared/types.ts כדי להוסיף את סוג פעולת התו החדש.
    export const enum OperationType {
      ...
      NEW_CHARACTER = 'NEW_CHARACTER', // add to list of types
      ...
    }

כדי לרשום את הדוגמאות בקובץ index.ts:

  1. מייבאים את הסכימה החדשה בקובץ wordcraft/app/context/index.ts.
    import {
      continueSchema,
      ...
      newCharacterSchema // add new schema
    } from './schema';
    
  2. מייבאים את קובץ ה-JSON החדש בתור newCharacterJson.
    import newCharacterJson from './json/new_character.json';
    
  3. רושמים את התוכן לדוגמה של התו החדש בהקשר של האפליקציה.
    export class WordcraftContext {
      constructor() {
      ...
        this.registerExamples(
          OperationType.NEW_CHARACTER,
          newCharacterSchema,
          newCharacterJson
        );
      ...
    }
  4. ייצוא סוג NewCharacterExample.
    export type NewCharacterExample = z.infer<typeof newCharacterSchema>;
    

פיתוח ממשק משתמש

אחרי שיצרתם ורשמתם את הדוגמאות ליצירת תוכן, תוכלו ליצור את ממשק המשתמש לפקד החדש. רוב העבודה בשלב הזה היא יצירת מחלקת פעולה חדשה ורישום המחלקה הזו באמצעות הקוד הראשי של אפליקציית Wordcraft.

כדי ליצור פעולה חדשה:

  1. בספרייה wordcraft/app/core/operations/ יוצרים מחלקת פעולה חדשה באמצעות אחת ממחלקות הפעולות הקיימות כתבנית. כדי להשתמש בפקד התווים החדש, אפשר ליצור עותק של המחלקה new_story_operation.ts ולשנות את השם שלה ל-new_character_operation.ts.
  2. נותנים למחלקה שם חדש ומציינים מתי הפקד יופיע בממשק המשתמש, על ידי הגדרה של ערך OperationSite אחד לפחות.
    export class NewCharacterOperation extends ChoiceOperation {
      static override isAvailable(operationSite: OperationSite) {
        return (
          operationSite === OperationSite.END_OF_SECTION ||
          operationSite === OperationSite.EMPTY_SECTION
        );
      }
    
  3. מגדירים את id עבור הפעולה.
      static override id = OperationType.NEW_CHARACTER;
    
  4. מעדכנים את הפונקציות get ו-run כך שישקפו את הערכים של הפרמטרים של הסכימה. הקוד הזה מטפל בקבלה של טקסט הבקשה מממשק המשתמש לשימוש בהנחיה של ה-AI.
      private get character(): string {
        return NewCharacterOperation.controls.character.value;
      }
    
      async run() {
        const params = { character: this.character };
        const choices = await this.getModel().newCharacter(params);
    
        this.setChoices(choices);
      }
    
  5. עדכון הטקסט והתיאורים של ממשק המשתמש.
      static override getButtonLabel() {
        return 'introduce character';
      }
    
      static override getDescription() {
        return 'Introduce a new character at the cursor.';
      }
    
      static override controls = {
        character: new TextareaControl({
          prefix: 'prompt',
          description: 'A prompt to introduce a new character.',
          value: 'A new character.',
        }),
      };
    

כדי לרשום את הפעולה החדשה באפליקציה Wordcraft:

  1. בקובץ wordcraft/app/core/operations/index.ts, מוסיפים ייבוא של הפעולה החדשה.
    import {NewCharacterOperation} from './new_character_operation';
    
  2. באותו קובץ index.ts, מוסיפים ייצוא למחלקה NewCharacterOperation.
    export {
      ...
      NewCharacterOperation, // add this class
      ...
    };
  3. בקובץ wordcraft/app/main.ts, רושמים את הפעולה החדשה.
    const operationsService = wordcraftCore.getService(OperationsService);
    operationsService.registerOperations(
      ...
      Operations.NewCharacterOperation, // add new operation
      ...
    );
    

יצירת טיפול בהנחיות

בשלב האחרון של יצירת אמצעי הבקרה החדש, יוצרים את הקוד שמטפל ביצירת הנחיות למודל הגנרטיבי של AI ומטפל בתגובה. החלק העיקרי בעבודה הוא ליצור handler של הנחיות בספרייה wordcraft/app/models/gemini/prompts/, שמקבל קלט מממשק המשתמש ומרכיב הנחיה להעברה למודל הגנרטיבי.

כדי להגדיר ממשק לפרמטרים של ההנחיות:

  • בקובץ wordcraft/app/core/shared/interfaces.ts, מוסיפים ממשק לפרמטרים של הנחיות לפעולות החדשות.
    export interface NewCharacterPromptParams {
      character: string;
    }
    

כדי להגדיר handler של הנחיות לפעולה החדשה:

  1. בספרייה wordcraft/app/models/gemini/prompts/ יוצרים מחלקה חדשה של handler של הנחיות, תוך שימוש באחת ממחלקות הפעולות הקיימות כתבנית. כדי להשתמש בפקד התווים החדש, אפשר ליצור עותק של המחלקה new_story.ts ולשנות את השם שלה ל-new_character.ts כנקודת התחלה.
  2. מגדירים פונקציית handler של הנחיות ומייבאים את המחלקה NewCharacterExample.
    import { NewCharacterPromptParams } from '@core/shared/interfaces';
    import { NewCharacterExample, WordcraftContext } from '../../../context';
    import { OperationType } from '@core/shared/types';
    import { GeminiModel } from '..';
    
    export function makePromptHandler(model: GeminiModel, context: WordcraftContext) {
      ...
    }
    
  3. יצירת פונקציה generatePrompt() כדי לקבל את הקלט של ממשק המשתמש להנחיה של מודל ה-AI.
      function generatePrompt(character: string) {
        const prefix = "Here's a character description: ";
        const suffix = "Introduce this character in the story.";
    
        if (character.trim() === '') {
          return 'Introduce a new character to the story.';
        } else {
          return `${prefix}${model.wrap(character)}\n${suffix}`;
        }
      }
  4. יוצרים פונקציית getPromptContext() כדי להרכיב את הקלט של ממשק המשתמש עם התגובות לדוגמה, וליצור את ההנחיה המלאה.
      function getPromptContext() {
        const examples = context.getExampleData(
          OperationType.NEW_CHARACTER
        );
        let promptContext = model.getPromptPreamble();
        examples.forEach((example) => {
          const { character, target } = example;
          const prompt = generatePrompt(character);
          promptContext += `${prompt} ${model.wrap(target)}\n\n`;
        });
        return promptContext;
      }

כדי לשלב את ה-handler של שורת התווים החדשה:

  1. בקובץ wordcraft/app/models/gemini/index.ts, מייבאים את ה-handler של ההנחיות לפעולת התו החדש.
    import {makePromptHandler as newCharacter} from './prompts/new_character';
  2. מוסיפים הגדרת שינוי ל-handler של ההנחיות של newCharacter.
      override newCharacter = this.makePromptHandler(newCharacter);

כדי לרשום את הפרמטרים של ההנחיות עם הגדרת המודל:

  1. בקובץ wordcraft/app/models/model.ts, יש להוסיף ייבוא לממשק החדש של NewCharacterPromptParams.
    import {
      ...
      NewCharacterPromptParams,
      ...
    } from '@core/shared/interfaces';
  2. מוסיפים את הפרמטרים של ההנחיות מסוג newCharacter למחלקת המודל.
      async newCharacter(params: NewCharacterPromptParams): Promise<ModelResults> {
        throw new Error('Not yet implemented');
      }

בדיקה של פקד הכתיבה החדש

השליטה החדשה שלכם אמורה להיות מוכנה לבדיקה בממשק של Wordcraft. הקפידו לבדוק אם יש שגיאות בקוד לפני שתמשיכו.

כדי לבדוק את פקד התווים החדש:

  1. עוברים לספריית השורש של פרויקט Wordcraft.
    cd wordcraft/
    
  2. מריצים את הפרויקט במצב פיתוח:`
    npm run dev
    
  3. בדפדפן האינטרנט, נכנסים לממשק המשתמש של Wordcraft. הכתובת הספציפית מופיעה בפלט של הפקודה הקודמת, לדוגמה:
    http://localhost:3000/
    
  4. באפליקציית Wordcraft, יוצרים סטורי חדש או פותחים סטורי קיים.
  5. באזור העריכה של הסטורי, מזיזים את הסמן לסוף הסטורי. בכרטיסייה Controls בצד שמאל, אמור להופיע הפקד induction (תו ההקדמה).
  6. בשדה הצג תו מבוא, מקלידים תיאור קצר של התו החדש ולוחצים על הלחצן תו מבוא.

מקורות מידע נוספים

במאגר הקודים תוכלו לקרוא מידע נוסף על הפרויקט של Wordcraft. בבקשת המשיכה מפורטות השינויים שמתוארים במדריך הזה.

אפליקציות ייצור

אם אתם מתכננים לפרוס גרסה מותאמת אישית של Wordcraft לקהל גדול, שימו לב שהשימוש שלכם ב-Google Gemini API עשוי להיות כפוף להגבלת קצב של יצירת בקשות ולהגבלות שימוש נוספות. אם אתם שוקלים לפתח אפליקציה בסביבת ייצור באמצעות Gemini API, כמו Docs Agent, כדאי לבדוק את שירותי Google Cloud Vertex AI כדי לשפר את יכולת ההתאמה ואת האמינות של האפליקציה.