[NB: repo นี้เป็นงานติดตามงานการอนุมานเดียวกันที่ประเมิน chatgpt]
โมเดลภาษาขนาดใหญ่ (LLMS) เช่น GPT-4, CHATGPT และ Claude ได้แสดงให้เห็นถึงความสามารถในการเขียนโปรแกรมที่น่าประทับใจและมีความสามารถในการแก้ปัญหาในภาษาที่หลากหลายและอนุกรมวิธานของพวกเขา แม้จะประสบความสำเร็จเหล่านี้ แต่ความสงสัยบางอย่างยังคงมีอยู่ในระดับที่แบบจำลองเหล่านี้แสดงให้เห็นถึงความซาบซึ้งในกฎทางวากยสัมพันธ์และกฎการปฏิบัติงานที่อยู่ภายใต้ภาษาเหล่านี้ ( กับ การท่องจำรูปแบบจากข้อมูลการฝึกอบรม)
ในพื้นที่เก็บข้อมูลที่มีวิศวกรรมพร้อมใช้งานนี้ความสามารถในการเขียนโปรแกรมของ GPT-4 ได้รับการสำรวจโดยใช้ภาษาเฉพาะโดเมน (DSL) โดยพลการ DSLs เป็นตัวแทนของสารตั้งต้นที่น่าสนใจสำหรับการศึกษาความสามารถในการอนุมานของ LLM เพราะพวกเขาเป็นนวนิยายและมีโอกาสน้อยที่จะได้พบและจดจำอย่างกว้างขวางในระหว่างการฝึกอบรม 1 ด้วยเหตุนี้พวกเขาจึงเปิดใช้งานการทดสอบโดยตรงมากขึ้นในขอบเขตที่ LLM สามารถอนุมานกฎของภาษาการเขียนโปรแกรมใหม่ใน ลักษณะไม่กี่นัด
ที่นี่ภาษาเฉพาะของโดเมน SIL (ภาษาการรวมสมมาตร) ได้รับการคัดเลือกด้วยเหตุผลสองประการ ประการแรกมันไม่น่าเป็นไปได้อย่างยิ่งที่ GPT-4 ได้สัมผัสกับรหัส SIL จำนวนมากในระหว่างการฝึกอบรมเนื่องจากเป็น DSL ใน บริษัท ที่พัฒนาโดยกองทุนป้องกันความเสี่ยงที่มีเทคโนโลยีหนักที่เรียกว่า Symmetry Investments ประการที่สองเป็นภาษาการเขียนโปรแกรมมีคุณสมบัติที่น่าสนใจสำหรับแบบจำลองในการทำซ้ำ (เช่นเป็นภาษาที่ใช้งานได้ซึ่งเน้นการแสดงออก แต่ขาดการ let เช่นเดียวกับใน Haskell หรือ Ocaml)

หลังจากมีการแจ้งรหัสตัวอย่างแล้ว GPT-4 พยายามเขียนโค้ดใน DSL ที่ใช้งานได้ใหม่ที่เรียกว่า 'SIL'
ด้านล่างนี้เป็นชุดของพรอมต์บางอย่างประกอบด้วยตัวอย่างสั้น ๆ ของรหัส SIL ซึ่งเน้นการทำงานของมัน หลังจากแจ้งให้ GPT-4 พร้อมงานและให้ตัวอย่างรหัส SIL (ดูด้านล่างไลบรารีเต็มของพรอมต์และตัวอย่างรหัสที่สร้างขึ้นสามารถพบได้ใน repo นี้) ฉันขอให้ใช้งานการเขียนโปรแกรมหลักจำนวนหนึ่งใน SIL
ในส่วนด้านล่างฉันแสดงตัวอย่างสคริปต์รหัส SIL ที่มีการแจ้งเตือนแบบจำลอง (ชุดตัวอย่างเต็มรูปแบบสามารถพบได้ที่นี่) และความพยายามที่จะใช้ปัญหาต่าง ๆ ใน SIL
พรอมต์แรกคือสคริปต์เพื่อจัดการฟังก์ชั่นเซิร์ฟเวอร์เมลบางส่วน ดังนั้นมันจึงแตกต่างอย่างมากจากประเภทของปัญหาฉันจะแจ้งให้ Chatgpt แก้ปัญหา แต่มันแสดงให้เห็นถึงบางส่วนของไวยากรณ์โครงสร้างข้อมูลและแง่มุมการทำงานของ SIL (เช่น |> )
// example of using IMAP IDLE to run rules on new mail
import imap
moveMessages(session,ids,target) => if (ids.length > 0 ) then imap.moveUIDs(session,ids,target) else false
login = imap.ImapLogin(environment( " IMAP_USER " ),environment( " IMAP_PASS " ))
server = imap.ImapServer( " imap.fastmail.com " , " 993 " )
session = imap.Session(server,login, true ,imap.Options(debugMode: true )) | > imap.openConnection | > imap.login
rules=[ [
[ " INBOX/0receipts " ,
[
" FROM [email protected] " ,
" FROM interactivebrokers.com " ,
]],
[ " Junk " ,
[
" FROM Tapatalk " ,
]],
[ " INBOX/newsletters " ,
[
" FROM [email protected] " ,
" HEADER X-mailer mailgun " ,
" HEADER X-mailer WPMailSMTP/Mailer/mailgun 2.4.0 " ,
" HEADER X-mailer nlserver " ,
" FROM hbr.org " ,
" FROM elliottwave.com " ,
" OR FROM cio.com FROM cio.co.uk " ,
" FROM substack.com " ,
" FROM eaglealpha.com " ,
" FROM haaretz.com " ,
" FROM gavekal.com " ,
" FROM go.weka.io " ,
" FROM marketing.weka.io " ,
` HEADER list-unsubscribe "" ` ,
` HEADER list-Id "" ` ,
` HEADER list-Post "" ` ,
` HEADER list-owner"" ` ,
` HEADER Precedence bulk ` ,
` HEADER Precedence list ` ,
` HEADER list-bounces "" ` ,
` HEADER list-help "" ` ,
` HEADER List-Unsubscribe "" ` ,
" FROM no-reply " ,
]],
[ " INBOX/notifications " ,
[
` KEYWORD "$IsNotification" ` ,
" FROM [email protected] " ,
" FROM [email protected] " ,
" FROM skillcast.com " ,
" FROM reedmac.co.uk " ,
" FROM [email protected] " ,
" FROM [email protected] " ,
" FROM [email protected] " ,
]],
]
runRules(Session,Rules) => Rules
| > map(target => [target[ 0 ],(target[ 1 ] | > map(term => imap.search(Session,term).ids))])
| > mapa(set => moveMessages(Session,set[ 1 ] | > join,set[ 0 ]))
runRulesBox(Session,Rules,Mailbox) => {
imap.select(Session,Mailbox)
in runRules (Session,Rules)
}
inboxes=[ " INBOX " ]
result = inboxes | > mapa(inbox => runRulesBox(session,rules,imap.Mailbox(session,inbox)))
print(result)
import parallel;
threadFunction(x) => {
imap.idle(session)
in inboxes | > mapa(inbox => runRulesBox(session,rules,imap.Mailbox(session,inbox)))
}
parallel.runEvents((x) => false ,[threadFunction]) ตัวอย่างรหัสที่สองพร้อมที่จะเน้นคุณสมบัติบางอย่างของ DSL นี้สำหรับรุ่นและแนะนำฟังก์ชั่นไลบรารีมาตรฐานใหม่เช่น iota และ fold
import imap
import imap_config
import string
// Get the configuration from the environment and command line.
config = imap_config.getConfig(commandLineArguments)
// -------------------------------------------------------------------------------------------------
// Some helper functions.
//
// Firstly, a function to join an array of strings.
joinFields(flds, sep) => {
len(flds) > 0 | > enforce( " Cannot join an empty array. " )
in fold (flds[ 1 :$], (str, fld) => str ~ sep ~ fld, flds[ 0 ])
}
// Secondly, a field formatter which strips the field prefix and pads to a fixed width.
// E.g., ("From: [email protected]" |> fmtField(20)) == "[email protected] "
fmtField(field, width) => {
pad(str) => iota(width - len(str)) | > fold((a, i) => a ~ " " , str)
in field
| > string .split( " : " )[ 1 :$]
| > joinFields( " : " )
| > pad
}
// And thirdly, a function which concatenates the headers into a formatted string.
fmtHeaders(outStr, headers) => {
outStr ~ " " ~ joinFields(headers, " | " ) ~ " n "
}
// -------------------------------------------------------------------------------------------------
// Connect to the inbox.
creds = imap.ImapLogin(config.user, config.pass)
server = imap.ImapServer(config.host, config.port)
session =
imap.Session(server, creds)
| > imap.openConnection()
| > imap.login()
inbox = imap.Mailbox(session, " INBOX " )
// Get the number of messages in the inbox.
msgCount = imap.status(session, inbox).messages
// Select the default inbox.
inbox | > imap.examine(session, _)
// Get the headers (date, from and subject) for each message, from oldest to newest, format and
// print them.
headers =
iota(msgCount)
| > map(id => " # " ~ toString(id + 1 ))
| > map(id =>
imap.fetchFields(session, id, " date from subject " ).lines
| > map(hdr => fmtField(hdr, 40 )))
| > fold(fmtHeaders, " INBOX: n " )
print(headers)ตัวอย่างโค้ดที่สามแสดงให้เห็นถึงคุณสมบัติที่ผิดปกติของ DSL นี้โดยมีจุดประสงค์ที่ ChatGPT จะใช้สิ่งเหล่านี้ในการใช้งานของตัวเองต่อไป
// This script will create a report based on a specific example set of automated 'support' emails.
// E.g.,
//
// "support.mbox": 17 messages 17 new
// N 1 [email protected] Mon May 11 22:26 28/1369 "Alert: new issue 123"
// N 2 [email protected] Tue May 12 12:20 22/933 "Notification: service change"
// N 3 [email protected] Tue May 12 12:36 26/1341 "Alert: new issue 124"
// N 4 [email protected] Wed May 13 02:13 21/921 "Resolution: issue 124"
// N 5 [email protected] Wed May 13 18:53 26/1332 "Email not from robot."
// N 6 [email protected] Thu May 14 03:13 27/1339 "Alert: new issue 125"
// N 7 [email protected] Thu May 14 08:46 26/1270 "Resolution: issue 123"
// N 8 [email protected] Thu May 14 17:06 25/1249 "Alert: new issue 126"
// N 9 [email protected] Fri May 15 09:46 24/1185 "Resolution: issue 126"
// N 10 [email protected] Fri May 15 12:33 23/1052 "Alert: new issue 127"
// N 11 [email protected] Fri May 15 15:20 27/1331 "Notification: service change"
// N 12 [email protected] Fri May 15 18:06 23/953 "Resolution: issue 127"
// N 13 [email protected] Mon May 18 12:46 27/1218 "Alert: new issue 128"
// N 14 [email protected] Mon May 18 15:33 32/1628 "Alert: new issue 129"
// N 15 [email protected] Tue May 19 05:26 25/1176 "Resolution: issue 128"
// N 16 [email protected] Tue May 19 08:13 26/1312 "Notification: service change"
// N 17 [email protected] Tue May 19 11:00 28/1275 "Alert: new issue 130"
//
//
// Each of these automated emails are from `robot` _except_ for message 5. Messages 2, 8 and 16 are
// from `robot` but are unrelated to issues.
//
// This script will search for emails and match new issue numbers with resolutions to report the
// number of outstanding alerts.
import imap
import * from imap.query
import imap_config
import dates
import string
// Get the configuration from the environment and command line.
config = imap_config.getConfig(commandLineArguments)
// Connect to the inbox.
creds = imap.ImapLogin(config.user, config.pass)
server = imap.ImapServer(config.host, config.port)
session =
imap.Session(server, creds)
| > imap.openConnection()
| > imap.login()
inbox = imap.Mailbox(session, " support " )
// Select the default inbox.
inbox | > imap.examine(session, _)
// These criteria are common for both our searches.
commonCrit = imap.Query()
| > and(from( ` [email protected] ` ))
| > and(sentSince(dates. Date ( 2020 , 5 , 13 )))
// Get each of the alerts and resolutions from the past week (13-19 May 2020).
alertMsgIds =
imap.search(session, imap.Query(subject( " Alert: new issue " )) | > and(commonCrit)).ids
resolutionMsgIds =
imap.search(session, imap.Query(subject( " Resolution: issue " )) | > and(commonCrit)).ids
// A function to get the alert ID from a message subject.
getAlertId(msgId) => {
imap.fetchFields(session, toString (msgId), " subject " ).lines[ 0 ]
| > string .split()[$ - 1 ]
}
// A function to remove an entry from a table whether it's there or not.
removeIfExists(tbl, key) => {
if find( keys (tbl), key) == [] then
tbl
else
removeEntry(tbl, key)
}
// Now find those alerts which have no resolution. Firstly the subject for each alert, get the
// issue number end and store it in a table.
allAlertTable = alertMsgIds | > fold((tbl, msgId) => addEntry(tbl, getAlertId(msgId), msgId), {})
// Go through the resolutions and remove their corresponding alerts from the table.
unresolvedAlertTable =
resolutionMsgIds | > fold((tbl, msgId) => removeIfExists(tbl, getAlertId(msgId)), allAlertTable)
// Create a report with the date of the unresolved alerts.
report =
keys (unresolvedAlertTable)
| > map(alertId => {
msgId = unresolvedAlertTable[alertId] | > toString
in [ alertId
, imap.fetchFields(session, msgId, " date " ).lines[ 0 ]
, imap.fetchText(session, msgId).lines[ 0 ]
]
})
| > fold((outStr, tuple) => {
outStr ~ " Issue: " ~ tuple[ 0 ] ~ " n " ~ tuple[ 1 ] ~ " n Summary: " ~ tuple[ 2 ] ~ " n "
}, " n UNRESOLVED ISSUES FROM THE PAST 10 DAYS: nn " )
// Close the session.
imap.closeConnection(session)
// Print the report last.
print(report) ในการออกกำลังกายครั้งแรกฉันขอให้โมเดลใช้ฐานข้อมูลเชิงสัมพันธ์ที่ง่ายมากใน SIL ด้วยฟังก์ชันพื้นฐาน (โปรดทราบว่า // หมายถึงการแสดงความคิดเห็นใน SIL)
import imap
import imap_config
import string
// Get the configuration from the environment and command line.
config = imap_config.getConfig(commandLineArguments)
// Connect to the server.
creds = imap.ImapLogin(config.user, config.pass)
server = imap.ImapServer(config.host, config.port)
session =
imap.Session(server, creds)
| > imap.openConnection()
| > imap.login()
// -------------------------------------------------------------------------------------------------
// Here's an attempt to create something resembling a simple relational database.
// Define two tables, 'Employees' and 'Departments'.
Employees = { " 1 " : [ " Alice " , " Engineering " ], " 2 " : [ " Bob " , " Marketing " ], " 3 " : [ " Charlie " , " Engineering " ] }
Departments = { " Engineering " : [ " Alice " , " Charlie " ], " Marketing " : [ " Bob " ] }
// Function to emulate SQL SELECT operation.
select = (table, id) => {
table[id] | > enforce( " Id does not exist in table. " )
}
// Function to emulate SQL INSERT operation.
insert = (table, id, values ) => {
addEntry(table, id, values )
}
// Function to emulate SQL DELETE operation.
delete = (table, id) => {
removeEntry(table, id)
}
// Function to emulate SQL JOIN operation.
join = (table1, table2, commonField) => {
// This is a very basic JOIN operation and does not account for multiple matches, etc.
joinedTable = {}
for key in keys (table1) {
value = table1[key][commonField]
if find( keys (table2), value) != [] {
joinedTable = addEntry(joinedTable, key, [table1[key], table2[value]])
}
}
joinedTable
}
// Close the session.
imap.closeConnection(session)
// Perform operations.
newEmployee = [ " David " , " Marketing " ]
Employees = insert(Employees, " 4 " , newEmployee)
Departments = insert(Departments, newEmployee[ 1 ], [ " David " ])
print(select(Employees, " 1 " ))
print(join(Employees, Departments, 1 ))การใช้อัลกอริทึมการเรียงลำดับเป็นคำถามสัมภาษณ์วิศวกรรมซอฟต์แวร์แบบดั้งเดิม ที่นี่ฉันขอให้ GPT-4 ใช้ Bubblesort (แนวคิดการเรียงลำดับขั้นพื้นฐานที่สุดในแนวคิด) ใน SIL ด้านล่างคือการตอบสนอง:
// Helper function to bubble up the largest value in one pass
bubble(list) => {
if length(list) <= 1 then
list
else
if list[ 0 ] > list[ 1 ] then
[list[ 1 ]] ~ bubble([list[ 0 ]] ~ list[ 2 to $])
else
[list[ 0 ]] ~ bubble(list[ 1 to $])
}
// Main BubbleSort function
bubbleSort(list) => {
bubbled = bubble(list)
if bubbled == list then
list
else
bubbleSort(bubbled)
} ต่อไปฉันแจ้งให้แบบจำลองเขียนสคริปต์สำหรับการคำนวณค่ามัธยฐานของรายการ (การตอบกลับที่สร้างขึ้นด้านล่าง) sortList นั้นสอดคล้องกับกระบวนทัศน์การเขียนโปรแกรมที่ใช้งานได้ แต่ที่นี่ GPT-4 ถือว่าการมีอยู่ของผู้ดำเนินการที่ได้รับมอบหมาย :=
// Helper function to sort an array of integers.
sortList(list) => list | > len | > iota | > map(i => list | > min | > snd) | > each((i, minVal) => list := removeIndex(list, minVal))
// Function to compute the median of a set of integers.
computeMedian(list) => {
// Sort the list in ascending order.
sortedList = sortList(list)
// Get the length of the list.
length = len(sortedList)
// Check if the length is even.
isEven = length % 2 == 0
// If the length is even, the median is the average of the two middle numbers.
// Otherwise, the median is just the middle number.
median =
if isEven then
(sortedList[length / 2 - 1 ] + sortedList[length / 2 ]) / 2
else
sortedList[length / 2 ]
// Return the median.
median
} GPT -4 ได้รับแจ้งต่อไปให้ใช้อัลกอริทึมเพื่อนบ้าน K -nearest ใน Sil นอกเหนือจากภาพหลอน/สมมติว่าการมีอยู่ของโมดูลที่ |> ว่า math (ซึ่งเป็นข้อสันนิษฐานที่สมเหตุสมผลสำหรับ fold ของแบบฝึกหัดนี้) ดูเหมือนว่า map เป็นวิธีแก้ปัญหาที่ยอมรับได้
import math
distance(p1, p2) => {
math.sqrt(
math.pow(p1[ 0 ] - p2[ 0 ], 2 )
+ math.pow(p1[ 1 ] - p2[ 1 ], 2 )
)
}
majorityVote(labels) => {
labelCounts = labels | > fold((counts, label) => addEntry(counts, label, get (counts, label, 0 ) + 1 ), {})
labelCounts | > maxBy((_, count) => count)
}
knn(data, newPoint, k) => {
distances = data | > map((point, label) => (distance(point, newPoint), label))
sorted = distances | > sort((a, b) => a[ 0 ] < b[ 0 ])
nearest = sorted | > take(k)
labels = nearest | > map((_, label) => label)
majorityVote(labels)
}
หนึ่งในคุณสมบัติที่น่าสนใจของภาษาที่ใช้งานได้คือพวกเขาสามารถแสดงออกได้สูง ที่นี่ฉันได้รับแจ้งให้ GPT-4 ใช้ map ตัวดำเนินการทำงานพื้นฐาน filter และ reduce (หรือ fold ในบริบทของภาษาที่ใช้งานได้)
// map
// The map-like function would take a function and a list, and apply the function to each element in the list.
mapList(func, list) => {
len(list) > 0 | > enforce( " Cannot map over an empty list. " )
in iota (len(list)) | > fold((result, i) => addEntry(result, func(list[i])), [])
}
// filter
// The filter-like function would take a predicate and a list, and return a list of elements for which the predicate returns true.
filterList(pred, list) => {
len(list) > 0 | > enforce( " Cannot filter an empty list. " )
in iota (len(list)) | > fold((result, i) => if pred(list[i]) then addEntry(result, list[i]) else result, [])
}
// reduce
// The reduce-like function would take a binary function, a list, and an initial accumulator, and apply the function to each element in the list with the accumulator.
reduceList(func, list, acc) => {
len(list) > 0 | > enforce( " Cannot reduce an empty list. " )
in iota (len(list)) | > fold((result, i) => func(result, list[i]), acc)
}
Project Euler เป็นชุดของปัญหาทางคณิตศาสตร์และการเขียนโปรแกรม (ซึ่งฉันคิดว่าทำพรอมต์ที่น่าสนใจสำหรับ LLMs) ที่นี่ฉันแจ้งให้ GPT-4 แก้ปัญหาออยเลอร์สองโครงการแรกโดยใช้ SIL
// Project Euler problem #1:
// Here, my prompt was to solve the (easy) first problem of the Project Euler series (https://projecteuler.net/problem=1)
// Define a range from 1 to 999.
range = iota( 999 ) | > map(x => x + 1 )
// Define a function to check if a number is a multiple of 3 or 5.
isMultipleOf3Or5 = (num) => num % 3 == 0 || num % 5 == 0
// Filter the range to get only multiples of 3 or 5.
multiples = range | > filter(isMultipleOf3Or5)
// Sum the multiples.
sum = multiples | > fold((a, b) => a + b, 0 )
// Print the sum.
print(sum)
// Project Euler problem #2:
// This prompt is to solve the second Project Euler problem (https://projecteuler.net/problem=2)
// Define a function to generate the next term in the Fibonacci sequence.
nextFibonacciTerm = (tuple) => [tuple[ 1 ], tuple[ 0 ] + tuple[ 1 ]]
// Start with the first two terms.
initialTerms = [ 1 , 2 ]
// Define a function to generate Fibonacci sequence up to a limit.
generateFibonacci = (limit) => {
fibonacciSequence = unfold(nextFibonacciTerm, initialTerms, (tuple) => tuple[ 1 ] <= limit)
fibonacciSequence
}
// Define a function to check if a number is even.
isEven = (num) => num % 2 == 0
// Generate the Fibonacci sequence up to four million.
fibonacciSequence = generateFibonacci( 4000000 )
// Extract the second term from each tuple in the sequence, which is the actual Fibonacci number.
fibonacciNumbers = fibonacciSequence | > map(tuple => tuple[ 1 ])
// Filter the sequence to get only even numbers.
evenFibonacciNumbers = fibonacciNumbers | > filter(isEven)
// Sum the even numbers.
sum = evenFibonacciNumbers | > fold((a, b) => a + b, 0 )
// Print the sum.
print(sum)
การสำรวจความสามารถของ LLMs ในการอนุมานและเข้าใจคุณสมบัติของภาษาการเขียนโปรแกรมใหม่ในลักษณะ ไม่กี่นัด ยังคงเป็นคำถามที่เปิดกว้างและน่าสนใจ ที่นี่ความสามารถเหล่านี้ได้รับการสำรวจในบริบทของการกระตุ้น GPT-4 เพื่อแก้ปัญหาที่แจ้งเตือนในภาษาเฉพาะโดเมน (DSL) ที่เรียกว่า SIL DSLs เป็นกรณีทดสอบที่มีประโยชน์สำหรับการสำรวจ การอนุมาน เทียบกับ การจดจำ ใน LLM เนื่องจากพวกเขามักจะมีคุณสมบัติที่โดดเด่นและมีโอกาสน้อยที่จะพบอย่างกว้างขวางในระหว่างการฝึกอบรม (ถ้าเลย)
บางทีการค้นพบที่น่าสนใจที่สุดของแบบฝึกหัดนี้คือความสามารถในการอนุมานไม่กี่ครั้งของ GPT-4 นั้นดีกว่าของ CHATGPT อย่างมีนัยสำคัญ เมื่อประเมินด้วยพรอมต์และงานเดียวกัน (ดูแบบฝึกหัดแบบอะนาล็อกกับ CHATGPT ที่นี่)
มีหลักฐานว่าการจดจำ LLM ได้รับการส่งเสริมโดยความถี่ของการนำเสนอตัวอย่างการฝึกอบรมและจำนวนโทเค็นที่เกี่ยวข้องที่ใช้ในการกระตุ้นแบบจำลอง