Wordcraft로 AI 글쓰기 도우미 빌드

우리는 스토리를 좋아합니다. 이야기를 전달하고 다른 형태의 창의적인 글쓰기를 하는 것은 어렵고 보람이 있을 수 있습니다. 하지만 빈 페이지에서 나만의 이야기를 만드는 것은 어렵고 때로는 부담스러울 수도 있습니다. 인공지능 (AI) 생성 모델은 빈 페이지에서 벗어나 내러티브를 구축하는 데 유용한 도구가 될 수 있습니다.

이 가이드에서는 Google 인력 및 AI 연구팀에서 빌드한 AI 기반 스토리 작성 도구인 Wordcraft를 확장하는 방법을 보여줍니다. 이 웹 애플리케이션은 Gemini API를 사용하여 아이디어를 생성하고, 스토리의 일부를 작성하고, 콘텐츠를 수정하여 세부정보를 추가하여 조금씩 스토리를 빌드할 수 있도록 지원합니다. 자신의 글쓰기 스타일에 맞게 Wordcraft를 수정하고 새로운 쓰기 컨트롤을 빌드하여 워크플로를 더 잘 지원할 수 있습니다.

AI 작성 어시스턴트 - Google AI로 빌드에서 프로젝트 및 프로젝트 확장 방법에 관한 동영상 개요와 프로젝트를 빌드하는 담당자의 유용한 정보를 확인할 수 있습니다. 그렇지 않은 경우 아래 안내에 따라 프로젝트 확장을 시작할 수 있습니다.

프로젝트 설정

다음 안내는 개발 및 테스트를 위해 Wordcraft 프로젝트를 설정하는 방법을 안내합니다. 필수 소프트웨어를 설치하고, 코드 저장소에서 프로젝트를 클론하고, 구성 설치를 실행하고, 몇 가지 환경 변수를 설정해야 합니다. 이 단계를 완료한 후 프로젝트를 실행하여 설정을 테스트할 수 있습니다.

기본 요건 설치

Wordcraft 프로젝트는 Node와 npm을 사용하여 패키지를 관리하고 애플리케이션을 실행합니다. 다음 설치 안내는 Linux 호스트 머신용입니다.

필요한 소프트웨어를 설치하려면 다음 단계를 따르세요.

  • 플랫폼의 설치 안내에 따라 nodenpm를 설치합니다.

프로젝트 클론 및 구성

프로젝트 코드를 다운로드하고 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 생성 모델에 대한 프롬프트를 만듭니다. 예시는 생성 모델이 스토리의 텍스트를 생성하는 과정을 안내합니다. 작업 예시를 수정하면 다른 작성 패턴이나 스타일을 따르도록 출력을 변경할 수 있습니다. 이 접근 방식을 사용하면 Wordcraft를 원하는 방식으로 쓸 수 있습니다.

다음 예는 Wordcraft의 new_story 예를 수정한 것입니다. 이 수정의 목표는 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 기본 메뉴로 이동한 다음 새 스토리 시작을 선택합니다.
  5. 새 스토리 프롬프트를 업데이트하거나 원하는 대로 변경한 후 새 스토리 시작을 선택합니다.

이 기법을 사용하여 Wordcraft의 모든 기존 스토리 쓰기 컨트롤을 수정할 수 있습니다. wordcraft/app/context/json/ 디렉터리의 예를 업데이트하여 다른 스토리 컨트롤 변경 시도

새 쓰기 제어 기능 만들기

Wordcraft 캐릭터 사용자 인터페이스 소개 Wordcraft 앱은 확장되도록 설계되어 앱 오른쪽의 컨트롤 탭에 있는 텍스트 생성 또는 문장 재작성 버튼과 유사한 새로운 쓰기 컨트롤을 추가하여 도움을 받을 수 있습니다. 수정 작업은 좀 더 번거로울 수 있지만 워크플로와 목표에 맞게 Wordcraft의 기능을 만들 수 있습니다.

다음 예에서는 Wordcraft의 새 문자 컨트롤을 만듭니다. 이를 통해 캐릭터의 속성에 대한 설명과 함께 스토리에 새로운 캐릭터를 소개할 수 있습니다. 이 컨트롤의 기반은 앞에서 설명한 start new Story 컨트롤과 같은 다른 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.tsindex.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. 스키마 매개변수의 값을 반영하도록 getrun 함수를 업데이트합니다. 이 코드는 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 생성 모델의 프롬프트 생성을 처리하고 응답을 처리하는 코드를 만듭니다. 작업의 주요 부분은 wordcraft/app/models/gemini/prompts/ 디렉터리에 사용자 인터페이스의 입력을 받아 생성 모델에 전달할 프롬프트를 조합하는 프롬프트 핸들러를 빌드하는 것입니다.

프롬프트 매개변수의 인터페이스를 정의하는 방법은 다음과 같습니다.

  • wordcraft/app/core/shared/interfaces.ts 파일에서 매개변수를 표시하는 새 작업의 인터페이스를 추가합니다.
    export interface NewCharacterPromptParams {
      character: string;
    }
    

새 작업에 대한 프롬프트 핸들러를 정의하려면 다음 안내를 따르세요.

  1. wordcraft/app/models/gemini/prompts/ 디렉터리에서 기존 작업 클래스 중 하나를 템플릿으로 사용하여 새 프롬프트 핸들러 클래스를 만듭니다. 새 문자 컨트롤의 경우 new_story.ts 클래스의 사본을 만들고 시작점으로 이름을 new_character.ts로 바꿀 수 있습니다.
  2. 프롬프트 핸들러 함수를 정의하고 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;
      }

새 문자 프롬프트 핸들러를 통합하려면 다음 단계를 따르세요.

  1. wordcraft/app/models/gemini/index.ts 파일에서 새 문자 작업을 위한 프롬프트 핸들러를 가져옵니다.
    import {makePromptHandler as newCharacter} from './prompts/new_character';
  2. 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 탭에 소개 캐릭터 컨트롤이 표시되어야 합니다.
  6. 소개 캐릭터 필드에 새 캐릭터에 관한 간단한 설명을 입력한 후 소개 캐릭터 버튼을 선택합니다.

추가 리소스

Wordcraft 프로젝트에 관한 자세한 내용은 코드 저장소를 참고하세요. 이 가이드에 설명된 변경사항은 이 pull 요청에서 확인할 수 있습니다.

프로덕션 애플리케이션

대규모 사용자를 위해 맞춤 버전의 Wordcraft를 배포하려는 경우 Google Gemini API 사용에 비율 제한 및 기타 사용 제한이 적용될 수 있습니다. Docs 에이전트와 같은 Gemini API로 프로덕션 애플리케이션을 빌드하려는 경우 Google Cloud Vertex AI 서비스를 확인하여 앱의 확장성과 안정성을 높이세요.