(api)使用 Completion Q&A 模式

在线运行open in new window启动 AI 助手open in new window

func main() {
	client := openai.NewClient("sk-your-key")
	resp, err := client.CreateChatCompletion(
		context.Background(),
		openai.ChatCompletionRequest{
			Model: openai.GPT3Dot5Turbo,
			Messages: []openai.ChatCompletionMessage{
				{
					Role:    openai.ChatMessageRoleUser,
					Content: "Hello!",
				},
			},
		},
	)

	if err != nil {
		fmt.Printf("ChatCompletion error: %v\n", err)
		return
	}

	fmt.Println(resp.Choices[0].Message.Content)
}

程序使用OpenAI的GPT-3.5 Turbo模型进行聊天文本生成。

在主函数中,它创建了一个OpenAI客户端,并使用提供的API密钥进行身份验证。然后,它发送一个包含用户角色和内容的聊天消息给GPT-3.5 Turbo模型进行处理,并接收生成的回复。

(api)实现交互式的问答

在线运行open in new window启动 AI 助手open in new window

func main() {
	client := openai.NewClient("sk-your-key")
	messages := make([]openai.ChatCompletionMessage, 0)
	reader := bufio.NewReader(os.Stdin)

	for {
		// 提示符
		fmt.Print("-> ")
		text, _ := reader.ReadString('\n')
		// 把 CRLF 转成 LF
		text = strings.Replace(text, "\n", "", -1)

		resp, err := client.CreateChatCompletion(
			context.Background(),
			openai.ChatCompletionRequest{
				Model:    openai.GPT3Dot5Turbo,
				Messages: []openai.ChatCompletionMessage{
				    {
				        Role:    openai.ChatMessageRoleUser,
			            Content: text,
				    },
				},
			},
		)

		if err != nil {
			fmt.Printf("ChatCompletion error: %v\n", err)
			continue
		}

		content := resp.Choices[0].Message.Content
		messages = append(messages, openai.ChatCompletionMessage{
			Role:    openai.ChatMessageRoleAssistant,
			Content: content,
		})

		fmt.Println(content)
	}
}

在程序中,它创建了一个OpenAI客户端,并使用提供的API密钥进行身份验证。

然后,它使用标准输入读取用户的输入,并将用户的消息添加到消息列表中。

随后,它调用CreateChatCompletion函数来获取OpenAI模型的回复。回复中的内容被添加到消息列表,并打印出来。循环会不断读取用户的输入并生成回复。

(api)使用 Dall-E 实现文生图

在线运行open in new window启动 AI 助手open in new window

func main() {
	c := openai.NewClient("sk-your-key")
	ctx := context.Background()

	reqUrl := openai.ImageRequest{
		Prompt:         "A yellow cat on the tree, cartoon style, natural light, high detail",
		Size:           openai.CreateImageSize256x256,
		ResponseFormat: openai.CreateImageResponseFormatURL,
		N:              1,
	}

	respUrl, err := c.CreateImage(ctx, reqUrl)
	if err != nil {
		fmt.Printf("Image creation error: %v\n", err)
		return
	}
	fmt.Println(respUrl.Data[0].URL)

	reqBase64 := openai.ImageRequest{
		Prompt:         "Portrait of a humanoid parrot in a classic costume, high detail, realistic light, unreal engine",
		Size:           openai.CreateImageSize256x256,
		ResponseFormat: openai.CreateImageResponseFormatB64JSON,
		N:              1,
	}

	respBase64, err := c.CreateImage(ctx, reqBase64)
	if err != nil {
		fmt.Printf("Image creation error: %v\n", err)
		return
	}

	imgBytes, err := base64.StdEncoding.DecodeString(respBase64.Data[0].B64JSON)
	if err != nil {
		fmt.Printf("Base64 decode error: %v\n", err)
		return
	}

	r := bytes.NewReader(imgBytes)
	imgData, err := png.Decode(r)
	if err != nil {
		fmt.Printf("PNG decode error: %v\n", err)
		return
	}

	file, err := os.Create("/tmp/a_yellow_cat.png")
	if err != nil {
		fmt.Printf("File creation error: %v\n", err)
		return
	}
	defer file.Close()

	if err := png.Encode(file, imgData); err != nil {
		fmt.Printf("PNG encode error: %v\n", err)
		return
	}

	fmt.Println("The image was saved")
}

在主函数中,它创建了一个OpenAI客户端并进行身份验证。 然后,它通过调用CreateImage函数来创建图像。

程序中展示了两种不同的请求方式:一种是通过URL获取图像,另一种是将图像以base64编码的JSON格式获取。对于以base64编码的JSON格式获取的图像,程序对其进行解码并保存为PNG文件。

最后,它打印出图像的URL(如果是通过URL获取的)和保存成功的消息。

(api)把语音转换成文本字幕

在线运行open in new window启动 AI 助手open in new window

func main() {
	c := openai.NewClient("sk-your-key")
	req := openai.AudioRequest{
		Model:    openai.Whisper1,
		FilePath: "recording.mp3",
	}

	resp, err := c.CreateTranscription(context.Background(), req)
	if err != nil {
		fmt.Printf("Transcription error: %v\n", err)
		return
	}
	
	fmt.Println(resp.Text)
}

程序使用OpenAI的Whisper模型来进行音频转录。

首先创建了一个OpenAI客户端,并使用提供的API密钥进行身份验证。

然后,它通过调用CreateTranscription函数来对指定的音频文件进行转录,转录的结果会打印出来。

(lcg)使用 Completion Q&A 模式

在线运行open in new window启动 AI 助手open in new window

const (
	// plz replace below to your openai api key secret
	OPENAI_API_KEY = "sk-your-key"
)

func main() {
	os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.New()
	if err != nil {
		log.Fatal(err)
	}

	completion, err := llm.Call(context.Background(), "What would be a good name for a cute cat?")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(completion)
	// 输出 Fluffy, Snowball, Misty, Simba, Coco, Tiger, Shadow, Gizmo, Oreo, Luna.
}

在程序中,我们首先使用 os.Setenv() 函数设置 OPENAI_API_KEY 环境变量,以便程序可以访问 OpenAI 的 API。

然后,我们创建一个 openai.LLM 对象,并使用 llm.Call() 方法调用 GPT 模型来生成自然语言回答。在这个例子中,我们询问 GPT 模型“如何给一只可爱的猫起一个好名字?”,然后模型返回了一个包含自然语言文本的结构体 completion。

最后,将文本输出到终端上。

(lcg)补全单词并且设置忽略内容

在线运行open in new window启动 AI 助手open in new window

const (
	// plz replace below to your openai api key secret
	OPENAI_API_KEY = "sk-your-key"
)

func main() {
	os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.New()
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()
	completion, err := llm.Call(ctx, "The first man to walk on the moon", llms.WithStopWords([]string{"Armstrong"}))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(completion)
    // The first man to walk on the moon was Neil
}

在这个程序中,我们首先定义了一个常量 OPENAI_API_KEY,它包含了我们的 OpenAI API 密钥。然后,我们使用 os.Setenv() 函数将该密钥存储在环境变量 OPENAI_API_KEY 中,以便应用程序在稍后的 API 调用中使用该密钥。

在 main() 函数中,我们创建了一个新的 OpenAI 客户端对象 llm,并使用 llm.Call() 方法调用 GPT 模型来获取一个自然语言文本的补全。在这个示例中,我们要求模型根据给定的输入 “The first man to walk on the moon” 来补全下一个单词,但是我们不希望模型返回 "Armstrong" 这个词汇,因此我们使用 llms.WithStopWords() 方法将其排除。

如果我们设置其他忽略单词或者补设置,AI 的回答会是 “The first man to walk on the moon was Neil Armstrong on July 20, 1969.”。

(lcg)使用 Chain 执行预设提示模版

在线运行open in new window启动 AI 助手open in new window

func main() {
    os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.New()
	if err != nil {
		panic(err)
	}

	prompt := prompts.NewPromptTemplate(
		"What is a good name for a company that makes {{.product}}?",
		[]string{"product"},
	)

	llmChain := chains.NewLLMChain(llm, prompt)
	// out, err := chains.Run(context.Background(), llmChain, "bread")
	// 多个参数调用 Call 函数,第三个参数传入 map[string]any 类型
    out, err := chains.Call(context.Background(), llmChain, map[string]any{
        "product": "bread",
    })
	if err != nil {
		panic(err)
	}
	fmt.Println(out)
}

(lcg)聊天机器人

在线运行open in new window启动 AI 助手open in new window

func main() {
    os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.NewChat()
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()
	completion, err := llm.Call(ctx, []schema.ChatMessage{
		schema.SystemChatMessage{Text: "Hello, I am a friendly chatbot. I love to talk about movies, books and music. Answer in long form yaml."},
		schema.HumanChatMessage{Text: "What would be a good company name a company that makes colorful socks?"},
	}, llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
		fmt.Print(string(chunk))
		return nil
	}))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(completion)
}

(lcg)调用语言描述的数学计算

在线运行open in new window启动 AI 助手open in new window

func main() {
    os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.New()
	if err != nil {
		panic(err)
	}

	llmMathChain := chains.NewLLMMathChain(llm)
	ctx := context.Background()
	out, err := chains.Run(ctx, llmMathChain, "What is 1024 raised to the 0.43 power?")
	if err !=nil {
        panic(err)
    }
    fmt.Print(out) // 19.69831061351866
}

在主函数中,我们创建了一个新的 LLMMathChain 对象 llmMathChain,这个对象封装了 OpenAI 的 GPT 模型,并允许我们执行数学计算。然后,我们使用 chains.Run() 方法在数学链条上运行给定的命令 "What is 1024 raised to the 0.43 power?",并将结果输出到终端上。

(lcg)根据预设的文档进行 Q&A 交互

在线运行open in new window启动 AI 助手open in new window

const (
	// plz replace below to your openai api key secret
	OPENAI_API_KEY = "sk-your-key"
)

func main() {
    os.Setenv("OPENAI_API_KEY", OPENAI_API_KEY)

	llm, err := openai.New()
	if err != nil {
		panic(err)
	}

	// 使用 LoadStuffQA 工具来创建一个链条,该链条接受输入文档和一个问题
    // 将所有文档填写到 LLM 的提示中,并返回问题的答案
    // 它适用于少量文档
	stuffQAChain := chains.LoadStuffQA(llm)
	docs := []schema.Document{
		{PageContent: "Harrison went to Harvard."},
		{PageContent: "Ankush went to Princeton."},
	}

	answer, err := chains.Call(context.Background(), stuffQAChain, map[string]any{
		"input_documents": docs,
		"question":        "Where did Harrison go to collage?",
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
    // map[text: Harrison went to Harvard.]

	// 另一种选项是使用 Refine Documents 工具进行问题回答
    // 这个工具会逐个迭代输入文档,每次迭代都更新一个中间答案
    // 它使用上一个答案版本和下一个文档作为上下文
    // 这种类型的工具的缺点是它使用多个 LLM 调用,并且无法并行进行
	refineQAChain := chains.LoadRefineQA(llm)
	answer, err = chains.Call(context.Background(), refineQAChain, map[string]any{
		"input_documents": docs,
		"question":        "Where did Ankush go to collage?",
	})
	fmt.Println(answer)
    // map[text: Ankush went to Princeton for college.]
}

在 main() 函数中,我们创建了一个新的 OpenAI 客户端对象 llm,并使用 llm 创建了两个 LangChainGo 链条,stuffQAChain 和 refineQAChain。这些链条实现了不同的文档问题回答工具,可以根据输入文档和问题返回答案。

在这个示例中,我们首先使用 LoadStuffQA() 工具创建了 stuffQAChain 链条,并提供了两个示例文档作为输入。然后,我们向 stuffQAChain 链条输入一个问题 "Where did Harrison go to collage?",并将文档作为上下文。执行链条后,我们可以在控制台上看到问题的答案。

接下来,我们使用 LoadRefineQA() 工具创建了 refineQAChain 链条,这个链条会迭代输入文档,以逐步更新答案。然后,我们将相同的问题 "Where did Ankush go to collage?" 输入到 refineQAChain 链条中,并以文档作为上下文。执行链条后,我们可以在控制台上看到问题的答案。

Last Updated:
Contributors: Bob Wang