先填表单还是先聊会儿天
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 国际许可协议进行许可。