fengchaogo

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 15, 2024 License: MIT Imports: 11 Imported by: 0

README

Fengchao

FengChao Golang SDK

Quick Start

这是一个通过Prompt模板,来生成文章的例子,在使用时我们可以通过With方法来传递请求的多种参数,实现模板渲染,超时检测,模型的参数控制,最后可以直接输出生成内容的文本。


func ChatWithHistory() {
    client := fengchao.NewFengChao(ApiKey, ApiSecret, BaseUrl)
    client.SetLogger(logrus.StandardLogger())

    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewPromptTemplate(
            fengchao.NewMessage(fengchao.RoleSystem, systemPrompt),
            fengchao.NewMessage(fengchao.RoleUser, `
本次工作为根据已确认的选题《{{.title}}》,和参考内容完成一篇关于[{{.tags}}]的文章,文章中应避免使用总结、结论等类似的段落。
你要清楚,文章内容将会直接发表到新闻媒体中,稿件的阅读量会直接决定你的绩效考核成绩,请严格按照工作规范来完成,这将会影响你的职业生涯。
以下为本次选题的相关参考内容:
{{.text}}`),
        ),
        fengchao.WithParams(struct {
            title string
            text  string
            tags  string
        }{
            title: `国产AI增强操作系统发布:填补端侧推理空白`,
            text: `8月8日举行的2024中国操作系统产业大会上,国产桌面操作系统银河麒麟发布首个AIPC版本,这是一款与人工智能融合的国产桌面操作系统,填补了我国操作系统端侧推理能力研发的空白。
操作系统是计算机之魂,承接上层软件生态与底层硬件资源,为AI算法、模型与应用的运行提供支撑环境,在IT国产化中发挥重要作用。过去很长一段时间,全球操作系统厂商主要为欧美企业。
我国操作系统发展起步晚、系统生态存在短板,赶超压力大。新一轮人工智能技术的迅猛发展,为我国操作系统带来新机遇。`,
            tags: `#AI操作系统#国产操作系统#端侧推理`,
        }),
        fengchao.WithTemperature(0.9),
        fengchao.WithModel("gpt-4o"),
    )

    if err != nil {
    panic(err)
    }

    fmt.Println("结果如下:")
    fmt.Println(res)
}

如果需要更复杂的使用,请参考下面模块的文档

Prompt

PromptLLM的使用中是一个很重要的概念,为了简化用户手动构建Prompt。本项目提供了快速的创造Prompt的工具。

Message

Message是Prompt的基础,一个Prompt往往由多个MessageTemple组成。 目前我们提供两种创建Message的方式, 并提供Render方法提供携带变量的渲染,并获取格式化的Json数据。

使用用Message模版创建消息并渲染

import (
    "fmt"
    fengchao "github.com/ijiwei/fengchao-go"
)

func main() {
    UserMessage := fengchao.NewMessage(fengchao.RoleUser, `讲一个关于{{.name}}的笑话吧`)
    MessageJson, err := UserMessage.Render(map[string]interface{}{"name": "小狗"})
    if err != nil {
        panic(err)
    }
    fmt.Println(string(MessageJson)) 
    // output: {"role":"user","content":"讲一个关于小狗的笑话吧"}
}



模板渲染采用的是text/template,所以你可以使用任何其允许的编写方式来设计你的Prompt,甚至是编写循环

func main() {
    UserMessage := fengchao.NewMessage(fengchao.RoleUser, `分别讲一个关于{{range .Items}}、{{.}}{{end}}的笑话吧`)
    MessageJson, err :=UserMessage.Render(map[string]interface{}{"Items": []string{"小猫", "小狗", "小狐狸"}})
    if err != nil {
        panic(err)
    }
    fmt.Println(string(MessageJson)) 
    // output: {"role":"user","content":"分别讲一个关于、小猫、小狗、小狐狸的笑话吧"}
}
手动创建的Message

import fengchao "github.com/ijiwei/fengchao-go"

func main() {
    message := &fengchao.Message{
        Role: fengchao.RoleUser
        Content: "讲一个笑话吧"
    }
}

当然手动创建的Message同样也可以进行Render:


import fengchao "github.com/ijiwei/fengchao-go"

func main() {
    message := &fengchao.Message{
        Role: fengchao.RoleUser
        Content: "讲一个笑话吧"
    }
    MessageJson, err := message.Render(nil)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(MessageJson)) 
    // output: {"role":"user","content":"讲一个笑话吧"}
}

Template

熟悉了Message创建之后,就可以创造第一个Prompt



import fengchao "github.com/ijiwei/fengchao-go"

func main() {
    prompt := fengchao.NewPromptTemplate(
        fengchao.NewMessage(fengchao.RoleSystem, `你是一个非常厉害的{{.Name}}!`),
        fengchao.NewMessage(fengchao.RoleUser, `分别讲一个关于{{range .Items}}、{{.}}{{end}}的笑话吧`),
    )
    prompt.HumanFriendly = true
    PromptJson, err := prompt.Render(map[string]interface{}{
        "Items": []string{"小猫", "小狗", "小狐狸"},
        "Name": "智能助手",
    })

    if err != nil {
        panic(err)
    }
    fmt.Println(string(PromptJson)) 
}

output:

[
  {
    "role": "system",
    "content": "你是一个非常厉害的智能助手!"
  },
  {
    "role": "user",
    "content": "分别讲一个关于、小猫、小狗、小狐狸的笑话吧"
  }
]

Prompt也可以嵌套使用:


import fengchao "github.com/ijiwei/fengchao-go"

func main() {

    prompt := fengchao.NewPromptTemplate(
        fengchao.NewMessage(fengchao.RoleSystem, `你是一个非常厉害的{{.Name}}!`),
        fengchao.NewMessage(fengchao.RoleUser, `分别讲一个关于{{range .Items}}、{{.}}{{end}}的笑话吧`),
        fengchao.NewMessage(fengchao.RoleAssistant, `小猫:小猫去银行,工作人员问:“你要存什么?”小猫眨眨眼说:“我存爪印!”
小狗:小狗学会了打字,但每次发的都是“汪汪汪”,它说:“我这不是在聊天,是在打码!”
小狐狸:小狐狸问妈妈:“为什么我们叫狡猾?”妈妈笑着说:“因为我们知道怎么用优惠券!”`),
    )
    prompt = fengchao.NewPromptTemplate(
        prompt,
        fengchao.NewMessage(fengchao.RoleUser, `再讲{{.Count}}个好不好?`),
    )
    prompt.HumanFriendly = true
    PromptJson, err := prompt.Render(map[string]interface{}{
        "Items": []string{"小猫", "小狗", "小狐狸"},
        "Name": "智能助手",
        "Count": 3,
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(string(PromptJson)) 

}

output:

[
  {
    "role": "system",
    "content": "你是一个非常厉害的智能助手!"
  },
  {
    "role": "user",
    "content": "分别讲一个关于、小猫、小狗、小狐狸的笑话吧"
  },
  {
    "role": "assistant",
    "content": "小猫:小猫去银行,工作人员问:“你要存什么?”小猫眨眨眼说:“我存爪印!”\n小狗:小狗学会了打字,但每次发的都是“汪汪汪”,它说:“我这不是在聊天,是在打码!”\n小狐狸:小狐狸问妈妈:“为什么我们叫狡猾?”妈妈笑着说:“因为我们知道怎么用优惠券!”"
  },
  {
    "role": "user",
    "content": "太好笑了😂,再讲3个好不好?"
  }
]

Chat

Chat Completion

在进行对话前,首先需要获取到一对API KEY和Secret,以及Fengchao服务的Url

同步Chat

ChatCopletion方法会在API完成响应的返回ChatCopletion对象, 可以获取对话相关的信息,也可以直接打印(已经实现了String()方法)。


func SimpleChat() {
    apiKey := "you api key"
    apiSecret := "you api secret"
    client := fengchao.NewFengChao(apiKey, apiSecret, "http://fengchao.api")
    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewMessage(fengchao.RoleUser, "讲一个冷笑话"),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("结果如下:")
    fmt.Println(res)
}

也可以使用复杂的Prompt Template来进行生成

func SimpleChat() {
    apiKey := "you api key"
    apiSecret := "you api secret"
    client := fengchao.NewFengChao(apiKey, apiSecret, "http://fengchao.api")
    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewMessage(fengchao.RoleUser, "讲一个{{.Story}}"),
        fengchao.WithParams(map[string]string{
            "Story": "鬼故事",
        }),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("结果如下:")
    fmt.Println(res)
}

除此之外,我们也可通过其History属性,获取对话的列表数据

func SimpleChat() {
    apiKey := "you api key"
    apiSecret := "you api secret"
    client := fengchao.NewFengChao(apiKey, apiSecret, "http://fengchao.api")
    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewMessage(fengchao.RoleUser, "讲一个{{.Story}}"),
        fengchao.WithParams(map[string]string{
            "Story": "鬼故事",
        }),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("结果如下:")
    fmt.Println(res)
    historyData, err := json.MarshalIndent(res.History, "", "   ")
    if err != nil {
        panic(fmt.Sprintf("marshal history error: %v", err))
    }

    fmt.Println("对话记录如下:")
    fmt.Println(string(historyData))
}

当我们想使用对话记录快速构建Prompt的时候,对话记录也提供了一个构建PromptTemplate的方法

func SimpleChat() {
    apiKey := "you api key"
    apiSecret := "you api secret"
    client := fengchao.NewFengChao(apiKey, apiSecret, "http://fengchao.api")
    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewMessage(fengchao.RoleUser, "讲一个{{.Story}}"),
        fengchao.WithParams(map[string]string{
            "Story": "鬼故事",
        }),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("结果如下:")
    fmt.Println(res)

    promptTemplate := fengchao.NewPromptTemplate(
        res.GetHistoryPrompts(),
        fengchao.NewMessage(fengchao.RoleUser, `根据文章内容,总结一份{{.language}}摘要`),
    )
}

我们可以使用它来继续构建下一次的对话

func SimpleChat() {
    apiKey := "you api key"
    apiSecret := "you api secret"
    client := fengchao.NewFengChao(apiKey, apiSecret, "http://fengchao.api")
    res, err := client.ChatCompletion(
        context.Background(),
        fengchao.NewMessage(fengchao.RoleUser, "讲一个{{.Story}}"),
        fengchao.WithParams(map[string]string{
            "Story": "鬼故事",
        }),
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("结果如下:")
    fmt.Println(res)

    prompt := fengchao.NewPromptTemplate(
        res.GetHistoryPrompts(),
        fengchao.NewMessage(fengchao.RoleUser, `根据文章内容,总结一份{{.language}}摘要`),
    )

    res, err = client.ChatCompletion(
        ctx,
        prompt,
        fengchao.WithTemperature(0.9),
        fengchao.WithModel("glm-4"),
        fengchao.WithParams(map[string]interface{}{"language": "英文"})
    )

    if err != nil {
        panic(err)
    }

    fmt.Println("结果如下:")
    fmt.Println(res)
}
🏗

Documentation

Index

Constants

View Source
const (
	RoleUser      = "user"
	RoleAssistant = "assistant"
	RoleSystem    = "system"
)
View Source
const BasicRequestTimeout int = 3
View Source
const ExpiresTime = 1700

Variables

View Source
var DefaultChatCompletionOption = &ChatCompletion{
	Model:       "ERNIE-Bot-4",
	Stop:        []string{},
	MaxTokens:   2000,
	Timeout:     60,
	IsSensitive: false,
}

DefaultChatCompletionOption 默认配置, 可以覆盖

Functions

func NewMessage

func NewMessage(role string, messageStr string) lazyMessage

Types

type ChatCompletion

type ChatCompletion struct {
	// RequestID 请求ID
	RequestID string `json:"request_id"`
	// Model 模型
	Model string `json:"model"`
	// Temperature 模型参数
	Temperature float64 `json:"temperature,omitempty"`
	// TopP 模型参数
	TopP float64 `json:"top_p,omitempty"`
	// DoSample 是否开启采样
	DoSample bool `json:"do_sample"`
	// IsSensitive 是否开启敏感词
	IsSensitive bool `json:"is_sensitive"`
	// MaxTokens 最大长度
	MaxTokens int `json:"max_tokens,omitempty"`
	// Stop 停用词
	History []*Message `json:"history"`
	// Query 问题
	Query string `json:"query"`
	// System 系统消息
	System string `json:"system"`

	// Stop 停用词
	Stop []string
	// Timeout 超时时间
	Timeout int
	// contains filtered or unexported fields
}

func (*ChatCompletion) Apply

func (option *ChatCompletion) Apply(helpers ...Option[ChatCompletion])

Apply 应用配置

func (*ChatCompletion) Clone

func (cc *ChatCompletion) Clone() *ChatCompletion

clone 拷贝

func (*ChatCompletion) LoadPromptTemplates

func (option *ChatCompletion) LoadPromptTemplates(prompt Prompt) ([]*Message, error)

RenderMessages 渲染消息列表

type ChatCompletionResult

type ChatCompletionResult struct {
	RequestID string `json:"request_id"`
	Object    string `json:"object"`
	Created   string `json:"created"`
	Choices   []struct {
		Index        int     `json:"index"`
		Role         string  `json:"role"`
		FinishReason string  `json:"finish_reason"`
		Message      Message `json:"message"`
	} `json:"choices"`
	Usage struct {
		PromptTokens     int `json:"prompt_tokens"`
		CompletionTokens int `json:"completion_tokens"`
		TotalTokens      int `json:"total_tokens"`
	} `json:"usage"`
	Msg     string `json:"msg"`
	Status  int    `json:"status"`
	History []*Message
}

func (*ChatCompletionResult) GetHistoryPrompts

func (r *ChatCompletionResult) GetHistoryPrompts() *PromptTemplate

func (*ChatCompletionResult) String

func (r *ChatCompletionResult) String() string

type FengChao

type FengChao struct {
	// ApiKey fengchao api key
	ApiKey string
	// SecretKey fengchao secret key
	SecretKey string
	// BaseUrl api url
	BaseUrl string

	sync.Mutex
	// contains filtered or unexported fields
}

FengChaoOptions 配置

func NewFengChao

func NewFengChao(apiKey string, secretKey string, baseUrl string) *FengChao

func (*FengChao) ChatCompletion

func (f *FengChao) ChatCompletion(ctx context.Context, prompt Prompt, chatCompletionOption ...Option[ChatCompletion]) (*ChatCompletionResult, error)

func (*FengChao) GetAvailableModels

func (f *FengChao) GetAvailableModels() []Model

func (*FengChao) SetDebug

func (f *FengChao) SetDebug(debug bool) *FengChao

type Message

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
	// contains filtered or unexported fields
}

func (*Message) Render

func (m *Message) Render(vairables map[string]interface{}) ([]byte, error)

func (*Message) RenderMessages

func (m *Message) RenderMessages(vairables map[string]interface{}) ([]*Message, error)

type Model

type Model struct {
	ID             string   `json:"id"`
	OwnedBy        string   `json:"owned_by"`
	MaxInputToken  int      `json:"max_input_token"`
	MaxOutputToken int      `json:"max_output_token"`
	InPrice        float64  `json:"in_price"`
	OutPrice       float64  `json:"out_price"`
	Unit           string   `json:"unit"`
	Modes          []string `json:"mode"`
	Channel        string   `json:"channel"`
	Created        string   `json:"created"`
}

type Option

type Option[T any] func(option *T)

OptionHelper 配置

func WithDoSample

func WithDoSample(doSample bool) Option[ChatCompletion]

WithDoSample 设置是否开启采样

func WithHistory

func WithHistory(history []*Message) Option[ChatCompletion]

WithHistory 设置历史消息

func WithIsSensitive

func WithIsSensitive(isSensitive bool) Option[ChatCompletion]

WithIsSensitive 设置是否开启敏感词

func WithMaxTokens

func WithMaxTokens(maxTokens int) Option[ChatCompletion]

WithMaxTokens 设置最大长度

func WithModel

func WithModel(model string) Option[ChatCompletion]

WithModel 设置模型

func WithParams

func WithParams(variables any) Option[ChatCompletion]

WithVariables 设置变量

func WithQuery

func WithQuery(query string) Option[ChatCompletion]

WithQuery 设置问题

func WithRequestID

func WithRequestID(requestID string) Option[ChatCompletion]

func WithStop

func WithStop(stop []string) Option[ChatCompletion]

WithStop 设置停用词

func WithSystem

func WithSystem(system string) Option[ChatCompletion]

WithSystem 设置系统消息

func WithTemperature

func WithTemperature(temperature float64) Option[ChatCompletion]

WithTemperature 设置模型参数

func WithTimeout

func WithTimeout(timeout int) Option[ChatCompletion]

WithTimeout 设置超时时间

func WithTopP

func WithTopP(topP float64) Option[ChatCompletion]

WithTopP 设置模型参数

type Prompt

type Prompt interface {
	// Render 渲染,这个用来展示
	Render(vairables map[string]interface{}) ([]byte, error)
	// RenderMessages 渲染消息列表,对应的渲染方法是 Render,这个提供给用户自定义使用
	RenderMessages(vairables map[string]interface{}) ([]*Message, error)
}

Prompt 接口, 暴露一个渲染的能力

type PromptTemplate

type PromptTemplate struct {
	Messages []*Message
	Prompts  []Prompt

	HumanFriendly bool
}

PromptTemplate 模板

func NewPromptTemplate

func NewPromptTemplate(p ...Prompt) *PromptTemplate

NewPromptTemplate 创建 PromptTemplate

func (*PromptTemplate) MarshalJSON

func (m *PromptTemplate) MarshalJSON() ([]byte, error)

MarshalJSON 渲染

func (*PromptTemplate) Render

func (m *PromptTemplate) Render(vairables map[string]interface{}) ([]byte, error)

Render 渲染 Prompt

func (*PromptTemplate) RenderMessages

func (m *PromptTemplate) RenderMessages(vairables map[string]interface{}) ([]*Message, error)

RenderMessages 渲染消息列表

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL