Coding solutions with AI The world changed Solving problems with AI A simple example

2025-06-09

使用人工智能编码解决方案

世界改变了

利用人工智能解决问题

一个简单的例子

我们在 Dev 上经常讨论我们担心人工智能会抢走我们的工作,担心它会代替我们写代码。我想我们对此都有自己的看法,而这篇文章根本不是讨论这个话题。

我想写的是我工具箱里的一个新工具,它似乎越来越频繁地被我使用,因为它不断地成功地解决了我客户的问题。你可能已经猜到了,这个工具就是 GPT4-Turbo。

我下面列出的问题是在约 90 分钟的火车旅途中解决的,包括所有编码、调试和运行。

世界改变了

我发现自己选择要解决的问题,以前由于复杂性而被放在了较低的位置,或者主要是人力任务,投入的资源对于所提供的利益来说太昂贵了。

利用人工智能解决问题

如果我们要用人工智能来解决问题,就必须运用程序员日常使用的思维方式来分解问题。我们需要把问题分解成多个更小的单元,然后解决它们。

当子问题并非明确的公式或数据操作时,我们可以选择人工智能作为解决方案,最明显的例子就是涉及自然语言的情况。自然语言是一个复杂的问题,同一个含义可以用许多不同的方式表达——还有很多类似的问题,例如科学测量、财务数据等等,但就我个人而言,语言是遇到最多的问题。

一个简单的例子

我已经用这里要讲的流程解决了我的解决方案中的 5 个主要问题。如果我解释一些复杂的问题,你会觉得很无聊,而且我需要提供大量的数据来解释这个问题。

我的生意

我是一家致力于确保建筑物对住户或租户安全的企业的首席技术官。30多年来,SFG20 一直致力于打造行业维护标准,确保我们的客户采取有效措施,防止人员受伤,并尽可能延长设备的使用寿命。其中许多工作都是法律要求,近年来,伦敦一栋住宅楼发生火灾,造成72人死亡,相关法律也随之发生了巨大变化。

英国政府、医院、养老院、住宅房地产开发商和数百家私营企业均使用 SFG20,以确保他们满足法律要求并最大限度地保障建筑物居住者的健康和安全。

SFG20 内容通常用于计算机辅助设施管理解决方案,该解决方案实际上指导人们在适当的时间执行任务,然后确保跟踪其完成情况。

问题

我有数千份维护计划,其中包含数万项待执行的操作。这些操作由工程师制定,并经过批准,以确保符合法律和最佳实践。这些操作以自由文本形式编写,包含标题和待执行步骤列表。

许多 CAFM 供应商希望允许其用户修改某些操作的频率或禁用它们,因为它们与特定设备无关。

最近,一些时间表被重写,以便更清晰地显示,虽然在纸面上看起来不错,但这意味着任务步骤被分组到时间段 - 这扰乱了识别特定子任务的能力。

我需要制定一份明确的时间表清单,其中的任务标题现在仅仅是时间段,并查找是否存在以前的版本不是以这种方式组织的。

解决方案

首先让我们将我的任务分解为几个步骤。

  1. 收集每个维护计划的任务标题。
  2. 确定一个或多个任务标题是否仅与某个时间段相关:“每六个月检查一次”是一个问题,但“每三个月检查一次发动机油”则不是。
  3. 如果有问题,则循环运行步骤 1 和 2 的先前版本,直到找到没有问题的版本。
  4. 输出存在问题的计划列表,并指出是否存在没有问题的先前版本,以便技术作者可以应对挑战。

使用人工智能

如果我们尝试手动分析时间表,这将花费很长时间。

如果我们要寻找 NLP 所说的具有时间段的任务:列表仍然很庞大,并且需要作者花费数周的时间。

人工智能擅长这类任务,它可以像人一样阅读标题并识别任务是否仅仅是一个时间段。

构建和调试解决方案

我对这项任务的提示工程的方法是迭代。

  1. 首先,我会让 ChatGPT 告诉我,它会用什么提示符来提示我的问题。我知道 Meta 的问题。这是第一个调试阶段,如果 GPT 给出的提示符似乎没有切中要点,我会在这里进行修复。

  2. 接下来,我构建框架代码并使用我制作的一些辅助函数来获取我想要的输出,在大多数情况下,它是某种 JSON。

  3. 最后的迭代步骤是通过AI部分运行一系列测试用例并检查结果。如果它没有达到我的预期,我会将这些用例作为示例提供给GPT,并询问它应该使用什么提示来避免这些问题——回到第一步。

解决方案

这是检查特定时间表的代码的 JS。这里的结果提示是基于我的两次迭代周期得出的。

运行此程序后,需要进一步审查 64 个时刻表,其中 6 个在前 3 个月内已发生过更改 - 而这些时刻表正是我们收到投诉的时刻表。

export async function checkScheduleTasks(schedule) {
    if (!schedule.tasks.filter((f) => !f.isHeader && !!f.title).length) return false
    const result = await chatJSON(
        [
            system(
                `
       You will be provided with a list of task names from a maintenance schedule. Your task is to examine the provided task names and determine if any of them represent only a time period, without being part of a more specific task description.

  Criteria for true:
  - A task name that consists solely of a time period description (e.g., "6 monthly", "Annual", "Bi-weekly").

  Criteria for false:
  - A task name that includes a time period as part of a broader task description (e.g., "Electrical tests - 6 monthly", "Annual safety inspection").

  Respond with {"response": true} if any task name meets the criteria for true. Otherwise, respond with {"response": false}.

    `
            ),
            jsonOutput(),
            `
       Here are the task names:

${schedule.tasks
    .filter((f) => !f.isHeader)
    .map((c) => c.title)
    .join("\n")}

    `,
        ],
        0.05
    )
    return result.response
}

Enter fullscreen mode Exit fullscreen mode

实用工具

从上面的代码中你可以看到,我有一些实用函数可以生成系统指令和 JSON 的默认指令。我会在这里列出它们,希望它们对你有帮助。

import OpenAI from "openai"

export let openai
try {
    openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
} catch (e) {
    console.warn(`!!!!!! ERROR in OpenAI`)
    console.error(e)
}

export async function chat(messages, temperature = 0.15, model = "gpt-4-turbo-preview") {
    messages = messages.filter(Boolean).map((m) => (typeof m === "string" ? { role: "user", content: m } : m))
    let retry = false
    let response
    do {
        retry = false
        try {
            response = await openai.chat.completions.create({
                messages,
                model,
                temperature,
            })
        } catch (e) {
            if (e.status === 429) {
                await new Promise((resolve) => setTimeout(resolve, 250))
                retry = true
            }
        }
    } while (retry)
    return response.choices[0].message.content?.value ?? response.choices[0].message.content
}

export async function chatJSON(...params) {
    const text = await chat(...params)
    try {
        return JSON.parse(text)
    } catch (e) {
        console.log(text)
        console.error(e)
    }
}

export async function chatStream(messages, temperature = 0.15, model = "gpt-4-turbo-preview") {
    messages = messages.filter(Boolean).map((m) => (typeof m === "string" ? { role: "user", content: m } : m))
    return openai.chat.completions.create({
        messages,
        model,
        temperature,
        stream: true,
    })
}

export function cleanLines(message) {
    if (Array.isArray(message)) return message.map(cleanLines)
    return message
        .split("\n")
        .map((s) => s.trim())
        .join("\n")
}

export function system(message) {
    return {
        role: "system",
        content: cleanLines(message),
    }
}

export function jsonOutput() {
    return system(`
            Your output will be JSON, not wrapped in \`\`\`json.  Validate the JSON parses correctly before returning, adjust as necessary
        `)
}

Enter fullscreen mode Exit fullscreen mode

鏂囩珷鏉ユ簮锛�https://dev.to/miketalbot/solving-natural-language-problems-with-ai-200g
PREV
👨‍🎓️📊 数据科学家——从初学者到专业人士的 12 个步骤
NEXT
使用 Firebase 的无服务器应用程序