agent.withContext
(message: string | {
content: string;
systemMessage: string;
}, func: () => any): Promise<any>
withContext
可以傳入一段訊息、函式,當傳入 withContext
的函式結束時,agent
的 content
以及 systemMessage
就會回復到呼叫 withContext
。
這在想要避免不同的 prompt 互相影響的時候,可以發揮作用。
agent.content = "No message"
await agent.withContext(`A: I want to buy something.`, async () => {
console.log(agent.content) // "A: I want to buy something."
await agent.yesNo("Does user want to check product ?")
// ...do something with current context
})
console.log(agent.content) // "No message"
你也可以同時傳入 systemMessage
。
agent.systemMessage = ""
await agent.withContext({
content: `A: I want to buy something.`,
systemMessage: "You are a customer service"
}, async () => {
console.log(agent.systemMessage) // You are a customer service
// ...do something with current context
})
在 withContext
中,也可以使用 withContext
。
agent.content = "No message"
await agent.withContext(`A: I want to buy something.`, async () => {
console.log(agent.content) // "A: I want to buy something."
console.log(agent.systemMessage) // ""
await agent.withContext({
content: `A: I want to buy something.`,
systemMessage: "You are a customer service, help user find the products he/she want."
}, async () => {
console.log(agent.content) // "A: I want to buy something."
console.log(agent.systemMessage) // "You are a customer service, help user find the products he/she want."
})
console.log(agent.content) // "A: I want to buy something."
console.log(agent.systemMessage) // ""
})
console.log(agent.content) // "No message"
agent.choice
Agent.choice(question: string, choices: AgentChoice[]): Promise<any>
type AgentChoice =
| string
| [string, () => any]
| [string, any]
| ((...args: any) => any)
choice 可以提出一個問題,並提供可回答的選項,讓 model 只從中挑選回答。
agent.withContext("User: I want to find a job", async ()=> {
const purpose = await agent.choice("Which is user's purpose ?", [
"Looking for a job",
"Buying a car",
"Renting a house"
])
console.log(purpose) // "Looking for a job"
})
你也可以直接傳入 handler function,當那個選項被回答時可以執行
const purpose = await agent.choice("Which is user's purpose ?", [
["Looking for a job", () => { console.log(/* .... */) }],
"Buying a car",
"Renting a house"
])
console.log(purpose) // "Looking for a job"
handler function 的回傳內容會直接成為 choice 的回傳內容。因此,實際上可以把前面的例子看成:
const purpose = await agent.choice("Which is user's purpose ?", [
["Looking for a job", () => "Looking for a job"],
["Buying a car", () => "Buying a car"]
["Renting a house", () => "Renting a house"]
])
console.log(purpose) // "Looking for a job"
handler behaviour
choice 根據 handler 的類型不同會有不同的回傳值
[
["Looking for a job", () => "Looking for a job"], // return "Looking for a job"
["Buying a car", true] // return true
["Renting a house"] // return "Renting a house"
"Renting a house" // return "Renting a house"
]
handle "I don't know" or others...
當 model 回答選項以外的答案時(e.g I don't know),在預設的情況下,會回傳 null
agent.withContext("User: I want to see Naruto !", async ()=> {
const purpose = await agent.choice("Which is user's purpose ?", [
"Looking for a job",
"Buying a car",
"Renting a house"
])
console.log(purpose) // null
})
但是你也可以傳入 handler 處理這種情況:
agent.withContext("User: I want to see Naruto !", async ()=> {
const purpose = await agent.choice("Which is user's purpose ?", [
"Looking for a job",
"Buying a car",
"Renting a house",
() => "I don't know"
])
console.log(purpose) // "I don't know"
})
agent.yesNo
(method) Agent.yesNo(question: string, choices?: AgentChoice[]): Promise<any>
這是一種 choice
的變形,他只會回答 yes/no,你需要提出一個是或否的問題。 當 model 回傳 yes 時,會回傳 true
,反之則是 false
vai.withContext("I am looking for a job", async () => {
const result = await vai.yesNo(
"Does user want to looking for new job opportunities?",
)
console.log(result) // true
})
你可以透過提供選項改變預設的行為:
vai.withContext("I am looking for a job", async () => {
const result = await vai.yesNo(
"Does user want to looking for new job opportunities?",
["yes", () => "Find a job"],
["no", () => "Do nothing"],
)
console.log(result) // "Find a job"
})
與 choice
相同,你也可以提供 "I don't know" 的 handler
vai.withContext("XXXX", async () => {
const result = await vai.yesNo(
"Does user want to looking for new job opportunities?",
[
["yes", () => "Find a job"],
["no", () => "Do nothing"],
() => "handle by I don't know",
]
)
console.log(result) // "handle by I don't know"
})
agent.does
(method) Agent.does(question: string, choices?: AgentChoice[]): Promise<any>
does
是一種 yesNo
的糖,只是會在傳入的 question 加上 Does
prefix。
// These 2 are the same
agent.yesNo("Does user want to looking for new job opportunities?")
agent.does("user want to looking for new job opportunities?")
agent.is
(method) Agent.is(question: string, choices?: AgentChoice[]): Promise<any>
is
是一種 yesNo
的糖,只是會在傳入的 question 加上 Is
prefix。
// These 2 are the same
agent.yesNo("Is user a member ?")
agent.is("user a memeber")
agent.whichOneIs
(method) Agent.whichOneIs(purpose: string, choices: AgentChoice[]): Promise<any>
whichOneIs
是一種 choice
的糖,只是會在傳入的 question 加上 Which one is
prefix。
// These 2 are the same
agent.choice("Which one is user's purpose ?")
agent.whichOneIs("user's purpose ?")
agent.choices
agent.whichOnesAre
agent.categorize
(method) Agent.categorize(question: string, categories: ([string, AgentChoice[]] | (() => any))[]): Promise<any>
categorize
可以減少呼叫 model 的次數,並且可以處理主題更多樣的情況。
categorize
在 choice
之上再加入一層分類,實際上在背後使用這樣的 prompt
Question: how to use job filter?
- job
- searching a job
- asking question about job filter
- has trouble with finding a job
- resume
- asking a problem about resume editor
- asking a problem about tip of writing a resume
model 會先將輸入分類為 job 或是 resume,然後在從中選擇一個選項。
將以上的結構換成 categorize 則可以表示為
const result = await agent.categorize(
"how to use job filter?",
{
"job": [
"searching a job",
"asking question about job filter",
"has trouble with finding a job"
],
"resume": [
"asking a problem about resume editor",
"asking a problem about tip of writing a resume",
]
}
)
console.log(result) // ["job", "asking question about job filter"]
categorize 的子分類其實跟 choice
的參數一樣,可以傳入 AgentChoice
,因此也可以傳入 handler。
const result = await agent.categorize(
"how to use job filter?",
{
"job": [
["searching a job", async () => { /** handle the situation */ }],
["asking question about job filter", () => true ],
"has trouble with finding a job"
() => "handle I dont know"
],
// ...
}
)
console.log(result) // value returned by handler
agent.chooseAndAnswer
(method) Agent.chooseAndAnswer(questionGroups: Record<string, {
questions: string[];
handler?: ((args: any[]) => any) | undefined;
}> & {
fallback?: (() => any) | undefined;
}): Promise<any>
chooseAndAnswer
會要求 model 先選擇一組分類,然後回答分類底下的所有問題。
agent.withContext("I am looking for a job, my name is John", async () => {
const result = await agent.chooseAndAnswer({
"Looking for a job": {
questions: ["user name", "user email", "user phone"],
// handler is optional, chooseAndAnswer will directly return [question, answer1, answer2, ...] when handler is not provided
handler: async ([question, answer1, answer2, answer3]) => {
console.log("r", [question, answer1, answer2, answer3])
// ['Looking for a job', 'John', '', '']
return [question, answer1, answer2, answer3]
},
},
// ....
})
console.log(result) // ['Looking for a job', 'John', '', '']
})
同時,也可以提供 fallback handler 處理沒有任何合適的分類時的狀況:
agent.withContext("I am looking for a job, my name is John", async () => {
const result = await agent.chooseAndAnswer({
// omit...
fallback: () => {
// handle I don't know...
}
// ....
})
})