使用 Wordcraft 打造 AI 写作助理

我们热爱故事。讲故事以及进行其他形式的创意写作 既具有挑战性又回报丰厚从空白页面制作自己的故事, 但有时可能会令人望而生畏,甚至有点不知所措。人造 生成式 AI 模型可以成为一个很好的工具, 创建您自己的叙事内容

本教程介绍了如何将 Wordcraft、 一款由 Google 人与 AI 研究团队开发的 AI 赋能的故事撰写工具 团队。此 Web 应用使用的是 Gemini 可帮助您通过构思想法、撰写部分内容,逐步构建故事的 API 您的故事,以及修改内容以添加更多细节。您可以修改 Wordcraft 更贴近您自己的写作风格,并开发新的写作控件 更好地支持您的工作流程

通过视频简要了解项目以及如何扩展项目(包括数据洞见) 敬请查看 AI 撰写助理 - 使用 Google AI 进行构建。 否则,您可以按照说明开始扩展项目 。

项目设置

以下说明会引导您完成 Wordcraft 项目的设置流程, 开发和测试。你需要安装必备软件,克隆 从代码库中创建项目,运行配置安装, 设置一些环境变量您可以通过运行项目来测试设置 。

安装必备项

Wordcraft 项目使用 Node 和 npm 来管理 打包并运行应用以下是安装说明 运行 25 万个 Pod

如需安装所需的软件,请执行以下操作:

克隆并配置项目

下载项目代码并使用 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 开始屏幕

如需测试安装和设置,请执行以下操作:

  1. 进入 Wordcraft 项目根目录。
    cd wordcraft/
    
  2. 在开发模式下通过它运行项目:
    npm run dev
    
  3. 在网络浏览器中,导航到 Wordcraft 界面。通过 特定地址显示在上一个命令的输出中,例如:
    http://localhost:3000/
    

修改提示示例文本

Wordcraft 命令界面 Wordcraft 使用一组示例为 AI 生成模型创建提示, 每项写作辅助操作,例如开始新故事生成 text 命令。这些示例将指导生成模型为 通过修改操作的示例,您可以更改 采用不同的写作模式或风格。这种方法 让 Wordcraft 随心所欲地书写。

以下示例展示了对 Google Cloud 控制台中的 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 的主菜单,然后选择 Start a New Story
  5. 更新新的故事提示或将其更改为所需内容,然后选择 开始新故事

您可以使用此 分析法。尝试通过更新 wordcraft/app/context/json/ 目录中。

创建新的书写控件

《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.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 生成模型生成提示,并处理回答。 这项工作的主要部分是在 Vertex AI Workbench 中 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. 在故事编辑区域中,将光标移至故事末尾。在 介绍角色控件 。
  6. 介绍字符字段中,输入 选择一个新角色,然后选择介绍角色按钮。

其他资源

有关 Wordcraft 项目的详情,请参阅代码 代码库。您可以查看 本教程中介绍的更改 拉取请求

生产应用

如果您打算为广大受众群体部署自定义版《Wordcraft》, 请注意,使用 Google Gemini API 可能会受到速率限制 其他 使用限制。 如果您在考虑使用 Gemini API 构建正式版应用,比如 文档代理,请查看 Google Cloud Vertex AI 以提高应用的可伸缩性和可靠性。