
介绍完链式调用后,我们开始介绍RAG,RAG最核心的就是文本迁入,如何嵌入呢?首先我们要定义嵌入模型,然后进行文本的向量化,具体看下面的例子
llm, err := openai.New(
openai.WithEmbeddingModel("text-embedding-ada-002"),
openai.WithBaseURL(Openai.Host),
openai.WithToken(Openai.Key),
)
if err != nil {
log.Fatal(err)
}
vectors, err := llm.CreateEmbedding(ctx, []string{"chatgpt-3.5"})
if err != nil {
log.Fatal(err)
}
fmt.Println(vectors)在定义模型的时候使用了openai.WithEmbeddingModel来定义嵌入模型 用法和定义LLM是一样的。
func WithEmbeddingModel(embeddingModel string) Option {
return func(opts *options) {
opts.embeddingModel = embeddingModel
}
}定义模型后就可以使用这个模型来向量化
// CreateEmbedding creates embeddings for the given input texts.
func (o *LLM) CreateEmbedding(ctx context.Context, inputTexts []string) ([][]float32, error) {
embeddings, err := o.client.CreateEmbedding(ctx, &openaiclient.EmbeddingRequest{
Input: inputTexts,
Model: o.client.EmbeddingModel,
})
if err != nil {
return nil, fmt.Errorf("failed to create openai embeddings: %w", err)
}
if len(embeddings) == 0 {
return nil, ErrEmptyResponse
}
if len(inputTexts) != len(embeddings) {
return embeddings, ErrUnexpectedResponseLength
}
return embeddings, nil
}它调用了http客户端的CreateEmbedding方法
func (c *Client) CreateEmbedding(ctx context.Context, r *EmbeddingRequest) ([][]float32, error) {
if r.Model == "" {
r.Model = defaultEmbeddingModel
}
resp, err := c.createEmbedding(ctx, &embeddingPayload{
Model: r.Model,
Input: r.Input,
})
if err != nil {
return nil, err
}
if len(resp.Data) == 0 {
return nil, ErrEmptyResponse
}
embeddings := make([][]float32, 0)
for i := 0; i < len(resp.Data); i++ {
embeddings = append(embeddings, resp.Data[i].Embedding)
}
return embeddings, nil
}最终是对路径/embeddings发起了http的POST请求
// nolint:lll
func (c *Client) createEmbedding(ctx context.Context, payload *embeddingPayload) (*embeddingResponsePayload, error) {
if c.baseURL == "" {
c.baseURL = defaultBaseURL
}
if c.Model == "" {
payload.Model = c.EmbeddingModel
}
if payload.Model == "" {
payload.Model = defaultEmbeddingModel
}
payloadBytes, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("marshal payload: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.buildURL("/embeddings", c.EmbeddingModel), bytes.NewReader(payloadBytes))
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
c.setHeaders(req)向量化返回的结构体定义如下
type embeddingResponsePayload struct {
Object string `json:"object"`
Data []struct {
Object string `json:"object"`
Embedding []float32 `json:"embedding"`
Index int `json:"index"`
} `json:"data"`
Model string `json:"model"`
Usage struct {
PromptTokens int `json:"prompt_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!