[15章]AI人人必修-提示詞工程+大模型多場景實戰(zhàn)(豐富資料)
網(wǎng)盤地址1:https://pan.baidu.com/s/1mTGe-dcXi177De39HoIR2g 提取碼:vau2?
網(wǎng)盤地址2:https://pan.baidu.com/s/1OTtLSBrwfbfICfoQ-x41cw 提取碼:i4ov?
AI時代下,只要掌握提示詞工程技能,每個人都能駕馭AI,實現(xiàn)大幅提升工作效能和質(zhì)量,拓寬職業(yè)發(fā)展,獲得更多的機會和優(yōu)勢。《[15章]AI人人必修-提示詞工程+大模型多場景實戰(zhàn)(豐富資料)》為你提供一套實用的、系統(tǒng)的提示詞工程基礎(chǔ)、原則、應(yīng)用場景和實踐方法。帶你從提示詞工程的市場需求和職業(yè)發(fā)展出發(fā),逐步深入并融合大模型提升商業(yè)化思維,打通職場、副業(yè)的求職、創(chuàng)作、教學、繪圖、編程等多場景應(yīng)用實戰(zhàn),輕松駕馭AI,大幅提升你的效能和質(zhì)量。
首先,提示詞工程是什么
提示詞工程就是給大模型應(yīng)用做出合適的提示,來讓大模型有更好的生成效果的一種技術(shù),英文叫Prompt Engineering。
目前提示詞工程主要應(yīng)用在兩個領(lǐng)域:一個是類似于大語言模型的應(yīng)用如ChatGPT,還有一種是文生圖領(lǐng)域。
指針有什么用?
指針實際上是提供了一種間接的途徑來訪問和修改一些值。比如我們希望通過函數(shù)的參數(shù)的傳遞來修改變量的原始值。
比如下面這個例子:
func main() {
? ? c := 1
f1(c)
fmt.Println("f1:c=", c) //c=1
f2(&c)
fmt.Println("f2:c=", c) //c=10
}
func f1(x int) {
x = 10
}
func f2(x *int) {
//實參x的副本跟c指向同一個地址,所以修改副本指向的值也會影響到函數(shù)外c的值
*x = 10
//這里直接修改了實參x的副本地址,相當于讓實參x指向了一個新的地址,所以這里改變x的地址并不會影響函數(shù)外c的值
x = nil
}
我們可以自定義一個錯誤類型,只要實現(xiàn)了Error方法它就是一個error類型:
package main
import "fmt"
type MyErr struct {
code int
Msg? string
}
func (e *MyErr) Error() string {
return fmt.Sprintf("code:%d;msg:%s", e.code, e.Msg)
}
func main() {
var e error
e = &MyErr{
code: 1,
Msg:? "server error",
}
fmt.Println(e)
}
我們先看下面這道筆試題的輸出結(jié)果,這也是大多數(shù)新手都可能會犯的錯誤:
func main() {
? ? slice := []int{0, 1, 2, 3}
? ? ? ? m := make(map[int]*int)
? ? ? ? for key, val := range slice {
? ? ? ? ? ? m[key] = &val
? ? ? ? }
? ??
? ? //0 -> 3?
//1 -> 3?
//2 -> 3
//3 -> 3
? ? ? ? for k, v := range m {
? ? ? ? ? ? fmt.Println(k, "->", *v)
? ? ? ? }
}
然后我們看,為什么需要提示詞工程
現(xiàn)在我們遇見的不管是OpenAI ChatGPT、谷歌Bert、百度文心一言還是阿里通義千問,底層都是用了大模型的概念,用了大量的數(shù)據(jù)進行無監(jiān)督預(yù)訓(xùn)練學習,最后的結(jié)果是訓(xùn)練出的AI是個通才。這個通才會根據(jù)我們的輸入,給一個輸出結(jié)果,而且一直在預(yù)測下一個token出現(xiàn)的概率,也就是根據(jù)上文的輸入來預(yù)測下文會是什么。輸入的不同,生成的結(jié)果質(zhì)量可能完全不一樣。比如,你告訴大模型應(yīng)用,讓它給你做一個單位門戶網(wǎng)站,其效果可能一般。但如果你告訴大模型應(yīng)用,讓它作為產(chǎn)品經(jīng)理,如何做一個單位門戶網(wǎng)站,其質(zhì)量會好很多??梢娞崾驹~工程多么重要。對大模型而言,最關(guān)鍵的就是提問一個好問題。提問一個好問題,你就能得到一個好結(jié)果。
package main
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
var s = strings.Repeat("1", 1<<20)
func main() {
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("s pointer:", unsafe.Pointer(ptr.Data))
Assign()
AssignPointer()
StringSlice()
Repeat()
StringSlice1(s)
StringSlice2(s)
StringSliceUseBuilder(s)
f1(s)
f2(&s)
}
func Assign() {
s2 := s
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("Assign:", unsafe.Pointer(ptr.Data))
_ = s2
}
func AssignPointer() {
s2 := &s
ptr := (*reflect.StringHeader)(unsafe.Pointer(s2))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("AssignPointer", unsafe.Pointer(ptr.Data))
_ = s2
}
func StringSlice() {
s2 := s[:20]
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSlice", unsafe.Pointer(ptr.Data))
_ = s2
}
func Repeat() {
s2 := strings.Repeat(s, 1)
//s2 := strings.Repeat(s, 2)
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("Repeat", unsafe.Pointer(ptr.Data))
_ = s2
}
func f1(s string) string {
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("f1:", unsafe.Pointer(ptr.Data))
return s
}
func f2(s *string) *string {
ptr := (*reflect.StringHeader)(unsafe.Pointer(s))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("f2:", unsafe.Pointer(ptr.Data))
return s
}
func StringSlice1(s string) string {
s1 := []byte(s[:20])
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSlice1:", unsafe.Pointer(ptr.Data))
s2 := string(s1)
ptr = (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSlice1:", unsafe.Pointer(ptr.Data))
return s2
}
func StringSlice2(s string) string {
s1 := string([]byte(s[:20]))
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSlice2:", unsafe.Pointer(ptr.Data))
return s1
}
func StringSlice3(s string) string {
s1 := (" " + s[:20])[1:]
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSlice3:", unsafe.Pointer(ptr.Data))
return s1
}
func StringSliceUseBuilder(s string) string {
var b strings.Builder
b.Grow(20)
b.WriteString(s[:20])
s1 := b.String()
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字節(jié)數(shù)組的的地址
fmt.Println("StringSliceUseBuilder:", unsafe.Pointer(ptr.Data))
return s1
}
嘗試多種提示表述以獲得最佳的生成結(jié)果
在使用generate時,嘗試不同的提示對于解決問題非常有用。即使看起來類似的不同提示表述也可能導(dǎo)致生成結(jié)果截然不同。這可能是因為我們的模型已經(jīng)學習到這些不同的提示表述在不同的上下文和用途中使用,因此會產(chǎn)生不同的結(jié)果。下面我們將給出一些我們發(fā)現(xiàn)在不同任務(wù)中特別有效的示例。
以摘要為例,如果使用“In summary”無法得到好的生成結(jié)果,我們可能需要嘗試使用“To summarize in plain language”或“The main point to take from this article is that”。
此外,您還可以在playground中使用可能性特征來查看模型是否存在特定的單詞、短語或結(jié)構(gòu)理解困難的問題。但是,請記住,序列開始時的標記平均可能性總是很高的。模型可能會將首次引入新概念或名稱的可能性降低,但一旦它看到它一次,就可以輕松地在生成中使用它。您還可以使用可能性功能查看是否有任何拼寫或標點符號會導(dǎo)致記號化問題。
s pointer: 0xc000180000
Assign: 0xc000180000
AssignPointer 0xc000180000
StringSlice 0xc000180000
Repeat 0xc000180000
StringSlice1: 0xc0000180f0
StringSlice1: 0xc000018108
StringSlice2: 0xc000018120
StringSliceUseBuilder: 0xc000018138
f1: 0xc000180000
f2: 0xc000180000
本文到此結(jié)束,感謝大家觀看