您现在的位置是:首页 > 文章详情

gfast AI 对话插件发布

日期:2025-06-04点击:37

支持配置不同平台大模型接口openAI或兼容openAI接口,DeepSeek,通义千问或者本地搭建接口ollama,并支持配置mcp服务调用mcp 工具。

AI对话聊天功能的核心特点

1、自然语言理解 NLU

理解用户输入的意思,包括意图识别、实体提取等。 例如用户说“明天北京天气怎么样?”AI能识别出意图是“查天气”,地点是“北京”,时间是“明天”。

2、对话管理

维持多轮对话的连贯性,记住上下文。 比如在一轮对话中,用户说“我想订机票”,然后接着说“去北京”,系统要能理解这是继续订票流程。 不同用户对话历史记录存入数据库,永久保存,由用户自行管理,方便查阅

3、自然语言生成 NLG

将系统的回应内容用自然流畅的语言表达出来。 比如根据查询结果,可自定义查询天气的mpc工具调用天气接口,对话时AI自动调用工具查询天气,生成“明天北京最高气温20℃,最低12℃。”

4、MCP工具掉用

系统内置了几个基本示例MCP工具,用户可自行扩展工具,系统已对mcp扩展功能进行了封装,扩展非常方便。

插件下载:

https://plugins.g-fast.cn/store#/showModule?id=22

插件安装

一、覆盖下载插件后端代码,并安装相关依赖

将下载插件中go文件夹下的文件覆盖到后端,后端代码为一个新的目录,不会覆盖项目已有代码,可放心覆盖到项目根目录下,覆盖后修改以下几个配置:

internal/app/system/consts/consts.go文件添加常量:

20250529171357

 // WebSocketTypeChat websocket通知类型-AI对话 WebSocketTypeChat = "chat" WebSocketTypeLLMTools = "LLMTools" 

main.go文件中注册 mcp hook:

20250529171603

 import ( ... _ "github.com/tiger1103/gfast/v3/internal/app/mcp/hook" ... ) 

安装相关依赖:

 go get github.com/mark3labs/mcp-go go get github.com/cloudwego/eino go get github.com/cloudwego/eino-ext/components/model/openai go get github.com/cloudwego/eino-ext/components/model/deepseek go get github.com/cloudwego/eino-ext/components/model/ollama go get github.com/cloudwego/eino-ext/components/tool/mcp go get github.com/cloudwego/eino-ext/libs/acl/openai 

二、覆盖下载插件前端代码,并安装相关依赖

将下载插件中vue文件夹下的文件覆盖到前端

添加前端依赖 通过修改package.json文件添加依赖,在dependencies块中添加(推荐使用此方式):

 "dependencies": { "dompurify": "^3.2.5", "marked": "^15.0.11", "@types/highlight.js": "^9.12.4", "highlight.js": "^11.11.1", } "devDependencies":{ "@types/dompurify": "^3.0.5", "@types/marked": "^5.0.2", } 

添加后运行:npm install --registry=https://registry.npmmirror.com 或者通过命令行安装(如果使用了上面方式安装,跳过,不需重复安装):

 npm install dompurify@3.2.5 marked@15.0.11 @types/highlight.js@9.12.4 highlight.js@11.11.1 --registry=https://registry.npmmirror.com npm install @types/dompurify@3.0.5 @types/marked@5.0.2 --save-dev --registry=https://registry.npmmirror.com 

修改src/utils/websocket.ts文件,添加AI对话相关处理代码

20250529174021

 import { ToolCall, useChatStore } from '/@/stores/chatStore'; 

20250529174122

 if(message.event ==='chat'){ useChatStore().setChunkMessage(message.data) return } if(message.event ==='LLMTools'){ const tools = message.data as ToolCall[] useChatStore().setToolCall(tools) return } 

三、导入数据库文件

1.1 字典数据导入

导入字典数据文件字典.sql

1.2 流程相关数据表导入

导入数据表文件表数据.sql 

1.3 菜单数据导入

导入菜单数据文件菜单.sql 

注意:菜单.sql为脚本,需要在mysql命令中执行 。

四、使用说明

1、模型配置

20250530104802

例如添加通义千问:

20250530104852

填写模型和密钥

配置ollama:

20250530104945

配置模型deepseek-r1 和 接口地址

注意有的模型不支持函数调用,不能使用mcp,则函数调用选择否。

配置完成后可进入AI对话

选择对应模型

20250530105432

选择 ollama deepseek-r1 则有思考过程:

20250530105559

四、MCP工具添加

系统默认已经有几个示例MCP工具

20250530110153

对应代码目录在 internal/app/mcp/tools下:

20250530110344

如果需要新增MCP工具,只需在该目录下添加对应方法即可,GFAST已对该目录下工具进行封装自动注册,添加后会自动加载注入到系统中, 注意系统中自带数据库操作的工具只在开发环境下有作用,生产环境不会调用,防止生产故障和数据泄漏例如用户对AI说请清空数据库...)。

以下我们做一个添加mcp工具实践,例如添加天气预报查询工具:

internal/app/mcp/tools目录下新建文件:wether_query.go(文件名这些都是随意填写,没有限制)

20250530152927

添加以下代码:

 /* * @desc:天气预报查询tools  */ package tools import ( "context" "errors" "fmt" "github.com/gogf/gf/v2/encoding/gurl" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" "github.com/tiger1103/gfast/v3/internal/app/mcp/register" "github.com/tiger1103/gfast/v3/internal/consts" "github.com/tiger1103/gfast/v3/library/liberr" ) func (r *Reg) RegisterWeatherQuery() { // 注册工具 register.AddHandler(func(mcpServer *server.MCPServer) { // 添加工具 var ( tool = mcp.NewTool("weather_query", // 工具名称 mcp.WithDescription("查询给定城市的天气预报信息"), // 工具描述 mcp.WithString("city", // 参数名称 mcp.Required(), // 参数是必需的 mcp.Description("指定的城市名称"), // 参数描述 ), mcp.WithString("extensions", // 参数名称 mcp.Description("气象类型实况天气如现在,今天base;预报天气如这几天,明天等all"), // 参数描述 ), ) helloHandler = func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { var ( err error weather = new(Weather) ) err = g.Try(ctx, func(ctx context.Context) { // 从请求参数中获取名字参数,并断言为字符串类型 name, ok := request.GetArguments()["city"].(string) if !ok { // 如果断言失败,返回错误 liberr.ErrIsNilCode(ctx, errors.New("请给我一个城市名称"), consts.CodeInfo) } extensions := request.GetArguments()["extensions"].(string) weather, err = weather.Query(ctx, name, extensions) liberr.ErrIsNilCode(ctx, err, consts.CodeInfo) }) if err != nil { return r.returnRes(err) } // 返回结果 return mcp.NewToolResultText(fmt.Sprintf("该城市的天气预报信息为: %s!", gconv.String(weather))), nil } ) mcpServer.AddTool(tool, helloHandler) }) } func (s *Weather) Query(ctx context.Context, city, extensions string) (info *Weather, err error) { err = g.Try(ctx, func(ctx context.Context) { var ( key = "此处填写高德开发平台申请的接口key" cityInfo *AMapDistrictResponse ) cityInfo, err = s.GetDistricts(ctx, city, key) liberr.ErrIsNil(ctx, err) if cityInfo == nil || len(cityInfo.Districts) == 0 { liberr.ErrIsNil(ctx, errors.New("未查询到对应城市行政编码信息,请核对城市是否正确")) } info, err = s.GetWeather(ctx, cityInfo.Districts[0].AdCode, extensions, key) }) return } func (s *Weather) GetWeather(ctx context.Context, code, extensions, key string) (info *Weather, err error) { // 1. 构造请求 URL url := fmt.Sprintf( "https://restapi.amap.com/v3/weather/weatherInfo?city=%s&extensions=%s&key=%s", gurl.Encode(code), gurl.Encode(extensions), gurl.Encode(key), ) // 2. 发起 GET 请求 client := g.Client() resp, err := client.Get(ctx, url) if err != nil { return nil, fmt.Errorf("请求失败: %v", err) } defer resp.Close() // 3. 解析 JSON 响应 if err := gconv.Scan(resp.ReadAll(), &info); err != nil { return nil, fmt.Errorf("解析 JSON 失败: %v", err) } // 4. 检查接口返回状态 if info.Status != "1" { return nil, fmt.Errorf("查询天气接口返回错误: %s,状态码:%s", info.Info, info.Infocode) } return } // GetDistricts 调用高德地图行政区域查询接口 func (s *Weather) GetDistricts(ctx context.Context, keywords string, key string) (*AMapDistrictResponse, error) { // 1. 构造请求 URL url := fmt.Sprintf( "https://restapi.amap.com/v3/config/district?keywords=%s&subdistrict=2&key=%s", gurl.Encode(keywords), gurl.Encode(key), ) // 2. 发起 GET 请求 client := g.Client() resp, err := client.Get(ctx, url) if err != nil { return nil, fmt.Errorf("请求失败: %v", err) } defer resp.Close() // 3. 解析 JSON 响应 var result *AMapDistrictResponse if err := gconv.Scan(resp.ReadAll(), &result); err != nil { return nil, fmt.Errorf("解析 JSON 失败: %v", err) } // 4. 检查接口返回状态 if result.Status != "1" { return nil, fmt.Errorf("查询城市行政区划接口返回错误: %s,状态码:%s", result.Info, result.Infocode) } return result, nil } type Suggestion struct { Keywords []string `json:"keywords"` Cities []string `json:"cities"` } type District struct { CityCode string `json:"citycode"` AdCode string `json:"adcode"` Name string `json:"name"` Center string `json:"center"` Level string `json:"level"` } type AMapDistrictResponse struct { Status string `json:"status"` Info string `json:"info"` Infocode string `json:"infocode"` Count string `json:"count"` Suggestion Suggestion `json:"suggestion"` Districts []District `json:"districts"` } type Weather struct { Status string `json:"status"` Count string `json:"count"` Info string `json:"info"` Infocode string `json:"infocode"` Lives []struct { Province string `json:"province"` City string `json:"city"` Adcode string `json:"adcode"` Weather string `json:"weather"` Temperature string `json:"temperature"` Winddirection string `json:"winddirection"` Windpower string `json:"windpower"` Humidity string `json:"humidity"` Reporttime string `json:"reporttime"` TemperatureFloat string `json:"temperature_float"` HumidityFloat string `json:"humidity_float"` } `json:"lives"` Forecasts []struct { City string `json:"city"` Adcode string `json:"adcode"` Province string `json:"province"` Reporttime string `json:"reporttime"` Casts []struct { Date string `json:"date"` Week string `json:"week"` Dayweather string `json:"dayweather"` Nightweather string `json:"nightweather"` Daytemp string `json:"daytemp"` Nighttemp string `json:"nighttemp"` Daywind string `json:"daywind"` Nightwind string `json:"nightwind"` Daypower string `json:"daypower"` Nightpower string `json:"nightpower"` DaytempFloat string `json:"daytemp_float"` NighttempFloat string `json:"nighttemp_float"` } } `json:"forecasts"` } 

注意,天气查询接口用的是高德地图,需要在高德开放平台申请一个key即可免费使用

完成后对话如下图:

20250530153214

补充,使用MCP Inspector工具连接时,需要配置token

原文链接:https://www.oschina.net/news/353427
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章