mirror of
https://github.com/alibaba/higress.git
synced 2026-05-27 06:07:27 +08:00
update template decorator (#1142)
This commit is contained in:
@@ -1,18 +1,12 @@
|
|||||||
# 简介
|
# 简介
|
||||||
AI提示词修饰插件,通过在与大模型发起的请求前后插入指定信息来调整大模型的输出。
|
AI提示词装饰器插件,支持在LLM的请求前后插入prompt。
|
||||||
|
|
||||||
# 配置说明
|
# 配置说明
|
||||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
|
||||||
|----------------|-----------------|------|-----|----------------------------------|
|
|
||||||
| `decorators` | array of object | 必填 | - | 修饰设置 |
|
|
||||||
|
|
||||||
template object 配置说明:
|
|
||||||
|
|
||||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||||
|----------------|-----------------|------|-----|----------------------------------|
|
|----------------|-----------------|------|-----|----------------------------------|
|
||||||
| `name` | string | 必填 | - | 修饰名称 |
|
| `prepend` | array of message object | optional | - | 在初始输入之前插入的语句 |
|
||||||
| `decorator.prepend` | array of message object | 必填 | - | 在初始输入之前插入的语句 |
|
| `append` | array of message object | optional | - | 在初始输入之后插入的语句 |
|
||||||
| `decorator.append` | array of message object | 必填 | - | 在初始输入之后插入的语句 |
|
|
||||||
|
|
||||||
message object 配置说明:
|
message object 配置说明:
|
||||||
|
|
||||||
@@ -26,57 +20,50 @@ message object 配置说明:
|
|||||||
配置示例如下:
|
配置示例如下:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
decorators:
|
prepend:
|
||||||
- name: "hangzhou-guide"
|
- role: system
|
||||||
decorator:
|
content: "请使用英语回答问题"
|
||||||
prepend:
|
append:
|
||||||
- role: system
|
- role: user
|
||||||
content: "You will always respond in the Chinese language."
|
content: "每次回答完问题,尝试进行反问"
|
||||||
- role: user
|
|
||||||
content: "Assume you are from Hangzhou."
|
|
||||||
append:
|
|
||||||
- role: user
|
|
||||||
content: "Don't introduce Hangzhou's food."
|
|
||||||
```
|
```
|
||||||
|
|
||||||
使用以上配置发起请求:
|
使用以上配置发起请求:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
{
|
curl http://localhost/test \
|
||||||
|
-H "content-type: application/json" \
|
||||||
|
-d '{
|
||||||
"model": "gpt-3.5-turbo",
|
"model": "gpt-3.5-turbo",
|
||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
"role": "user",
|
"role": "user",
|
||||||
"content": "Please introduce your home."
|
"content": "你是谁?"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
响应如下:
|
经过插件处理后,实际请求为:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
{
|
curl http://localhost/test \
|
||||||
"id": "chatcmpl-9UYwQlEg6GwAswEZBDYXl41RU4gab",
|
-H "content-type: application/json" \
|
||||||
"object": "chat.completion",
|
-d '{
|
||||||
"created": 1717071182,
|
"model": "gpt-3.5-turbo",
|
||||||
"model": "gpt-3.5-turbo-0125",
|
"messages": [
|
||||||
"choices": [
|
|
||||||
{
|
{
|
||||||
"index": 0,
|
"role": "system",
|
||||||
"message": {
|
"content": "请使用英语回答问题"
|
||||||
"role": "assistant",
|
},
|
||||||
"content": "杭州是一个美丽的城市,有着悠久的历史和富有特色的文化。这里风景优美,有西湖、雷峰塔等著名景点,吸引着许多游客前来观光。杭州人民热情好客,城市宁静安逸,是一个适合居住和旅游的地方。"
|
{
|
||||||
},
|
"role": "user",
|
||||||
"logprobs": null,
|
"content": "你是谁?"
|
||||||
"finish_reason": "stop"
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "每次回答完问题,尝试进行反问"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"usage": {
|
|
||||||
"prompt_tokens": 49,
|
|
||||||
"completion_tokens": 117,
|
|
||||||
"total_tokens": 166
|
|
||||||
},
|
|
||||||
"system_fingerprint": null
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
github.com/alibaba/higress/plugins/wasm-go v1.3.5 h1:VOLL3m442IHCSu8mR5AZ4sc6LVT9X0w1hdqDI7oB9jY=
|
|
||||||
github.com/alibaba/higress/plugins/wasm-go v1.3.5/go.mod h1:kr3V9Ntbspj1eSrX8rgjBsdMXkGupYEf+LM72caGPQc=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 h1:IHDghbGQ2DTIXHBHxWfqCYQW1fKjyJ/I7W1pMyUDeEA=
|
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 h1:IHDghbGQ2DTIXHBHxWfqCYQW1fKjyJ/I7W1pMyUDeEA=
|
||||||
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520/go.mod h1:Nz8ORLaFiLWotg6GeKlJMhv8cci8mM43uEnLA5t8iew=
|
github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520/go.mod h1:Nz8ORLaFiLWotg6GeKlJMhv8cci8mM43uEnLA5t8iew=
|
||||||
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240226064518-b3dc4646a35a h1:luYRvxLTE1xYxrXYj7nmjd1U0HHh8pUPiKfdZ0MhCGE=
|
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240711023527-ba358c48772f h1:ZIiIBRvIw62gA5MJhuwp1+2wWbqL9IGElQ499rUsYYg=
|
||||||
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240226064518-b3dc4646a35a/go.mod h1:hNFjhrLUIq+kJ9bOcs8QtiplSQ61GZXtd2xHKx4BYRo=
|
|
||||||
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240711023527-ba358c48772f/go.mod h1:hNFjhrLUIq+kJ9bOcs8QtiplSQ61GZXtd2xHKx4BYRo=
|
github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240711023527-ba358c48772f/go.mod h1:hNFjhrLUIq+kJ9bOcs8QtiplSQ61GZXtd2xHKx4BYRo=
|
||||||
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
|
||||||
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"encoding/json"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
"github.com/alibaba/higress/plugins/wasm-go/pkg/wrapper"
|
||||||
"github.com/higress-group/proxy-wasm-go-sdk/proxywasm"
|
"github.com/higress-group/proxy-wasm-go-sdk/proxywasm"
|
||||||
@@ -20,66 +19,53 @@ func main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Message struct {
|
||||||
|
Role string `json:"role"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
type AIPromptDecoratorConfig struct {
|
type AIPromptDecoratorConfig struct {
|
||||||
decorators map[string]string
|
Prepend []Message `json:"prepend"`
|
||||||
|
Append []Message `json:"append"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeBrackets(raw string) (string, error) {
|
func parseConfig(jsonConfig gjson.Result, config *AIPromptDecoratorConfig, log wrapper.Log) error {
|
||||||
startIndex := strings.Index(raw, "{")
|
return json.Unmarshal([]byte(jsonConfig.Raw), config)
|
||||||
endIndex := strings.LastIndex(raw, "}")
|
|
||||||
if startIndex == -1 || endIndex == -1 {
|
|
||||||
return raw, errors.New("message format is wrong!")
|
|
||||||
} else {
|
|
||||||
return raw[startIndex : endIndex+1], nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseConfig(json gjson.Result, config *AIPromptDecoratorConfig, log wrapper.Log) error {
|
|
||||||
config.decorators = make(map[string]string)
|
|
||||||
for _, v := range json.Get("decorators").Array() {
|
|
||||||
config.decorators[v.Get("name").String()] = v.Get("decorator").Raw
|
|
||||||
// log.Info(v.Get("decorator").Raw)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func onHttpRequestHeaders(ctx wrapper.HttpContext, config AIPromptDecoratorConfig, log wrapper.Log) types.Action {
|
func onHttpRequestHeaders(ctx wrapper.HttpContext, config AIPromptDecoratorConfig, log wrapper.Log) types.Action {
|
||||||
decorator, _ := proxywasm.GetHttpRequestHeader("decorator")
|
|
||||||
if decorator == "" {
|
|
||||||
ctx.DontReadRequestBody()
|
|
||||||
return types.ActionContinue
|
|
||||||
}
|
|
||||||
ctx.SetContext("decorator", decorator)
|
|
||||||
proxywasm.RemoveHttpRequestHeader("decorator")
|
|
||||||
proxywasm.RemoveHttpRequestHeader("content-length")
|
proxywasm.RemoveHttpRequestHeader("content-length")
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func onHttpRequestBody(ctx wrapper.HttpContext, config AIPromptDecoratorConfig, body []byte, log wrapper.Log) types.Action {
|
func onHttpRequestBody(ctx wrapper.HttpContext, config AIPromptDecoratorConfig, body []byte, log wrapper.Log) types.Action {
|
||||||
decoratorName := ctx.GetContext("decorator").(string)
|
|
||||||
decorator := config.decorators[decoratorName]
|
|
||||||
|
|
||||||
messageJson := `{"messages":[]}`
|
messageJson := `{"messages":[]}`
|
||||||
|
|
||||||
prependMessage := gjson.Get(decorator, "prepend")
|
for _, entry := range config.Prepend {
|
||||||
if prependMessage.Exists() {
|
msg, err := json.Marshal(entry)
|
||||||
for _, entry := range prependMessage.Array() {
|
if err != nil {
|
||||||
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", entry.Raw)
|
log.Errorf("Failed to add prepend message, error: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", string(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
rawMessage := gjson.GetBytes(body, "messages")
|
rawMessage := gjson.GetBytes(body, "messages")
|
||||||
if rawMessage.Exists() {
|
if !rawMessage.Exists() {
|
||||||
for _, entry := range rawMessage.Array() {
|
log.Errorf("Cannot find messages field in request body")
|
||||||
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", entry.Raw)
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
for _, entry := range rawMessage.Array() {
|
||||||
|
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", entry.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
appendMessage := gjson.Get(decorator, "append")
|
for _, entry := range config.Append {
|
||||||
if appendMessage.Exists() {
|
msg, err := json.Marshal(entry)
|
||||||
for _, entry := range appendMessage.Array() {
|
if err != nil {
|
||||||
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", entry.Raw)
|
log.Errorf("Failed to add prepend message, error: %v", err)
|
||||||
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
|
messageJson, _ = sjson.SetRaw(messageJson, "messages.-1", string(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
newbody, err := sjson.SetRaw(string(body), "messages", gjson.Get(messageJson, "messages").Raw)
|
newbody, err := sjson.SetRaw(string(body), "messages", gjson.Get(messageJson, "messages").Raw)
|
||||||
|
|||||||
Reference in New Issue
Block a user