AI驱动的表单自动填写 ai智能填报
myzbx 2024-12-22 19:43 13 浏览
我们都同意,填写表格是一项枯燥且耗时的任务。如果我们可以创建一个可以为我们填写表格的 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驱动的自动表单填写 - 汇智网
相关推荐
- 以文本的方式绘制简单的SVG流程图——flowchart.js
-
介绍flowchart.js是在浏览器和终端中运行的流程图DSL和SVG渲染。节点和连接是分别定义的,因此可以重复使用节点,并可以快速更改连接。也可以在DSL中对节点和连接器样式进行细微的更改。Git...
- 全国首套构网型SVG在木垒投运
-
中新网新疆新闻1月5日电(翟文辉)12月29日,全国首套构网型SVG在新疆木垒华电220千伏四十个井子汇集站并网,本项目是新疆电网继阿克陶构网型储能后又一次构网型支撑项目示范。为全面响应国家“双碳”...
- Popmotion – 小巧,灵活的 JS 运动引擎
-
Popmotion是一个只有12KB的JavaScript运动引擎,可以用来实现动画,物理效果和输入跟踪。原生的DOM支持:CSS,SVG,SVG路径和DOM属性的支持,开箱即用。Popmoti...
- 零基础教你学前端——43、初识SVG
-
解决网站图标问题的最佳方案——SVG!SVG是一种基于XML语法的图像格式,英文全称是:ScalableVectorGraphics,即可缩放矢量图,是W3C的一项建议。我们用手机拍摄...
- 2.3 文件格式全解:PSD/JPG/PNG/SVG/GIF
-
2.3文件格式全解:PSD/JPG/PNG/SVG/GIF一、文件格式的核心意义文件格式是数字图像的存储规则,决定了:-信息保留程度(图层/透明度/动画)-压缩方式与画质损失-跨平台兼容性-...
- vite v6.3.2 发布!HMR 优化+CSS 增强+稳定性提升,前端开发再提速!
-
前言:Vite6.3.2来了!2025年4月18日,Vite团队正式发布了v6.3.2版本!虽然是一个小版本更新,但修复了多个关键问题,并带来了性能优化和稳定性提升,让开发体验更丝滑!如果你还...
- 一篇文章带你了解SVG 蒙版(Mask)
-
SVG蒙版功能可将蒙版应用于SVG形状。蒙版可确定SVG形状的哪些部分可见,以及具有什么透明度。运行效果可以将SVG蒙版视为剪切路径的更高级版本。一、简单的蒙版代码解析:本示例使用ID=mask1定义...
- SVG实现的流程图绘制
-
一、项目简介使用SVG技术实现的流程图绘制二、实现功能流程图块生成、连线、拖拽产生相应的xml和xpdl导入导出json数据放大缩小功能保存操作(选择、自动插入、开始结束、普通活动、子活动、块活动、路...
- 解锁国内 404 页面:Next.js 设置指南和 33 个有趣 SVG 资源分享
-
前言当我们访问网站时,如果访问到不存在的路径时,会出现404错误。为了避免给访问者带来不良体验,设计网站时通常会在页面上展示“404页面不存在”的提示,并引导用户进行返回首页等操作。因此在建立网...
- 交互设计师做好动画后,提交给开发的文档有哪些?
-
谢邀!简单的说一下自己的看法。首先从制作动画开始。目前制作动画的方式主要有:Gif动画视频动画Web动画,而Web动画又包括:CSS动画、JS动画(Canvas动画、原生JS动画API)、SVG动画等...
- Motion for Vue:为Vue量身定制的强大动画库
-
在前端开发中,动画效果是提升用户体验的重要手段。Vue生态系统中虽然有许多动画库,但真正能做到高性能、易用且功能丰富的并不多。今天,我们要介绍的是MotionforVue(motion-v),...
- Web开发人员的福音!8个实用的SVG工具
-
SVG可缩放矢量图形(ScalableVectorGraphics)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式。SVG是W3C在2000年8月制定的一种新的二维矢量图形格式...
- 一键画波浪线、一键多图片调色?这3个网站好玩到停不下来
-
作为一个经常收集网站的PPT设计师,无意中发现了一些超级有趣的网站。只要你动手能力足够强,就一定会利用它做出创意作品。不说废话,直接进入主题。1、炫酷的光线绘画网站http://weavesilk.c...
- vite 6.2.5 更新速递:告别SVG路径Bug,构建效率再提升!
-
Vite6.2.5更新公告2025年4月3日,Vite团队正式发布了Vite6.2.5版本!此次更新虽然是一个小版本迭代,但修复了一个关键问题,涉及SVG文件路径检查,对前端开发者尤...
- DrawSVG – SVG 路径动画 jQuery 插件
-
jQueryDrawSVG使用了jQuery内置的动画引擎实现SVG路径动画,用到了stroke-dasharray和stroke-dashoffset属性。DrawSVG是完全...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 基础教程 (29)
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 选择器 (30)
- CSS 轮廓 (30)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 中级教程 (30)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)