百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

AI驱动的表单自动填写(ai置入表格)

zhezhongyun 2025-04-30 21:18 1 浏览

我们都同意,填写表格是一项枯燥且耗时的任务。如果我们可以创建一个可以为我们填写表格的 AI 助手,让我们将时间投入到更有建设性的任务中,那会怎样?

AI 助手将能够通过调用以表单字段为参数的函数来填写表单。该函数将返回一个 JSON 对象,其中表单字段作为键,值作为要填写的值。

网络上有无数的表单,每个表单都有自己独特的结构和命名约定。直到最近,几乎不可能创建一个可以填写任何表格的通用助手。但随着 LLM 的出现,我们可以创建一个。

在大多数情况下,函数调用允许 LLM 与 API 交互,但绝大多数 Web 应用程序不公开 API,与它们交互的唯一方法是填写表格。

本文的受众

本文适用于想要了解大型语言模型 (LLM)(如 OpenAI 或 Anthropic)“函数调用”功能基础知识的程序员。

函数调用是 LLM 的基本功能,允许创建可以与外部世界交互的专用工具、代理或助手。本文将向你展示如何创建一个可以填写 HTML 表单的简单 AI 助手。

你将学到什么

通过为 LLM 提供函数签名的定义来启用函数调用。函数签名是函数预期输入属性的描述。

你将学习如何创建动态生成的 JSON 模式函数签名,允许 AI 助手与 HTML 表单交互。

JSON 模式是定义和验证 JSON 对象结构的强大工具。出于教育目的,将不使用任何外部库,只使用纯 JavaScript 代码。

1、原理及实现代码

表单可能彼此非常不同,但它们都是使用输入字段、文本区域、复选框、单选按钮等常见元素构建的。

我们将仅讨论脚本中最重要的部分。完整脚本可在此处找到。

首先,我们需要识别表单元素及其类型。无论元素类型如何,每个元素都应该有一个 name属性,该属性稍后将用作 JSON 对象中的键。

对于每种元素类型,我们将创建一个函数,该函数将返回定义元素的 JSON 模式片段。JSON 模式应包含元素用途的描述。

这对于 LLM 了解元素的用途或预期值非常有用。描述的文本将从元素的标签或占位符属性中收集。

每个元素的 Json 模式属性至少包含:

  • name:元素的名称
  • type:元素类型,通常是字符串
  • description:元素描述

然后我们可以根据元素类型拥有更多附加字段。例如,对于输入元素,我们可以有最小、最大、模式和必填字段。

对于选择元素、单选或复选框元素,我们还添加了包含所有可能值的枚举字段。特定的复选框和单选元素应该以特殊方式处理,因为它们可以具有与一个名称相关的多个值选项。

const getInputSchema = (input) => {
  const { name, type, min, max, pattern, required } = input;
  if (!name) return null;

  const schema = {
    name,
    type: type === 'number' ? 'number' : 'string',
    description: getElementDescription(input),
  };

  if (min) schema.minimum = Number(min);
  if (max) schema.maximum = Number(max);
  if (pattern) schema.pattern = pattern;

  return [formatName(name), schema, required];
};

const getSelectSchema = (select) => {
  const { name, required } = select;
  if (!name) return null;

  return [
    formatName(name),
    {
      name,
      type: 'string',
      description: getElementDescription(select),
      enum: Array.from(select.options).map((option) => option.value),
    },
    required,
  ];
};

const getTextareaSchema = (textArea) => {
  const { name, required } = textArea;
  if (!name) return null;

  return [
    formatName(name),
    { name, type: 'string', description: getElementDescription(textArea) },
    required,
  ];
};

const getCheckboxesSchema = ([name, values]) => {
  const element = document.querySelector(`[name="${name}"]`);
  const isArray = name.endsWith('[]');

  const schema = {
    name,
    type: isArray ? 'array' : 'boolean',
    description: getDescription(element),
  };

  if (isArray) {
    schema.uniqueItems = true;
    schema.items = { oneOf: values };
  }

  return [formatName(name), schema];
};

const getRadioSchema = ([name, values]) => {
  const element = document.querySelector(`[name="${name}"]`);
  return [
    formatName(name),
    {
      name,
      type: 'string',
      description: getDescription(element),
      enum: values.map((v) => v.const),
    },
  ];
};

现在我们来到最重要的函数,它将使用所有可用的函数为每个表单生成模式。

const generateSchema = (form) => {
  const inputSelectors = [
    'input[type="text"]',
    'input[type="email"]',
    'input[type="number"]',
    'input[type="password"]',
    'input[type="tel"]',
    'input[type="url"]',
    'input[type="date"]',
    'input[type="time"]',
    'input[type="datetime-local"]',
    'input[type="month"]',
    'input[type="week"]',
    'input[type="color"]',
    'input[type="range"]',
    'input[type="search"]',
  ].join(', ');

  const inputs = Array.from(form.querySelectorAll(inputSelectors))
    .map(getInputSchema)
    .filter(Boolean);
  const checkboxes = groupByName(
    Array.from(form.querySelectorAll('input[type="checkbox"]'))
  ).map(getCheckboxesSchema);
  const radios = groupByName(
    Array.from(form.querySelectorAll('input[type="radio"]'))
  ).map(getRadioSchema);
  const selects = Array.from(form.getElementsByTagName('select'))
    .map(getSelectSchema)
    .filter(Boolean);
  const textAreas = Array.from(form.getElementsByTagName('textarea'))
    .map(getTextareaSchema)
    .filter(Boolean);

  const schemaProps = [
    ...inputs,
    ...checkboxes,
    ...radios,
    ...selects,
    ...textAreas,
  ];
  const required = schemaProps.filter(([, , r]) => r).map(([name]) => name);

  return {
    name: 'fillup_form',
    description: 'Schema to fill form inputs',
    parameters: {
      type: 'object',
      required,
      properties: Object.fromEntries(
        schemaProps.map(([name, schema]) => [name, schema])
      ),
    },
  };
};

此函数扫描表单中的所有输入元素并为每个元素创建一个架构。它按名称对复选框和单选按钮进行分组,并为每个组创建一个架构。最后,它创建一个包含所有表单元素的 JSON 架构。

在这里,我们定义了一个将调用 OpenAI chat completitions API 的函数。我们提供模型名称(在本例中为“gpt-4o”,这保证了函数调用的良好结果)和 API 密钥,同时我们将“温度”设置为 0 以获得确定性结果。

const callOpenAiAPI = async ({
  api_key,
  model = 'gpt-4o',
  max_tokens = 3024,
  tools,
  messages,
}) => {
  try {
    const response = await fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${api_key}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model,
        max_tokens,
        temperature: 0,
        tools,
        messages,
      }),
    });
    return await response.json();
  } catch (error) {
    console.error('Error calling OpenAI API:', error);
    throw error;
  }
};

最后,我们可以向 OpenAI API 提交请求,并用响应填写表单。我们利用“工具”功能提供生成的模式。在这里,我们使用“自动”工具选择让 OpenAI 选择最适合该工作的工具。

我们将要填写在表单中的数据作为消息提供给 AI 助手,使用非常简单的提示调用 fillup_form,其中包含以下数据: \n${data}。

我们可以以类似的方式调用 Anthropic API,而不是 openAi。

const submitForm = async (submitButton, form, formId) => {
  submitButton.classList.add('spinner');
  const formSchema = generateSchema(form);
  const data = document.getElementById(`_data_${formId}`).value;
  const apiKey = document.getElementById(`_api-key_${formId}`).value;

  try {
    const llmResponse = await callOpenAiAPI({
      api_key: apiKey,
      tools: [{ type: 'function', function: formSchema }],
      tool_choice: 'auto',
      messages: [
        {
          role: 'user',
          content: `call "fillup_form" with following data:\n${data}`,
        },
      ],
    });

    const rawData =
      llmResponse.choices[0].message?.tool_calls?.[0]?.function?.arguments ||
      llmResponse.choices[0].message?.content;
    const inputData = Object.entries(JSON.parse(rawData));
    fillForm(formSchema.parameters.properties, inputData);
  } catch (error) {
    console.error('Error processing form submission:', error);
  } finally {
    submitButton.classList.remove('spinner');
  }
};

上述函数返回来自 OpenAI API 的响应,其中对象将表单字段映射到要填写的值。然后我们调用 fillForm 函数用响应填充表单。瞧!表单已填写。

const fillForm = (formFields, inputData) => {
  inputData.forEach(([name, value]) => {
    try {
      const fieldDef = formFields[name];
      const fieldName = fieldDef.name;
      const fieldElement = document.querySelector(`[name="${fieldName}"]`);

      if (Array.isArray(value)) {
        value.forEach((val) => {
          const checkbox = document.querySelector(
            `[name="${fieldName}"][value="${val}"]`
          );
          if (checkbox) checkbox.checked = true;
        });
      } else if (fieldElement.type === 'radio') {
        const radio = document.querySelector(
          `[name="${fieldName}"][value="${value}"]`
        );
        if (radio) radio.checked = true;
      } else if (fieldElement) {
        fieldElement.value = value;
      }
    } catch (error) {
      console.error(`Error filling form field: ${name}`, error);
    }
  });
};

2、可以用它做什么?

可以通过添加更多高级功能(如处理文件上传、处理动态表单等)进一步改进此脚本。可能的进一步发展:

  • 浏览器扩展将根据存储的配置文件自动填写页面上的表单。
  • 可以创建 AI 代理来代表我们填写表单。
  • 可以创建自动数据输入工具,该工具将根据数据库或任何其他来源的数据填写表单。
  • 在需要保护隐私的情况下,使用 LLM 生成虚假数据。
  • 我们可以使用一些持久层扩展脚本以存储填充的值,以便将来使用它们。

如果表单非常复杂且包含大量字段,请将表单拆分为较小的部分(字段集)并分别填写。

3、结束语

此脚本应该适用于大多数表单。但是,如果表单是动态的(某些表单元素在用户输入时会更改或激活)或使用一些高级功能(如文件上传)或以非标准或错误的方式构建,它可能无法按预期工作。在这种情况下,你可能需要调整脚本以处理这些情况。


原文链接:AI驱动的自动表单填写 - 汇智网

相关推荐

字体缩放(方式一)(字体缩放150%怎么做)

通过元素宽度和字数计算得到缩放简单实现如下:/***字体最大为视觉要求大小(maxFontSize);超出缩小字体显示,最小为minFontSize;最小字体时超出部分使用圆点(...);*p...

网页世界隐藏的神秘代码语言,竟能这样改变布局

CSS基础:选择器与属性CSS(CascadingStyleSheets)是用于控制网页外观的一门样式表语言。它通过定义HTML元素的显示方式来增强网页的表现力。CSS的选择器允许开发者精确地定位...

CSS属性值计算过程详解(css属性用来定义元素计算)

在CSS中,即使某些属性没有显式声明,浏览器也会通过**属性值计算过程**为每个元素的所有属性赋予最终值。这一过程分为四个关键步骤,以下将逐一解析。1.确定声明值浏览器首先检查所有**直接应用**到...

软网推荐:找回调整Windows 10字号功能

之前的系统,从WindowsXP到早期版本的Windows10,均有字体大小调整功能,但从创意者版Windows10以来,取消了之前的设置选项,取而代之的是自定义缩放比例设置。使用这个功能调整过...

Excel中如何设置文本框属性,实例代码讲解

Excel不仅可以对数据进行处理,而且也可以图形化数据,直观显示数据表达的内容。本节介绍一个很重要的对象,Characters,字符对象,使用Characters对象可修改包含在全文本字符串中的任...

CSS 字体样式(css中字体)

本节我们来讲字体样式,之前我们学习HTML的时候学过一些用于字体加粗、倾斜的标签,但是使用标签来实现的效果肯定没有我们通过CSS中的样式来的方便。接下来我们会给大家介绍下面这几个属性的使用:通...

PC网站建设必备代码知识:HTML基础与应用技巧

在PC网站建设的相关课程里,代码扮演着至关重要的角色。只有熟练运用正确的代码,我们才能打造出功能完善、用户体验出色的PC网站。接下来,我会详细讲解在PC网站建设环节中必须了解的代码知识。HTML基础代...

让你大跌眼镜的疯狂 HTML 和 CSS 技巧

今天,分享一个让你大开眼界的技巧。通过使用这个技巧,你可以将整个网页变成一个CSS编辑器。没错,你从未见过这种方法。当我第一次尝试时,我完全被震惊到了。现在,让我们开始吧!步骤1首先,创建一个基础的...

jQuery EasyUI使用教程:创建一个链接按钮

jQueryEasyUI最新版下载>本教程主要为大家展示如何使用jQueryEasyUI创建一个链接按钮。通常情况下,使用“button/”元素来创建一个按钮;使用“a/”元素来创建链接按钮...

React 19 有哪些新特性?(react100)

如果你对React18还不熟悉,欢迎阅读之前的文章《React18全览[1]》最近React发布了V19RC版本,按照惯例,我们对React19的新特性进行一次深度的体验学习...

Java注解探秘:为什么@PostConstruct能解决你的初始化难题?

你是否在Spring项目中遇到过这样的困扰:明明依赖注入已经完成,但某些配置就是无法正常加载?手动调用初始化方法又容易引发空指针异常?这就是@PostConstruct注解大显身手的时候了!@Post...

AI驱动的表单自动填写(ai置入表格)

我们都同意,填写表格是一项枯燥且耗时的任务。如果我们可以创建一个可以为我们填写表格的AI助手,让我们将时间投入到更有建设性的任务中,那会怎样?AI助手将能够通过调用以表单字段为参数的函数来填写表...

从零到一:小程序设计新手如何快速上手?

开发环境搭建对于小程序设计新手而言,搭建合适的开发环境是首要任务。以小程序为例,其官方提供了功能强大的开发工具——开发者工具。首先,新手需前往官方开发者平台,在页面中找到“工具下载”板块,根据...

JavaSwingGUI从小白到大神-6(续)(java从小白到大牛怎么样)

接上一篇《JavaSwingGUI从小白到大神-6》,因本篇文章3万多字,头条一篇发不完,只能分开发。同事查询面板:CompanyFind.javapublicclassCompanyFind{...

C# winform界面假死(c#程序假死)

针对C#WinForm界面假死问题,以下是分步解决方案:1.使用异步编程(async/await)将耗时操作移至后台线程,保持UI线程响应。步骤:将事件处理函数标记为async。使用Task....