![12.png](http://static.itsharecircle.com/231116/3e234a7b1f885155c27e1dcff3801cc7.png)
AI时代下,只要掌握提示词工程技能,每个人都能驾驭AI,实现大幅提升工作效能和质量,拓宽职业发展,获得更多的机会和优势。《[15章]AI人人必修-提示词工程+大模型多场景实战(丰富资料)》为你提供一套实用的、系统的提示词工程基础、原则、应用场景和实践方法。带你从提示词工程的市场需求和职业发展出发,逐步深入并融合大模型提升商业化思维,打通职场、副业的求职、创作、教学、绘图、编程等多场景应用实战,轻松驾驭AI,大幅提升你的效能和质量。
首先,提示词工程是什么
提示词工程就是给大模型应用做出合适的提示,来让大模型有更好的生成效果的一种技术,英文叫Prompt Engineering。
目前提示词工程主要应用在两个领域:一个是类似于大语言模型的应用如ChatGPT,还有一种是文生图领域。
指针有什么用?
指针实际上是提供了一种间接的途径来访问和修改一些值。比如我们希望通过函数的参数的传递来修改变量的原始值。
比如下面这个例子:
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指向同一个地址,所以修改副本指向的值也会影响到函数外c的值
*x = 10
//这里直接修改了实参x的副本地址,相当于让实参x指向了一个新的地址,所以这里改变x的地址并不会影响函数外c的值
x = nil
}
我们可以自定义一个错误类型,只要实现了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)
}
我们先看下面这道笔试题的输出结果,这也是大多数新手都可能会犯的错误:
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)
}
}
然后我们看,为什么需要提示词工程
现在我们遇见的不管是OpenAI ChatGPT、谷歌Bert、百度文心一言还是阿里通义千问,底层都是用了大模型的概念,用了大量的数据进行无监督预训练学习,最后的结果是训练出的AI是个通才。这个通才会根据我们的输入,给一个输出结果,而且一直在预测下一个token出现的概率,也就是根据上文的输入来预测下文会是什么。输入的不同,生成的结果质量可能完全不一样。比如,你告诉大模型应用,让它给你做一个单位门户网站,其效果可能一般。但如果你告诉大模型应用,让它作为产品经理,如何做一个单位门户网站,其质量会好很多。可见提示词工程多么重要。对大模型而言,最关键的就是提问一个好问题。提问一个好问题,你就能得到一个好结果。
package main
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
var s = strings.Repeat("1", 1<<20)
func main() {
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
//字符串字节数组的的地址
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))
//字符串字节数组的的地址
fmt.Println("Assign:", unsafe.Pointer(ptr.Data))
_ = s2
}
func AssignPointer() {
s2 := &s
ptr := (*reflect.StringHeader)(unsafe.Pointer(s2))
//字符串字节数组的的地址
fmt.Println("AssignPointer", unsafe.Pointer(ptr.Data))
_ = s2
}
func StringSlice() {
s2 := s[:20]
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字节数组的的地址
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))
//字符串字节数组的的地址
fmt.Println("Repeat", unsafe.Pointer(ptr.Data))
_ = s2
}
func f1(s string) string {
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s))
//字符串字节数组的的地址
fmt.Println("f1:", unsafe.Pointer(ptr.Data))
return s
}
func f2(s *string) *string {
ptr := (*reflect.StringHeader)(unsafe.Pointer(s))
//字符串字节数组的的地址
fmt.Println("f2:", unsafe.Pointer(ptr.Data))
return s
}
func StringSlice1(s string) string {
s1 := []byte(s[:20])
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字节数组的的地址
fmt.Println("StringSlice1:", unsafe.Pointer(ptr.Data))
s2 := string(s1)
ptr = (*reflect.StringHeader)(unsafe.Pointer(&s2))
//字符串字节数组的的地址
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))
//字符串字节数组的的地址
fmt.Println("StringSlice2:", unsafe.Pointer(ptr.Data))
return s1
}
func StringSlice3(s string) string {
s1 := (" " + s[:20])[1:]
ptr := (*reflect.StringHeader)(unsafe.Pointer(&s1))
//字符串字节数组的的地址
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))
//字符串字节数组的的地址
fmt.Println("StringSliceUseBuilder:", unsafe.Pointer(ptr.Data))
return s1
}
尝试多种提示表述以获得最佳的生成结果
在使用generate时,尝试不同的提示对于解决问题非常有用。即使看起来类似的不同提示表述也可能导致生成结果截然不同。这可能是因为我们的模型已经学习到这些不同的提示表述在不同的上下文和用途中使用,因此会产生不同的结果。下面我们将给出一些我们发现在不同任务中特别有效的示例。
以摘要为例,如果使用“In summary”无法得到好的生成结果,我们可能需要尝试使用“To summarize in plain language”或“The main point to take from this article is that”。
此外,您还可以在playground中使用可能性特征来查看模型是否存在特定的单词、短语或结构理解困难的问题。但是,请记住,序列开始时的标记平均可能性总是很高的。模型可能会将首次引入新概念或名称的可能性降低,但一旦它看到它一次,就可以轻松地在生成中使用它。您还可以使用可能性功能查看是否有任何拼写或标点符号会导致记号化问题。
s pointer: 0xc000180000
Assign: 0xc000180000
AssignPointer 0xc000180000
StringSlice 0xc000180000
Repeat 0xc000180000
StringSlice1: 0xc0000180f0
StringSlice1: 0xc000018108
StringSlice2: 0xc000018120
StringSliceUseBuilder: 0xc000018138
f1: 0xc000180000
f2: 0xc000180000
本文到此结束,感谢大家观看
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传