故事我們喜歡故事,述說故事和採用其他形式的創意寫作 不僅困難重重,也更值得回報然而,從空白網頁建構自己的故事 似乎相當困難,有時甚至令人頭昏腦脹人工智慧 (AI) 生成式模型是非常實用的工具,可協助您擺脫空白的頁面,建立論述內容。
本教學課程說明如何擴充 Wordcraft,這是由 Google 人力與 AI 研究團隊打造的 AI 技術輔助故事撰寫工具。這個網頁應用程式使用 Gemini API 協助您建構故事,而且要有初步的生成概念、撰寫報導部分,以及修改內容以新增更多詳細資料。您可以修改 Wordcraft,讓自己的寫作更符合自己的風格,並建構新的寫作控制項,讓工作流程更完善。
如需專案簡介影片並瞭解如何延伸,包括建構程式開發人員的深入分析,請查看 AI Writer Assistant - Build with 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 的主選單,然後選取「Start a New Story」(開始新故事)。
- 更新新的故事提示或將其變更為所需內容,然後選取「start new story」(建立新的故事)。
您可以使用這個技巧,修改 Wordcraft 中的所有現有的故事撰寫控制項。嘗試透過更新 wordcraft/app/context/json/
目錄中的範例來變更其他故事控制項。
建立新的書寫控制項
Wordcraft 應用程式經過精心設計,您可以擴充應用程式的新撰寫控制項,就像應用程式右側「控制項」分頁中的產生文字或重新撰寫句子按鈕一樣。要進行這些修改雖然有些繁瑣,但您可以依據自己的工作流程和目標調整 Word 生成的功能。
以下範例修改內容會為 Wordcraft 建立新的字元控制項。您可以用它為故事引入新角色,並提供該角色的屬性說明。這個控制項的基礎與先前討論的其他 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」分頁中,應會顯示「引入字元」控制項。
- 在「Intro character」欄位中,輸入新字元的簡短說明,然後選取「Intro character」按鈕。
其他資源
如要進一步瞭解 Wordcraft 專案,請參閱程式碼存放區。您可在此提取要求中,查看本教學課程中所述的變更。
正式版應用程式
如果您打算為大量目標對象部署自訂的 Wordcraft 版本,請注意使用 Google Gemini API 時可能必須遵守頻率限制和其他使用限制。如果您考慮使用 Gemini API (例如文件代理程式) 建構正式版應用程式,請查看 Google Cloud Vertex AI 服務,以提高應用程式的擴充性和可靠性。