跳至内容

代理

GenAIScript将智能体定义为一种工具,它通过运行内联提示来完成任务。该智能体的LLM通常还会配备额外的工具和记忆功能。

script({
// use all agents
tools: "agent",
})
// agent git to get the commits
// agent interpreter to run python code
$`Do a statistical analysis of the last commits`

GenAIScript 实现任何代理工作流或决策。 它完全依赖于LLM内置的工具支持。

智能体 = 大语言模型 + 工具集

让我们看一下查询Git仓库的agent_git示例。这个代理被注册为一个tool,可以在LLM提示中使用。 当LLM需要诸如"总结当前分支中的变更"这样的信息时,它会调用agent_git工具并传入查询get changes in the current branch

agent_git工具本身可以访问各种git专用工具,如git branchgit diff,它可以使用这些工具来解决问题。 它需要解析当前和默认分支,计算差异并将其返回给主LLM。

代理与工具

“代理”是一种配备其他工具、用于查询大型语言模型(LLM)以完成任务的高级工具。它是一种更高层次的抽象概念,可用于将多个工具组合在一起。 在某些场景下,您可能会决定移除这种抽象层级,通过“直接提供”工具给调用的LLM来绕过代理机制。 在这个简单示例中,您也可以选择扁平化这个结构,将git工具直接开放给主LLM使用,从而跳过代理环节。

然而,当您开始拥有过多函数或需要保持聊天对话长度简短时,代理抽象就变得很有用,因为每次代理LLM调用都会被"压缩"为代理响应。

多代理

让我们来看一个更复杂的例子,其中涉及多个代理参与对话。在这个案例中,我们想要调查为什么GitHub操作失败了。 它涉及agent_gitagent_github两个代理。agent_github可以查询工作流、运行、作业、日志,而agent_git可以查询git仓库。

内存

所有代理都配备了记忆功能,使它们能够在所有对话中横向共享信息。

内存是一个存储所有agent / query / answer交互记录的日志。在为agent生成提示时,首先会提示内存(使用一个小型LLM)以提取相关信息,然后将该信息传递给agent查询。

ask agent about "query":
wisdom = find info in memory about "query"
agent answer "query" using your tools and information in "wisdom"

所有代理都会对对话记忆做出贡献,除非明确使用disableMemory禁用该功能。

defAgent(..., { disableMemory: true })

defAgent

defAgent 函数用于定义一个可由LLM调用的代理。它接收一个JSON模式来定义输入,并期望输出字符串。LLM会自主决定是否调用此代理。

defAgent(
"git", // agent id becomes 'agent_git'
"Handles any git operation", // description
"You are a helpful expert in using git.",
{
tools: ["git"],
}
)
  • 代理ID将成为工具ID agent_
  • 代理的描述将自动补充有关可用工具的信息

同一代理的多个实例

某些代理,如agent_git,可以通过不同的配置进行实例化,例如在不同的代码库上工作。

多智能体.genai.mts
script({
system: [
"system.agent_git",
{
id: "system.agent_git",
parameters: { repo: "microsoft/jacdac", variant: "jacdac" },
},
],
})
$`Generate a table with the last commits of the jacdac and current git repository?`

内置代理

示例 agent_github

让我们通过构建一个GitHub代理来说明这一点。该代理是一个工具,接收查询并使用与GitHub相关的工具执行LLM提示。

代理的定义如下所示:

defAgent(
"github", // id
"query GitHub to accomplish tasks", // description
// callback to inject content in the LLM agent prompt
(ctx) =>
ctx.$`You are a helpful LLM agent that can query GitHub to accomplish tasks.`,
{
// list tools that the agent can use
tools: ["github_actions"],
}
)

在内部,它被扩展为以下内容:

defTool(
// agent_ is always prefixed to the agent id
"agent_github",
// the description is augmented with the tool descriptions
`Agent that can query GitHub to accomplish tasks
Capabilities:
- list github workflows
- list github workflows runs
...`,
// all agents have a single "query" parameter
{
query: {
type: "string",
description: "Query to answer",
},
required: ["query"]
},
async(args) => {
const { query } = args
...
})

在回调函数内部,我们使用runPrompt来运行一个LLM查询。

  • 提示(prompt)接收查询(query)参数并指示LLM如何处理它。
  • 注意在嵌套提示中使用ctx.
const res = await runPrompt(
(ctx) => {
// callback to inject content in the LLM agent prompt
ctx.$`You are a helpful LLM agent that can query GitHub to accomplish tasks.`
ctx.def("QUERY", query)
_.$`Analyze and answer QUERY.
- Assume that your answer will be analyzed by an LLM, not a human.
- If you cannot answer the query, return an empty string.
`
}, , {
system: [...],
// list of tools that the agent can use
tools: ["github_actions", ...]
}
)
return res

选择工具和系统提示

我们使用system参数来配置暴露给LLM的工具。在本例中,我们暴露了GitHub工具(system.github_files, system.github_issues, …)

{
system: [
"system",
"system.tools",
"system.explanations",
"system.github_actions",
"system.github_files",
"system.github_issues",
"system.github_pulls",
],
}

该代理的完整源代码定义在system.agent_github系统提示中。