先填表单还是先聊会儿天

Posted on Mon 31 March 2025 in Journal

Abstract Journal on 2025-03-31
Authors Walter Fan
 Category    learning note  
Status v1.0
Updated 2025-03-31
License CC-BY-NC-ND 4.0

各种 web app 最常见的就是表单 (form), 各种文本框, 下拉框, 选择框, 复选框, 以及提交按钮, 我反正是挺烦填这些表单的. 在 AI 以及大语言模型大行其道的今天, 表单的使用率应该大大减少, 代之以轻松的聊天, 因为聊天就可以生成表单所需要的数据了.

例如, 我有一个 web app, 用来记录任务, 以前我需要填写任务名称, 描述, 截止日期, 优先级, 状态, 等等信息 现在我只需要告诉它, 我想记录一个任务, 大概内容是什么, 然后请 AI 根据文本生成结构化的表单数据, 以 json 格式提交到服务器.

例如下面这个 Task 类, 定义了一个表单所提交的数据

class Priority(Enum):
    HIGHEST = 1
    VERY_HIGH = 2
    HIGH = 3
    MEDIUM = 4
    LOW = 5

class Difficulty(Enum):
    EASIEST = 1
    EASY = 2
    MEDIUM = 3
    HARD = 4
    HARDEST = 5

class TaskTag(BaseModel):
    """A tag for categorizing tasks"""
    name: str = Field(..., description="The name of the tag")

class Task(BaseModel):
    """
    Task model, all datetime fields are iso format with time zone
    """
    task_id: Optional[str] = Field(None, description="Unique identifier for the task")
    name: str = Field(..., description="The title or name of the task")
    desc: Optional[str] = Field(None, description="Detailed description of the task")
    priority: Priority = Field(..., description="Priority level, from 1 (highest) to 5 (lowest)")
    difficulty: Difficulty = Field(..., description="Difficulty level, from 1 (easiest) to 5 (hardest)")
    duration: Optional[float] = Field(None, description="Estimated time to complete the task in hours")
    remind_note: Optional[str] = Field(None, description="remind user with check points of the task")
    remind_time: Optional[datetime] = Field(None, description="When to remind the user about the task")
    schedule_time: Optional[datetime] = Field(None, description="When work on the task should begin")
    start_time: Optional[datetime] = Field(None, description="When work on the task began actually")
    end_time: Optional[datetime] = Field(None, description="When the task was completed")
    deadline: Optional[datetime] = Field(None, description="When the task is due")

    create_time: Optional[datetime] = Field(None, description="When the task is created, defaults to now")
    update_time: Optional[datetime] = Field(None, description="When the task is updated, defaults to now")

    tags: List[TaskTag] = Field(default_factory=list, description="List of tags associated with this task")

我们可以写一个 python 类, 通过 chatgpt API 将文本转换成用来生成上述这个 Task 的 json 数据

#!/usr/bin/env python3
import uuid
from datetime import datetime
from typing import List, Optional, Dict, Any
from async_llm_agent import AsyncLlmAgent
import asyncio
from pydantic import BaseModel, Field
from enum import Enum
from loguru import logger
import os
from dotenv import load_dotenv

load_dotenv()

# ... task definition as above ...

class TaskJSONGenerator:
    def __init__(self):
        """Initialize the TaskJSONGenerator with your OpenAI API key."""
        self.api_key = os.getenv("LLM_API_KEY")
        self.base_url = os.getenv("LLM_BASE_URL")
        self.model = os.getenv("LLM_MODEL")

        self._agent = AsyncLlmAgent()

    async def extract_task_from_text(self, text: str) -> Task:
        """Extract task information from natural language text"""

        system_prompt="""
        You are an AI assistant specialized in extracting task information from text.
        You are also a smart task planner and manager.
        """
        user_prompt=f"""
        Extract as much relevant information as possible about the task being described as specified response format:
        ---
        {text}
        ---
        note: current time is {datetime.now().isoformat()}
        """

        return await self._agent.get_object_response(system_prompt, user_prompt, Task)

    async def generate_task_json(self, user_text: str) -> Dict[str, Any]:
        """
        Convert natural language text into a structured Task JSON.

        Args:
            user_text: A string containing the natural language description of the task

        Returns:
            A dictionary containing the structured task data
        """

        task_data = await self.extract_task_from_text(user_text)
        task_data.task_id = str(uuid.uuid4())
        task_data.create_time = datetime.now()
        task_data.update_time = datetime.now()

        return task_data.model_dump_json()



# Example usage:
if __name__ == "__main__":
    import json

    # Replace with your actual OpenAI API key
    generator = TaskJSONGenerator()

    # Example text
    text = """
    我下周二上午9点有一个重要的技术演示, 要提前一天花费2小时准备好相关的议程, 可运行的代码和PPT
    """
    task_json_str = asyncio.run(generator.generate_task_json(text))
    print(json.dumps(json.loads(task_json_str), indent=2, ensure_ascii=False))

输出如下

{
  "task_id": "5a573963-40dc-48a1-9d76-b53a25d2b857",
  "name": "技术演示准备",
  "desc": "准备下周二上午9点的技术演示,包括议程、可运行的代码和PPT。",
  "priority": 1,
  "difficulty": 3,
  "duration": 2.0,
  "remind_note": "提前一天提醒准备议程、代码和PPT。",
  "remind_time": "2025-03-31T09:00:00+08:00",
  "schedule_time": "2025-03-31T09:00:00+08:00",
  "start_time": null,
  "end_time": null,
  "deadline": "2025-04-01T09:00:00+08:00",
  "create_time": "2025-03-30T10:51:25.392850",
  "update_time": "2025-03-30T10:51:25.392963",
  "tags": [
    {
      "name": "技术演示"
    },
    {
      "name": "准备"
    }
  ]
}
  • 完整代码参见 https://github.com/walterfan/lazy-rabbit-agent/blob/master/example/text_to_form_json.py

这样, 我们就再也不用手动填写表单上的一个一个字段了, 就说一句话就能生成一个完整的 task.


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。