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

AI驱动的表单自动填写

qihemm 2025-06-25 18:24 10 浏览 0 评论

我们都同意,填写表格是一项枯燥且耗时的任务。如果我们可以创建一个可以为我们填写表格的 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驱动的自动表单填写 - 汇智网

相关推荐

VLOOKUP的18种高阶用法大公开!99%的人都不知道的神操作!

作为被头条用户催更的Excel课代表,今天带来让HR追着要模板、让老板主动加薪的VLOOKUP终极指南!从基础到高阶一网打尽,文末送36个行业专用模板!一、为什么你的VLOOKUP总报错?血泪大数据...

Vlooup公式,2种模糊查找匹配,1分钟学会

工作中,VLOOKUP公式使用频率是很高的,用来各种查找匹配问题今天我们分享两种模糊查找匹配问题,一种是文本的模糊查找匹配,一种是数字的模糊查找匹配问题1、文本模糊查找匹配使用模拟数据举个例子,原始数...

与vlookup功能相似的函数,照样搞定表格数据查询,简单还实用

在日常表格数据处理工作,说到数据查询,很多小伙伴首先想到的是Vlookup函数,老师的教程中也多次讲到Vlookup函数的用法和实例。其实在Excel中还有其他的数据查询函数公式或技巧,今天我们先来学...

别再折腾VLOOKUP了!DGET逆向查找10秒通关,小白必看

今天要掀翻一个“过气网红”——VLOOKUP!你是不是也经历过这些崩溃瞬间:逆向查找要交换列顺序,复制粘贴到手软!多条件查找要嵌套MATCH,公式长到怀疑人生!别忍了!今天教你用DGET函数一键封...

职场新人必学!VLOOKUP函数10分钟速成指南

正文:"今天来讲解办公人入职期初函数VLOOKUP,这是所有职场人最重要也是最基础的技能。掌握它,90%的数据查找再不用求人!特别献给刚入职场的你——别让Excel成为加班理由。"——...

巧用Vlookup函数揪出“第三者”(vlookup第三个参数是什么)

在一张Excel表格的重复记录中,让你快速列出每种不同物品第2次或第n次出现的记录,你会怎么做?Vlookup函数就有这个本事。举例来说,产品或者物流表格中往往会记录有同一货物的多笔数据(如下图的今日...

分享12个VLOOKUP超经典用法(vlookup通俗易懂)

刚毕业那会,面试的时候经常会被问到会不会用Excel?我就理直气壮地回答:“会啊。”毕竟,简历上可是写着熟练。接着面试官扔出一句“那你会VLOOKUP吗?”我还是会一口咬定:“我会。“其实,我都没用过...

查找匹配别只知道Vlookup,Sumifs也可以!

工作中遇到查找匹配问题的时候,大家第一反应是不是都想到的Vlookup公式呢,有没有小伙伴们给Sumifs一点点机会的呢,有时候Sumifs比Vlookup更好用1、Vlookup公式举个例子,左边是...

Excel函数讲解:VLOOKUP函数,轻松玩转数据查找

常用函数系列教学:VLOOKUP函数讲解(46)。不懂VLOOKUP函数怎么高效查找数据?闲话少叙直接开讲。基本含义:VLOOKUP函数用于在表格按垂直方向(到)上查找返回行数据。如何使用及注意事项?...

CHOOSEROWS+CHOOSECOLS原来是一个超级查找函数组合!

场景一:要在学生名册中,抽查一名学生成绩。公式:=CHOOSEROWS(A1:D5,2)解析:第一参数A1:D5为数据区域,第二参数2表示提取第2行数据。把数据区域改为A2:D5,结合RANDBETW...

数据查询不止有vlookup函数,自定义zlookup函数查询操作更高效

Excel数据查询,相信大家首先会想到vlookup函数。毋庸置疑vlookup函数在Excel数据查询中作用是非常的强大。但是它也有一些不能实现的数据查询。如上图所示,我们需要根据人员的出现次数,提...

「EXCEL进阶」VLOOKUP函数怎么查询一个值返回多个结果

前言:VLOOKUP函数一般一次只能返回一个结果,本例介绍通过辅助列的方法使VLOOKUP函数查询一个值,返回这个值对应的多个结果。使用场景举例:根据表格中同一数值,返回对应值的多个结果。比如这张数据...

WPS查找能手VLOOKUP函数使用方法讲解

各位同学好!今天我们来深度剖析WPS最实用的查找工具——VLOOKUP函数。这个函数能帮你在表格中快速定位并提取所需数据,可以帮你快速核对两批数据差异,还可以合并多个表格的关联信息,甚至可以帮你制作动...

Excel常用10个函数:跨表查找Vlookup,适用于大数据中查找精确值

Hello大家好,我是Office米,今天,我们将和大家一起分享交流,常用的10个函数之一:查找引用函数VLOOKUP。在说VLOOKUP函数之前,我们要先了解,平时Excel日常工作中会遇到哪些问题...

掌握了这个套路,无论用 Excel vlookup 函数查找第几次结果都很轻松

用vlookup查找默认情况下是一对一出结果,如果要一对多查找,就需要用到各种技巧,具体方法我写过非常多了,可以搜索一下历史记录。只要掌握了今天这个套路,无论你想查找第几次重复值,都易如反掌。案例...

取消回复欢迎 发表评论: