TypeChat实战,实现记账功能

前段时间在掘金看了一篇关于typechat的文章,觉得这玩意挺有意思的,就写了个demo玩了玩,这里给大家分享一下。

背景

前段时间在掘金看了一篇关于typechat的文章,觉得这玩意挺有意思的,就写了个demo玩了玩,这里给大家分享一下。

什么是 TypeChat

TypeChat 入门指南

这篇文章已经解释了什么是TypeChat,我这里就不介绍了,主要是实战。

需求分析

一般的记账小程序或app,基本都是需要自己一项一项输入,比如日期、金额、消费类型、备注等。这样录入感觉有点麻烦,快捷的录入方式是,输入一段文本,系统自动解析里面的关键字,生成对应模型数据。

举个例子

用户输入:昨天买了个西瓜,花了20元。

期望解析出来的数据结构是这样的

json
复制代码
{ date: '2023-08-24', amount: 20, name: '西瓜' }

自己写代码去解析难度太大了,用户输入的格式什么的你想不到有哪些,用chatgpt去分析,返回的数据格式有可能不是自己想要的,TypeChat就是干这个的。分析用户的输入,返回固定的数据格式。

实战

初始化一个后端midway项目

sh
复制代码
npm init midway

安装TypeChat依赖

sh
复制代码
pnpm i typechat --save

安装dotenv依赖

sh
复制代码
pnpm i dotenv --save

在项目根目录下建.env文件,配置openai key

env
复制代码
OPENAI_MODEL=gpt-3.5-turbo OPENAI_API_KEY=openai key

src/configuration.ts加载.env中的值到环境变量中

TypeChat实战,实现记账功能

定义schema

ts
复制代码
// src/schema/demo.ts export type Demo = { date: string; name: string; amount?: number; };

改造home.controller文件

ts
复制代码
// src/controller/home.controller.ts import { Controller, Get } from '@midwayjs/core'; import { readFileSync } from 'fs'; import { join } from 'path'; import { createLanguageModel, createJsonTranslator } from 'typechat'; import { Demo } from '../schema/demo'; @Controller('/') export class APIController { @Get('/') async home() { // 从环境变量里创建模型 const model = createLanguageModel(process.env); // 读取我们前面定义的schema const schema = readFileSync(join(__dirname, '../schema/demo.ts'), 'utf8'); // 创建转换器 const translator = createJsonTranslator<Demo>(model, schema, 'Demo'); // 解析输入的内容 const response = await translator.translate('昨天我买了西瓜,花了100元。'); if (response.success) { return response.data; } } }

启动项目,测试

sh
复制代码
npm run dev

访问 http://127.0.0.1:7001/

测试结果

TypeChat实战,实现记账功能

返回的数据不是我们想要的,这是因为typechat不知道字段的含义,没办法给你解析。

改造schema

可以通过给字段加注释让typechat知道你的模型是用来干啥的

ts
复制代码
export type Demo = { // 消费日期,输出YYYY-MM-DD格式 date: string; // 消费物品名称 name: string; // 消费金额 amount?: number; };

TypeChat实战,实现记账功能

解决日期问题

现在的数据格式就是我们想要的,但是日期有点问题,我明明输入的时候昨天,返回的却是2022-01-20,这个很奇怪,我猜测可能openai,没办法获取到当前日期,所以随便找了个日期。

想解决这个问题也简单,我们把当前日期注入进去就行了。注释里不能写函数,怎么注入当前日期呢,不知道大家有没有发现,上面创建schema的方法是读取demo.ts这个文件的内容当参数的,那我们在demo.ts写一个占位符,读取后用当前日期给替换掉就行了。

ts
复制代码
export type Demo = { // 消费日期,输出YYYY-MM-DD格式,举个例子:如果输入今天,输出今天的日期,今天日期为{today} date: string; // 消费物品名称 name: string; // 消费金额 amount?: number; };

这里只需要告诉他今天日期就行了,他会自动推算昨天前天,甚至上周五的日期。

TypeChat实战,实现记账功能

用当前日期给{today}占位符给替换掉

TypeChat实战,实现记账功能

现在日期就对了

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

提高难度也能正常识别,甚至中文的一百都给你转成数字了。

加大难度

如果不输入日期表示当前日期,怎么做呢,在注释中加个默认值就行了。

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

提示

node版本不能低于18.0.0,不然项目会报错,因为typechat里面用了node高版本的api。

做个网页

基于上面功能,我们来实现一个小功能。

用户输入一段内容,自动把数据插入到数据库中,并以表格的形式展示出来。

引入typeorm操作数据库表

具体请参考官方文档,www.midwayjs.org/docs/extens…

创建entity

ts
复制代码
// src/entity/accounting.ts import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class Accounting { @PrimaryGeneratedColumn() id: number; @Column({ comment: '物品名称', nullable: true }) name: string; @Column({ comment: '消费日期', nullable: true }) date: string; @Column({ comment: '金额', nullable: true }) amount: number; }

改造controller

ts
复制代码
import { Body, Controller, Get, Post } from '@midwayjs/core'; import { readFileSync } from 'fs'; import { join } from 'path'; import { createLanguageModel, createJsonTranslator } from 'typechat'; import { Demo } from '../schema/demo'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Accounting } from '../entity/accounting'; import { Repository } from 'typeorm'; @Controller('/') export class APIController { @InjectEntityModel(Accounting) accountingModel: Repository<Accounting>; @Post('/') async home(@Body() data: { text: string }) { // 从环境变量里创建模型 const model = createLanguageModel(process.env); // 读取我们前面定义的schema const schema = readFileSync( join(__dirname, '../schema/demo.ts'), 'utf8' ).replace(/{today}/g, new Date().toDateString()); // 创建转换器 const translator = createJsonTranslator<Demo>(model, schema, 'Demo'); // 解析输入的内容 const response = await translator.translate(data.text); if (response.success) { const accounting = new Accounting(); accounting.amount = response.data.amount; accounting.date = response.data.date; accounting.name = response.data.name; // 保存到数据库 await this.accountingModel.save(accounting); } } @Get('/') async list() { // 查询列表,倒序返回 return await this.accountingModel.find({ order: { id: 'DESC' } }); } }

前端项目

脚手架用的是vite,组件库用的是antd

tsx
复制代码
// src/App.tsx import { Button, Table, Input, Space } from 'antd' import { useEffect, useMemo, useState, } from 'react' function App() { const columns = useMemo(() => [ { dataIndex: 'date', title: '日期' }, { dataIndex: 'amount', title: '金额' }, { dataIndex: 'name', title: '备注' }, ], []); const [loading, setLoading] = useState(true); const [text, setText] = useState(''); const [dataSource, setDataSource] = useState([]); const [translating, setTranslating] = useState(false); function getTableData() { setLoading(true); window.fetch('/api', { method: 'GET', headers: { 'Content-Type': 'application/json' }, }) .then(res => res.json()) .then(data => { setDataSource(data); setLoading(false); }); } useEffect(() => { getTableData(); }, []); function translate() { setTranslating(true); window.fetch('/api', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text, }), }).then(() => { getTableData(); setTranslating(false); setText(''); }) } return ( <div className='p-[20px]'> <Table scroll={{ y: 500 }} pagination={false} rowKey="id" loading={loading} dataSource={dataSource} columns={columns} /> <Space className='w-[100%] mt-[20px]'> <Input onPressEnter={translate} value={text} onChange={e => { setText(e.target.value) }} className='w-[800px]' /> <Button type='primary' loading={translating} onClick={translate}>确定</Button> </Space> </div> ) } export default App

demo展示

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

总结

感觉这种交互方式,更适合语音输入,后面有时间做一个记账app,对接一下语音识别,就不用手动输入内容那么麻烦了。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
人工智能

TypeChat实战,实现记账功能

2024-5-3 3:33:07

人工智能

如何让 ChatGPT 接收或输出万字长文,突破 Token 限制

2024-5-3 7:30:37

TypeChat实战,实现记账功能

前段时间在掘金看了一篇关于typechat的文章,觉得这玩意挺有意思的,就写了个demo玩了玩,这里给大家分享一下。

背景

前段时间在掘金看了一篇关于typechat的文章,觉得这玩意挺有意思的,就写了个demo玩了玩,这里给大家分享一下。

什么是 TypeChat

TypeChat 入门指南

这篇文章已经解释了什么是TypeChat,我这里就不介绍了,主要是实战。

需求分析

一般的记账小程序或app,基本都是需要自己一项一项输入,比如日期、金额、消费类型、备注等。这样录入感觉有点麻烦,快捷的录入方式是,输入一段文本,系统自动解析里面的关键字,生成对应模型数据。

举个例子

用户输入:昨天买了个西瓜,花了20元。

期望解析出来的数据结构是这样的

json
复制代码
{ date: '2023-08-24', amount: 20, name: '西瓜' }

自己写代码去解析难度太大了,用户输入的格式什么的你想不到有哪些,用chatgpt去分析,返回的数据格式有可能不是自己想要的,TypeChat就是干这个的。分析用户的输入,返回固定的数据格式。

实战

初始化一个后端midway项目

sh
复制代码
npm init midway

安装TypeChat依赖

sh
复制代码
pnpm i typechat --save

安装dotenv依赖

sh
复制代码
pnpm i dotenv --save

在项目根目录下建.env文件,配置openai key

env
复制代码
OPENAI_MODEL=gpt-3.5-turbo OPENAI_API_KEY=openai key

src/configuration.ts加载.env中的值到环境变量中

TypeChat实战,实现记账功能

定义schema

ts
复制代码
// src/schema/demo.ts export type Demo = { date: string; name: string; amount?: number; };

改造home.controller文件

ts
复制代码
// src/controller/home.controller.ts import { Controller, Get } from '@midwayjs/core'; import { readFileSync } from 'fs'; import { join } from 'path'; import { createLanguageModel, createJsonTranslator } from 'typechat'; import { Demo } from '../schema/demo'; @Controller('/') export class APIController { @Get('/') async home() { // 从环境变量里创建模型 const model = createLanguageModel(process.env); // 读取我们前面定义的schema const schema = readFileSync(join(__dirname, '../schema/demo.ts'), 'utf8'); // 创建转换器 const translator = createJsonTranslator<Demo>(model, schema, 'Demo'); // 解析输入的内容 const response = await translator.translate('昨天我买了西瓜,花了100元。'); if (response.success) { return response.data; } } }

启动项目,测试

sh
复制代码
npm run dev

访问 http://127.0.0.1:7001/

测试结果

TypeChat实战,实现记账功能

返回的数据不是我们想要的,这是因为typechat不知道字段的含义,没办法给你解析。

改造schema

可以通过给字段加注释让typechat知道你的模型是用来干啥的

ts
复制代码
export type Demo = { // 消费日期,输出YYYY-MM-DD格式 date: string; // 消费物品名称 name: string; // 消费金额 amount?: number; };

TypeChat实战,实现记账功能

解决日期问题

现在的数据格式就是我们想要的,但是日期有点问题,我明明输入的时候昨天,返回的却是2022-01-20,这个很奇怪,我猜测可能openai,没办法获取到当前日期,所以随便找了个日期。

想解决这个问题也简单,我们把当前日期注入进去就行了。注释里不能写函数,怎么注入当前日期呢,不知道大家有没有发现,上面创建schema的方法是读取demo.ts这个文件的内容当参数的,那我们在demo.ts写一个占位符,读取后用当前日期给替换掉就行了。

ts
复制代码
export type Demo = { // 消费日期,输出YYYY-MM-DD格式,举个例子:如果输入今天,输出今天的日期,今天日期为{today} date: string; // 消费物品名称 name: string; // 消费金额 amount?: number; };

这里只需要告诉他今天日期就行了,他会自动推算昨天前天,甚至上周五的日期。

TypeChat实战,实现记账功能

用当前日期给{today}占位符给替换掉

TypeChat实战,实现记账功能

现在日期就对了

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

提高难度也能正常识别,甚至中文的一百都给你转成数字了。

加大难度

如果不输入日期表示当前日期,怎么做呢,在注释中加个默认值就行了。

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

提示

node版本不能低于18.0.0,不然项目会报错,因为typechat里面用了node高版本的api。

做个网页

基于上面功能,我们来实现一个小功能。

用户输入一段内容,自动把数据插入到数据库中,并以表格的形式展示出来。

引入typeorm操作数据库表

具体请参考官方文档,www.midwayjs.org/docs/extens…

创建entity

ts
复制代码
// src/entity/accounting.ts import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity() export class Accounting { @PrimaryGeneratedColumn() id: number; @Column({ comment: '物品名称', nullable: true }) name: string; @Column({ comment: '消费日期', nullable: true }) date: string; @Column({ comment: '金额', nullable: true }) amount: number; }

改造controller

ts
复制代码
import { Body, Controller, Get, Post } from '@midwayjs/core'; import { readFileSync } from 'fs'; import { join } from 'path'; import { createLanguageModel, createJsonTranslator } from 'typechat'; import { Demo } from '../schema/demo'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Accounting } from '../entity/accounting'; import { Repository } from 'typeorm'; @Controller('/') export class APIController { @InjectEntityModel(Accounting) accountingModel: Repository<Accounting>; @Post('/') async home(@Body() data: { text: string }) { // 从环境变量里创建模型 const model = createLanguageModel(process.env); // 读取我们前面定义的schema const schema = readFileSync( join(__dirname, '../schema/demo.ts'), 'utf8' ).replace(/{today}/g, new Date().toDateString()); // 创建转换器 const translator = createJsonTranslator<Demo>(model, schema, 'Demo'); // 解析输入的内容 const response = await translator.translate(data.text); if (response.success) { const accounting = new Accounting(); accounting.amount = response.data.amount; accounting.date = response.data.date; accounting.name = response.data.name; // 保存到数据库 await this.accountingModel.save(accounting); } } @Get('/') async list() { // 查询列表,倒序返回 return await this.accountingModel.find({ order: { id: 'DESC' } }); } }

前端项目

脚手架用的是vite,组件库用的是antd

tsx
复制代码
// src/App.tsx import { Button, Table, Input, Space } from 'antd' import { useEffect, useMemo, useState, } from 'react' function App() { const columns = useMemo(() => [ { dataIndex: 'date', title: '日期' }, { dataIndex: 'amount', title: '金额' }, { dataIndex: 'name', title: '备注' }, ], []); const [loading, setLoading] = useState(true); const [text, setText] = useState(''); const [dataSource, setDataSource] = useState([]); const [translating, setTranslating] = useState(false); function getTableData() { setLoading(true); window.fetch('/api', { method: 'GET', headers: { 'Content-Type': 'application/json' }, }) .then(res => res.json()) .then(data => { setDataSource(data); setLoading(false); }); } useEffect(() => { getTableData(); }, []); function translate() { setTranslating(true); window.fetch('/api', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text, }), }).then(() => { getTableData(); setTranslating(false); setText(''); }) } return ( <div className='p-[20px]'> <Table scroll={{ y: 500 }} pagination={false} rowKey="id" loading={loading} dataSource={dataSource} columns={columns} /> <Space className='w-[100%] mt-[20px]'> <Input onPressEnter={translate} value={text} onChange={e => { setText(e.target.value) }} className='w-[800px]' /> <Button type='primary' loading={translating} onClick={translate}>确定</Button> </Space> </div> ) } export default App

demo展示

TypeChat实战,实现记账功能

TypeChat实战,实现记账功能

总结

感觉这种交互方式,更适合语音输入,后面有时间做一个记账app,对接一下语音识别,就不用手动输入内容那么麻烦了。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
人工智能

Animated Drawings

2024-5-3 1:36:26

人工智能

TypeChat实战,实现记账功能

2024-5-3 5:34:07

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索