우리는 스토리를 좋아합니다. 이야기를 전달하고 다른 형태의 창의적인 글쓰기를 하는 것은 어렵고 보람이 있을 수 있습니다. 하지만 빈 페이지에서 나만의 이야기를 만드는 것은 어렵고 때로는 부담스러울 수도 있습니다. 인공지능 (AI) 생성 모델은 빈 페이지에서 벗어나 내러티브를 구축하는 데 유용한 도구가 될 수 있습니다.
이 가이드에서는 Google 인력 및 AI 연구팀에서 빌드한 AI 기반 스토리 작성 도구인 Wordcraft를 확장하는 방법을 보여줍니다. 이 웹 애플리케이션은 Gemini API를 사용하여 아이디어를 생성하고, 스토리의 일부를 작성하고, 콘텐츠를 수정하여 세부정보를 추가하여 조금씩 스토리를 빌드할 수 있도록 지원합니다. 자신의 글쓰기 스타일에 맞게 Wordcraft를 수정하고 새로운 쓰기 컨트롤을 빌드하여 워크플로를 더 잘 지원할 수 있습니다.
AI 작성 어시스턴트 - Google AI로 빌드에서 프로젝트 및 프로젝트 확장 방법에 관한 동영상 개요와 프로젝트를 빌드하는 담당자의 유용한 정보를 확인할 수 있습니다. 그렇지 않은 경우 아래 안내에 따라 프로젝트 확장을 시작할 수 있습니다.
프로젝트 설정
다음 안내는 개발 및 테스트를 위해 Wordcraft 프로젝트를 설정하는 방법을 안내합니다. 필수 소프트웨어를 설치하고, 코드 저장소에서 프로젝트를 클론하고, 구성 설치를 실행하고, 몇 가지 환경 변수를 설정해야 합니다. 이 단계를 완료한 후 프로젝트를 실행하여 설정을 테스트할 수 있습니다.
기본 요건 설치
Wordcraft 프로젝트는 Node와 npm을 사용하여 패키지를 관리하고 애플리케이션을 실행합니다. 다음 설치 안내는 Linux 호스트 머신용입니다.
필요한 소프트웨어를 설치하려면 다음 단계를 따르세요.
- 플랫폼의 설치 안내에 따라
node
및npm
를 설치합니다.
프로젝트 클론 및 구성
프로젝트 코드를 다운로드하고 npm
설치 명령어를 사용하여 필요한 종속 항목을 다운로드하고 프로젝트를 구성합니다. 프로젝트 소스 코드를 검색하려면 git 소스 제어 소프트웨어가 필요합니다.
프로젝트 코드를 다운로드하고 구성하려면 다음 안내를 따르세요.
- 다음 명령어를 사용하여 git 저장소를 클론합니다.
git clone https://github.com/PAIR-code/wordcraft
- Wordcraft 프로젝트 루트 디렉터리로 이동합니다.
cd wordcraft/
- 설치 명령어를 실행하여 종속 항목을 다운로드하고 프로젝트를 구성합니다.
npm install
환경 변수 설정하기
Wordcraft 코드 프로젝트 실행을 허용하는 데 필요한 환경 변수, 특히 Google Gemini API 키를 설정합니다. 다음 설치 안내는 Linux 호스트 머신용입니다.
환경 변수를 설정하려면 다음 안내를 따르세요.
- Google Gemini API 키를 가져오고 키 문자열을 복사합니다.
- Wordcraft 프로젝트 루트 디렉터리로 이동합니다.`
cd wordcraft/
- API 키를 환경 변수로 설정합니다. Linux 호스트에서는 다음 명령어를 사용합니다.
touch .env echo "API_KEY="<YOUR_API_KEY>"" > .env
설정 테스트
이제 기기에서 Wordcraft를 실행하여 프로젝트 설정을 테스트할 수 있습니다. 이 단계는 옵션이지만 권장됩니다.
설치 및 설정을 테스트하려면 다음 안내를 따르세요.
- Wordcraft 프로젝트 루트 디렉터리로 이동합니다.
cd wordcraft/
- 개발 모드에서 이 요소로 프로젝트 실행:
npm run dev
- 웹브라우저에서 Wordcraft 사용자 인터페이스로 이동합니다. 특정 주소는 이전 명령어의 출력에 표시됩니다. 예:
http://localhost:3000/
프롬프트 예시 텍스트 수정
Wordcraft는 새 이야기 시작 및 텍스트 생성 명령어와 같은 각 쓰기 지원 작업에 대한 일련의 예를 사용하여 AI 생성 모델에 대한 프롬프트를 만듭니다. 예시는 생성 모델이 스토리의 텍스트를 생성하는 과정을 안내합니다. 작업 예시를 수정하면 다른 작성 패턴이나 스타일을 따르도록 출력을 변경할 수 있습니다. 이 접근 방식을 사용하면 Wordcraft를 원하는 방식으로 쓸 수 있습니다.
다음 예는 Wordcraft의 new_story
예를 수정한 것입니다. 이 수정의 목표는 AI 생성 모델이 내부 독백 접근 방식을 사용하여 스토리 도입부를 작성하고 미스터리 소설에 더 적합한 스타일을 사용하도록 지시하는 것입니다. 이러한 종류의 스토리 소개에 관한 몇 가지 예를 작성하면 생성 모델이 일반적인 패턴을 따르면서 다른 테마의 소개를 생성할 수 있습니다.
Wordcraft에서 새 스토리 예시를 수정하려면 다음 단계를 따르세요.
wordcraft/app/context/json/new_story.json
파일을 엽니다.- 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." } ]
- 변경사항을 `new_story.json` 파일에 저장합니다.
수정된 새 스토리 작업을 테스트하려면 다음 단계를 따르세요.
- Wordcraft 프로젝트 루트 디렉터리로 이동합니다.
cd wordcraft/
- 개발 모드에서 프로젝트를 실행합니다. 이미 실행 중이면 앱을 중지하고 다시 시작해야 할 수 있습니다.
npm run dev
- 웹브라우저에서 Wordcraft 사용자 인터페이스로 이동합니다. 특정 주소는 이전 명령어의 출력에 표시됩니다. 예:
http://localhost:3000/
- Wordcraft 기본 메뉴로 이동한 다음 새 스토리 시작을 선택합니다.
- 새 스토리 프롬프트를 업데이트하거나 원하는 대로 변경한 후 새 스토리 시작을 선택합니다.
이 기법을 사용하여 Wordcraft의 모든 기존 스토리 쓰기 컨트롤을 수정할 수 있습니다. wordcraft/app/context/json/
디렉터리의 예를 업데이트하여 다른 스토리 컨트롤 변경 시도
새 쓰기 제어 기능 만들기
Wordcraft 앱은 확장되도록 설계되어 앱 오른쪽의 컨트롤 탭에 있는 텍스트 생성 또는 문장 재작성 버튼과 유사한 새로운 쓰기 컨트롤을 추가하여 도움을 받을 수 있습니다. 수정 작업은 좀 더 번거로울 수 있지만 워크플로와 목표에 맞게 Wordcraft의 기능을 만들 수 있습니다.
다음 예에서는 Wordcraft의 새 문자 컨트롤을 만듭니다. 이를 통해 캐릭터의 속성에 대한 설명과 함께 스토리에 새로운 캐릭터를 소개할 수 있습니다. 이 컨트롤의 기반은 앞에서 설명한 start new Story 컨트롤과 같은 다른 Wordcraft 컨트롤과 동일합니다. 문자를 도입하는 방법에 대한 몇 가지 예시가 포함된 JSON 파일을 만듭니다. 나머지 변경사항은 사용자 인터페이스 및 AI 프롬프트 관리 기능을 추가합니다
예시 만들기
생성 모델에서 캐릭터를 어떻게 소개하고 싶은지 몇 가지 예를 작성하세요. 예를 들어 내레이터처럼 설명하고 싶으신가요? 아니면 주인공의 경험으로 소개하고 싶으신가요? 다음 예에서는 후자의 접근 방식을 사용하여 주인공의 관점에서 새로운 캐릭터를 소개합니다. 새 JSON 파일과 함께 다음 예를 추가합니다.
새 컨트롤에 예를 추가하려면 다음 단계를 따르세요.
wordcraft/app/context/json/new_character.json
파일을 만듭니다.- 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." } ]
- 변경사항을
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
파일에 예시를 등록하려면 다음 안내를 따르세요.
wordcraft/app/context/index.ts
파일에서 새 스키마를 가져옵니다.import { continueSchema, ... newCharacterSchema // add new schema } from './schema';
- 새 JSON 파일을
newCharacterJson
로 가져옵니다.import newCharacterJson from './json/new_character.json';
- 새 문자 예시 콘텐츠를 애플리케이션 컨텍스트에 등록합니다.
export class WordcraftContext { constructor() { ... this.registerExamples( OperationType.NEW_CHARACTER, newCharacterSchema, newCharacterJson ); ... }
NewCharacterExample
유형을 내보냅니다.export type NewCharacterExample = z.infer<typeof newCharacterSchema>;
사용자 인터페이스 빌드
콘텐츠 생성 예를 만들고 등록한 후에는 새 컨트롤의 사용자 인터페이스를 만들 수 있습니다. 이 단계에서 대부분의 작업은 새 작업 클래스를 만든 다음 이 클래스를 Wordcraft 애플리케이션의 기본 코드에 등록하는 것입니다.
새 작업을 만들려면 다음 안내를 따르세요.
wordcraft/app/core/operations/
디렉터리에서 기존 작업 클래스 중 하나를 템플릿으로 사용하여 새 작업 클래스를 만듭니다. 새 문자 컨트롤의 경우new_story_operation.ts
클래스의 사본을 만들어new_character_operation.ts
로 이름을 바꿀 수 있습니다.- 클래스에 새 이름을 지정하고 하나 이상의
OperationSite
값을 정의하여 컨트롤이 사용자 인터페이스에 표시되는 시점을 지정합니다.export class NewCharacterOperation extends ChoiceOperation { static override isAvailable(operationSite: OperationSite) { return ( operationSite === OperationSite.END_OF_SECTION || operationSite === OperationSite.EMPTY_SECTION ); }
- 작업의
id
를 설정합니다.static override id = OperationType.NEW_CHARACTER;
- 스키마 매개변수의 값을 반영하도록
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); }
- 사용자 인터페이스 텍스트 및 설명을 업데이트합니다.
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 애플리케이션에 새 작업을 등록하려면 다음 안내를 따르세요.
wordcraft/app/core/operations/index.ts
파일에서 새 작업의 가져오기를 추가합니다.import {NewCharacterOperation} from './new_character_operation';
- 동일한
index.ts
파일에서NewCharacterOperation
클래스의 내보내기를 추가합니다.export { ... NewCharacterOperation, // add this class ... };
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; }
새 작업에 대한 프롬프트 핸들러를 정의하려면 다음 안내를 따르세요.
wordcraft/app/models/gemini/prompts/
디렉터리에서 기존 작업 클래스 중 하나를 템플릿으로 사용하여 새 프롬프트 핸들러 클래스를 만듭니다. 새 문자 컨트롤의 경우new_story.ts
클래스의 사본을 만들고 시작점으로 이름을new_character.ts
로 바꿀 수 있습니다.- 프롬프트 핸들러 함수를 정의하고
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) { ... }
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}`; } }
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; }
새 문자 프롬프트 핸들러를 통합하려면 다음 단계를 따르세요.
wordcraft/app/models/gemini/index.ts
파일에서 새 문자 작업을 위한 프롬프트 핸들러를 가져옵니다.import {makePromptHandler as newCharacter} from './prompts/new_character';
newCharacter
프롬프트 핸들러에 재정의 정의를 추가합니다.override newCharacter = this.makePromptHandler(newCharacter);
프롬프트 매개변수를 모델 정의와 함께 등록하려면 다음 안내를 따르세요.
wordcraft/app/models/model.ts
파일에서 새NewCharacterPromptParams
인터페이스 가져오기를 추가합니다.import { ... NewCharacterPromptParams, ... } from '@core/shared/interfaces';
newCharacter
프롬프트 매개변수를 모델 클래스에 추가합니다.async newCharacter(params: NewCharacterPromptParams): Promise<ModelResults> { throw new Error('Not yet implemented'); }
새로운 쓰기 제어 기능 테스트
이제 Wordcraft 인터페이스에서 새 컨트롤을 테스트할 수 있습니다. 계속하기 전에 코드에 컴파일 오류가 있는지 확인하세요.
새 문자 컨트롤을 테스트하려면 다음 단계를 따르세요.
- Wordcraft 프로젝트 루트 디렉터리로 이동합니다.`
cd wordcraft/
- 개발 모드에서 프로젝트를 실행합니다.`
npm run dev
- 웹브라우저에서 Wordcraft 사용자 인터페이스로 이동합니다. 특정 주소는 이전 명령어의 출력에 표시됩니다. 예:
http://localhost:3000/
- Wordcraft 애플리케이션에서 새 스토리를 만들거나 기존 스토리를 엽니다.
- 스토리 수정 영역에서 스토리의 끝 부분으로 커서를 이동합니다. 오른쪽의 Controls 탭에 소개 캐릭터 컨트롤이 표시되어야 합니다.
- 소개 캐릭터 필드에 새 캐릭터에 관한 간단한 설명을 입력한 후 소개 캐릭터 버튼을 선택합니다.
추가 리소스
Wordcraft 프로젝트에 관한 자세한 내용은 코드 저장소를 참고하세요. 이 가이드에 설명된 변경사항은 이 pull 요청에서 확인할 수 있습니다.
프로덕션 애플리케이션
대규모 사용자를 위해 맞춤 버전의 Wordcraft를 배포하려는 경우 Google Gemini API 사용에 비율 제한 및 기타 사용 제한이 적용될 수 있습니다. Docs 에이전트와 같은 Gemini API로 프로덕션 애플리케이션을 빌드하려는 경우 Google Cloud Vertex AI 서비스를 확인하여 앱의 확장성과 안정성을 높이세요.