Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add ai-intent plugin #1237

Merged
merged 9 commits into from
Aug 27, 2024
Merged

feature: add ai-intent plugin #1237

merged 9 commits into from
Aug 27, 2024

Conversation

lizhou0
Copy link
Contributor

@lizhou0 lizhou0 commented Aug 21, 2024

Ⅰ. Describe what this PR did

实现LLM 意图识别插件,能够智能判断用户请求与某个领域或agent的功能契合度,从而提升不同模型的应用效果和用户体验

Ⅱ. Does this pull request fix one issue?

fixes #1201 .

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

@CLAassistant
Copy link

CLAassistant commented Aug 21, 2024

CLA assistant check
All committers have signed the CLA.

| `DashScope.DashScopeDomain` | string | 非必填 | - | AI 服务提供商名称。目前支持以下取值:openai, azure, moonshot, qwen, zhipuai, baidu, minimax |
| `DashScope.DashScopeKey` | string | 非必填 | - | AI 服务提供商名称。目前支持以下取值:openai, azure, moonshot, qwen, zhipuai, baidu, minimax |
| `DashScope.DashScopeServiceName` | string | 必填 | - | 固定地址的服务,服务指向127.0.0.1:80 (即自身网关实例+端口),便于通过网关访问大模型 |
| `DashScope.Url` | string | 非必填 | /intent/api/v1/services/aigc/text-generation/generation | 新建一条higress的大模型路由,供该插件使用,路由以/intent作为前缀 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥是dashscope?而且还是qwen的url,用higress不应该用openai协议吗,配置字段名称也跟dashscope不应该有关系

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

字段名字是不应该小写开头?

if c.CacheKeyFrom.RequestBody == "" {
c.CacheKeyFrom.RequestBody = "[email protected]"
}
log.Info("Init ai intent's components successfully.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类似的日志等级都调整成debug

}
_ = proxywasm.ResumeHttpRequest()
return
}, 10000)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

超时时间要支持配置

log.Infof("start onHttpRequestHeaders function.")

log.Infof("end onHttpRequestHeaders function.")
return types.ActionContinue
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该使用 types.HeaderStopIteration,停止 header 处理,接收 body,否则请求已经发给后端了。
注意使用这个功能需要参考这个issue编译:
#1232 (comment)
另外,注意项目下增加这个文件:
https://github.com/alibaba/higress/blob/main/plugins/wasm-go/extensions/ai-proxy/.buildrc

DashScopeResponseBody, _ := DashScopeResponseHandle(ctx, responseBody, log)
//大模型返回的识别到的意图类型
if nil != DashScopeResponseBody && nil != DashScopeResponseBody.Choices && len(DashScopeResponseBody.Choices) > 0 {
category := DashScopeResponseBody.Choices[0].Message.Content
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接用这个content,不能确保取值一定是枚举值

| `DashScope.DashScopeDomain` | string | 非必填 | - | AI 服务提供商名称。目前支持以下取值:openai, azure, moonshot, qwen, zhipuai, baidu, minimax |
| `DashScope.DashScopeKey` | string | 非必填 | - | AI 服务提供商名称。目前支持以下取值:openai, azure, moonshot, qwen, zhipuai, baidu, minimax |
| `DashScope.DashScopeServiceName` | string | 必填 | - | 固定地址的服务,服务指向127.0.0.1:80 (即自身网关实例+端口),便于通过网关访问大模型 |
| `DashScope.Url` | string | 非必填 | /intent/api/v1/services/aigc/text-generation/generation | 新建一条higress的大模型路由,供该插件使用,路由以/intent作为前缀 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

字段名字是不应该小写开头?


| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
| -------------- | --------------- | -------- | ------ | ------------------------------------------------------------ |
| `Scene.Category` | string | 必填 | - | 预设场景类别 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个category配成一个数组是不是更便于使用?

plugins/wasm-go/extensions/ai-intent/main.go Outdated Show resolved Hide resolved
@lizhou0
Copy link
Contributor Author

lizhou0 commented Aug 22, 2024

@johnlanni @CH3CHO 代码已更新,相关内容整理如下:
1.为啥是dashscope?而且还是qwen的url,用higress不应该用openai协议吗,配置字段名称也跟dashscope不应该有关系。
readme中的url值当时未更新,现在统一调整了配置的字段名称,与dashscope无关。
2.类似的日志等级都调整成debug。
已修改
3.超时时间要支持配置。
已修改
4.应该使用 types.HeaderStopIteration,停止 header 处理,接收 body,否则请求已经发给后端了。
已修改
5.直接用这个content,不能确保取值一定是枚举值。
在给大模型的提问中明确指出了“直接返回一种具体类别,如果没有找到就返回'NotFound'。”,并且添加了返回结果是否包含在category中。
6.字段名字是不应该小写开头?
已修改
7.这个category配成一个数组是不是更便于使用?
category该字段的值会直接拼装在向大模型提问的 Prompt 预设问题中
8.用Handle的话就要放前面,放后面的话就要叫Handler。
已修改
9.新增.buildrc文件。
已修改

@@ -13,30 +13,28 @@ LLM 意图识别插件,能够智能判断用户请求与某个领域或agent

> 2.需新建一条higress的大模型路由,供该插件访问大模型,路由以 /intent 作为前缀,服务选择大模型服务,为该路由开启ai-proxy插件

> 3.需新建一个固定地址的服务,服务指向127.0.0.1:80 (即自身网关实例+端口),ai-intent插件内部需要该服务进行调用,以访问上述新增的路由,对应 DashScope.DashScopeServiceName
> 3.需新建一个固定地址的服务(如:intent-service),服务指向127.0.0.1:80 (即自身网关实例+端口),ai-intent插件内部需要该服务进行调用,以访问上述新增的路由,对应 DashScope.DashScopeServiceName
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这儿还是 dashscope 啊

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

抱歉,这里漏掉了,已更新

category: "['金融','电商','法律','Higress']"
prompt: "你是一个智能类别识别助手,负责根据用户提出的问题和预设的类别,确定问题属于哪个预设的类别,并给出相应的类别。用户提出的问题为:%s,预设的类别为%s,直接返回一种具体类别,如果没有找到就返回'NotFound'。"
llm:
proxyServiceName: "intent-service"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里测试过吗,Higress 上配出来的 service name 应该不长这样吧?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个测试过的,也是根据 #1201 中的建议:可以不用配置dasahcope字段,只需定义服务即可,可以把网关自身作为一个服务(127.0.0.1),然后复用网关的AI Proxy能力,统一用openai协议对接多个不同大模型。相当于这里添加了一个服务。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是我看你的实现只支持了 static 类型的服务,实际上也可以让用户配 Dns cluster,直接访问到 openai 等服务。这里建议参考下其他插件,用FQDNCluster

@CH3CHO
Copy link
Collaborator

CH3CHO commented Aug 22, 2024

category该字段的值会直接拼装在向大模型提问的 Prompt 预设问题中

这个是内部的实现细节,我们是否需要对用户暴露?

@lizhou0
Copy link
Contributor Author

lizhou0 commented Aug 22, 2024

category该字段的值会直接拼装在向大模型提问的 Prompt 预设问题中

这个是内部的实现细节,我们是否需要对用户暴露?

#1201 (comment)

@CH3CHO
Copy link
Collaborator

CH3CHO commented Aug 22, 2024

category该字段的值会直接拼装在向大模型提问的 Prompt 预设问题中

这个是内部的实现细节,我们是否需要对用户暴露?

#1201 (comment)

Fine.

@codecov-commenter
Copy link

codecov-commenter commented Aug 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 44.28%. Comparing base (ef31e09) to head (b9c9b72).
Report is 64 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1237      +/-   ##
==========================================
+ Coverage   35.91%   44.28%   +8.37%     
==========================================
  Files          69       75       +6     
  Lines       11576     9821    -1755     
==========================================
+ Hits         4157     4349     +192     
+ Misses       7104     5144    -1960     
- Partials      315      328      +13     

see 80 files with indirect coverage changes

@lizhou0
Copy link
Contributor Author

lizhou0 commented Aug 23, 2024

@johnlanni Build and Test Plugins 失败,报错:unknown directive: toolchain。在go.mod初始化的时候go版本较高 ,已提交修改go版本为1.19(之前版本写的1.21)且删除了toolchain部分

| `scene.category` | string | 必填 | - | 预设场景类别 |
| `scene.prompt` | string | 非必填 | 你是一个智能类别识别助手,负责根据用户提出的问题和预设的类别,确定问题属于哪个预设的类别,并给出相应的类别。用户提出的问题为:%s,预设的类别为%s,直接返回一种具体类别,如果没有找到就返回'NotFound'。 | llm请求prompt模板 |
| `llm.proxyServiceName` | string | 必填 | - | 新建的固定地址类型的服务,服务指向127.0.0.1:80 (即自身网关实例+端口),便于通过网关访问大模型 |
| `llm.proxyUrl` | string | 非必填 | /intent/compatible-mode/v1/chat/completions | 新建一条higress的大模型路由,供该插件使用,默认路由以/intent作为前缀 |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url的格式应该是类似:http://www.openai.com/v1/chat/completion
这样你可以从用户的配置里去同时解析出域名和path

category: "['金融','电商','法律','Higress']"
prompt: "你是一个智能类别识别助手,负责根据用户提出的问题和预设的类别,确定问题属于哪个预设的类别,并给出相应的类别。用户提出的问题为:%s,预设的类别为%s,直接返回一种具体类别,如果没有找到就返回'NotFound'。"
llm:
proxyServiceName: "intent-service"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是我看你的实现只支持了 static 类型的服务,实际上也可以让用户配 Dns cluster,直接访问到 openai 等服务。这里建议参考下其他插件,用FQDNCluster

proxyResponseBody, _ := proxyResponseHandler(responseBody, log)
//大模型返回的识别到的意图类型
if nil != proxyResponseBody && nil != proxyResponseBody.Choices && len(proxyResponseBody.Choices) > 0 {
category := proxyResponseBody.Choices[0].Message.Content
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个实现是否应该判断 content 中是否包含 category 枚举值?因为有时候LLM可能有废话,不是正好content就只返回这个category值

@lizhou0
Copy link
Contributor Author

lizhou0 commented Aug 26, 2024

@johnlanni 1.url的格式应该是类似:http://www.openai.com/v1/chat/completion
已修改,没有配置Domain、port相关字段时,则从proxyUrl配置中解析获取
2.但是我看你的实现只支持了 static 类型的服务,实际上也可以让用户配 Dns cluster,直接访问到 openai 等服务。这里建议参考下其他插件,用FQDNCluster
已修改
3.这个实现是否应该判断 content 中是否包含 category 枚举值?因为有时候LLM可能有废话,不是正好content就只返回这个category值
已修改,修改category字段格式和匹配逻辑。2种判定条件,1.返回的category与该预设的场景完全一致 2.返回的category包含该预设的场景

Copy link
Collaborator

@johnlanni johnlanni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@johnlanni johnlanni merged commit 2c1773a into alibaba:main Aug 27, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Higress 意图路由 AI_intent插件设计
5 participants