春哥的Agent通关秘籍04:智能记账小秘书【实战篇】

271 阅读4分钟

春哥的Agent通关秘籍04:智能记账小秘书【实战篇】

这一章会有大段大段代码块,提前告知下,主要是解释demo的撰写思路,不讲解新知识。

相关知识内容请看上一篇。

demo参考仓库:github.com/zhangshichu…

这篇我们对格式化输出找一个简单但常见的场景进行实战。

目标:实现记账能力的AI助理,并且能反馈相关情绪

用户输入:今天花xx钱买了个xx

AI输出一段稳定的json对象,不仅能抽离出用户自然语言里的字段,情绪,还能给与反馈。

有了上一节的知识补充,本节实战几乎没有阻碍。

01, 定义 JSON 对象获取Schema·

首先安装 pydantic:

pip install pydantic

然后,在代码里可以这样创建一个 Pydantic 对象:

# 引入 Pydantic 的核心组件
from pydantic import BaseModel, Field

# ==========================================
# 第一步:定义字段类型和描述
# ==========================================
class AccountItem(BaseModel):
    amount: float = Field(description="交易金额,必须是数字。如果未提及金额,默认为 0.0")
    category: str = Field(description="交易分类,只能从以下选择:[餐饮, 交通, 购物, 娱乐, 居家, 医疗, 学习, 其他]")
    product: str = Field(description="具体的商品或服务名称")
    sentiment: str = Field(description="消费时的情绪,例如:开心, 后悔, 心疼, 期待, 平淡 等等,可以自行总结")
    # 🔥 新增字段:AI 的情感反馈
    ai_comment: str = Field(description="根据用户的消费内容和情绪,给出一句简短的反馈。如果是乱花钱可以幽默吐槽,如果是必要消费给予肯定,如果是心情不好则给予安慰。")

这一步我们首先明确了我们接下来希望从 LLM 那里得到什么样的数据:

  • amount
  • category
  • product
  • sentiment 情绪
  • ai_comment AI评论

接下来,我们可以调用API轻松地把以上定义转换为标准的 JSONSchema。

# 把 Pydantic 类转换成 AI 能读懂的 JSON Schema 描述
# ensure_ascii=False 是为了让中文正常显示,不变成 \uXXXX
schema_str = json.dumps(AccountItem.model_json_schema(), ensure_ascii=False)

02,组装完整的System Prompt

上节我们说过,【系统提示词】是开发人员设置的静态的,高权重的提示词。

因此,在这里,我们需要明确:

  • AI 在扮演什么角色
  • 需要完成什么任务
  • 遵循什么样的规则和要求
# 2. 构建 System Prompt
    system_prompt = f"""
    你是一个不仅会记账,还很懂心理学的贴心助手。
    请分析用户的输入,提取关键信息,并给出情感反馈。
    
    【重要规则】
    1. 根据常识自动推断分类。
    2. 严格按照以下 JSON Schema 格式输出 JSON 数据,禁止包含 markdown:
    {schema_str}
    """

03. 创建 client和会话

from dotenv import load_dotenv
from openai import OpenAI

# 加载环境变量
load_dotenv()
# 创建client
client = OpenAI(
    api_key=os.getenv("DEEP_SEEK_API_KEY"), 
    base_url=os.getenv("DEEP_SEEK_API_URL")
)

然后利用我们前几步构建好的参数和client来发起会话。

  # 3. 调用大模型
  response = client.chat.completions.create(
      model="deepseek-chat", 
      messages=[
          {"role": "system", "content": system_prompt}, # 注入规则
          {"role": "user", "content": user_input}       # 注入数据
      ],
      # 【关键】强制模型进入 JSON 模式,防止它胡乱说话
      response_format={"type": "json_object"} 
  )

  # 4. 获取结果字符串
  json_str = response.choices[0].message.content
  
  # 5. 【验证】将 JSON 字符串倒回 Pydantic 对象
  data = json.loads(json_str)
  result = AccountItem(**data)

这里需要注意 AccountItem(**data) 这一步,如果返回的对象反序列化后,不符合最初设计的 JSON Schema格式,它就会报错,从而阻断脏数据等。

04. 动态获取cli的用户输入

在 python 里,这非常容易:

# 获取用户输入
user_input = input("\n📝 请输入账单描述: ").strip()

上节课我们怎么说的来着?用户输入最好作为 User Prompt,没错,把它动态传入作为 User Prompt 进行会话即可。

05. 测试代码

完整代码可以参考demo工程里的文件:github.com/zhangshichu…

尝试运行代码:

python .\lesson_04\lesson_04_structure.py

如果把这个代码组装到一个 web server 上,那就能实现和前端的通信了。

下一步预告

有了本节和上节的【结构化】输出,我们成功做到了可以准确让AI输出我们需要的结构化数据。

但,这实际上是最简单的一次性对话,根本不能代表AI Agent的核心场景。

但AI还有一些致命的弱点:

  • 不擅长算数
  • 训练集不是实时的,无法知道今天的天气怎么样,现在几点等
  • 没有记忆

下节课开始,让我们开始着手解决这些问题。

敬请期待!