如何使用DeepSeek的API开发大模型应用

如何使用DeepSeek的API开发大模型应用

DeepSeek-v3 和 DeepSeek-r1

最近Deepseek因为连续发布了Deepseek-v3和Deepseek-r1两个模型而迅速出圈,在全球科技领域引起了很大的轰动。

Deepseek2024年12月底发布并开源了DeepSeek-V3模型,性能可比肩顶级闭源模型。

Deepseek2025年1月发布了推理模型DeepSeek-R1,在多项测试中超越了OpenAI的o1模型。

以下是它们的基本介绍:

DeepSeek-V3

DeepSeek-V3 是一种混合专家(MoE)模型,具有 6710 亿参数,同时激活 370 亿参数。它在知识基础任务、长文本处理、代码生成和数学推理方面表现出色。它在中文语言能力方面也颇具特色。DeepSeek-V3 结合了多头潜在注意力(MLA)、DeepSeekMoE 和多标记预测(MTP)等创新。

主要特性和亮点:

  • 性能:DeepSeek V3 在一些领域超越了其他开源模型,并在某些方面与顶尖闭源模型如 GPT-4o 和 Claude 竞争。它在 MMLU(EM)上达到了 88.5% 的准确率,在 MMLU-Redux(EM)上达到了 89.1% 的准确率。
  • 速度:其生成速度提高了三倍,从每秒 20 个标记增加到 60 个标记(TPS)。
  • 架构:DeepSeek-V3 采用了一种新的负载平衡策略,不依赖于辅助损失。它使用细粒度专家系统,动态调整专家路由,以确保负载平衡而不牺牲模型性能。
  • 训练:DeepSeek-V3 使用 FP8 混合精度训练框架,完成了对 14.8 万亿标记的预训练,使用了 2.664M H800 GPU 小时。它从 DeepSeek R1 等模型中提炼推理能力,以提高其推理性能。

DeepSeek R1

DeepSeek R1 是一个基于开源和强化学习(RL)的模型,以其推理能力而闻名。它几乎完全依赖于 RL 进行微调,最小化了对标记数据集的需求。

主要特性和亮点:

  • 推理:DeepSeek R1 在数学、代码和自然语言任务中表现出强大的推理能力。在 AIME 2024 数学竞赛中,它达到了 79.8% 的 pass@1 得分。在 Codeforces 上获得了 2029 Elo 评分,超过了 96.3% 的人类参与者。
  • 训练:DeepSeek R1 使用多阶段训练过程,在强化学习之前集成冷启动数据。它采用基于规则的方法,确保可扩展的强化学习,并将强大的推理能力推广到其他领域。
  • 性价比:与 OpenAI 的 o1 模型相比,DeepSeek R1 的训练成本更低。每百万个标记的输入成本便宜 90%,输出价格约低 27 倍。
  • 开源:DeepSeek R1 在 MIT 许可下开源,允许用户自由使用、修改、分发和商业化该模型。

申请DeepSeek的API Key

进入DeepSeek官网, 点击右上角的“API开放平台”按钮,进入API开放平台页面。
选择“API Key”,点击“创建API Key”按钮,创建一个API Key。将你的API Key保存到安全的地方,后续会用到。

使用API Key调用DeepSeek的API

使用curl调用DeepSeek的API


curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer " \
  -d '{
        "model": "deepseek-chat",
        "messages": [
          {"role": "system", "content": "You are a helpful assistant."},
          {"role": "user", "content": "Hello!"}
        ],
        "stream": false
      }'

使用Python调用DeepSeek的API

DeepSeek的API与OpenAI的API兼容,因此完全可以使用OpenAI的SDK直接调用DeepSeek的API。
这也是官方文档推荐的方法。


# Please install OpenAI SDK first: pip3 install openai

from openai import OpenAI

client = OpenAI(api_key="", base_url="https://api.deepseek.com")

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "Hello"},
    ],
    stream=False
)

print(response.choices[0].message.content)

使用Langchain封装的接口调用DeepSeek的API

使用OpenAI的库是相对简单和直接的方法,但是OpenAI的库功能相对单一,如果需要更复杂
的功能,比如链式调用、内存管理、工具调用等,还是需要使用LangChain。

LangChain介绍

LangChain 是一个用于开发由大型语言模型(LLMs)驱动的应用程序的框架。简化了 LLM
应用程序生命周期的每个阶段,提供了一套工具、组件和接口,帮助开发者更高效地构建智
能应用。 LangChain 的主要功能包括:

  • 模型输入/输出(Model I/O):理大型语言模型的输入(Prompts)和输出格式化
    (Output Parsers)。
  • 数据连接(Data Connection):理向量数据存储(Vector Stores)、内容数据获取
    (Document Loaders)和转换(Transformers),以及向量数据查询(Retrievers)。
  • 记忆(Memory):于存储和获取对话历史记录的功能模块。
  • 链(Chains): Memory、Model I/O 和 Data Connection 串联起来,实现连续对话
    和推理流程。
  • 代理(Agents):于 Chains 进一步集成工具(Tools),将大语言模型的能力与本
    地或云服务结合。
  • 回调(Callbacks):供回调系统,可连接到 LLM 应用的各个阶段,便于日志记录和
    追踪。过这些功能,开发者可以创建各种应用程序,包括聊天机器人、智能问答工具、文档
    摘要生成等。

LangChain 还支持与外部数据源的连接,使语言模型能够与其环境进行交互,增强应用程序
的功能和灵活性。2022 年 10 月推出以来,LangChain 迅速获得了开发者的关注和支持,
成为构建 LLM 驱动应用程序的强大工具。

使用LangChain Python调用DeepSeek的API


# 安装必要库(如果未安装)
# pip install langchain-core langchain-openai

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 设置环境变量(替换为您的API Key)
os.environ["DEEPSEEK_API_KEY"] = "sk-your-api-key-here"

# 创建 DeepSeek 模型实例
# 假设 DeepSeek API 兼容 OpenAI 格式
model = ChatOpenAI(
    model="deepseek-chat",  # 指定模型名称
    base_url="https://api.deepseek.com/v1",  # DeepSeek API 地址
    api_key=os.environ["DEEPSEEK_API_KEY"],
    temperature=0.7,  # 控制生成随机性(0-1)
    max_tokens=512  # 最大输出长度
)

# 创建对话提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人的AI助手"),
    ("user", "{input}")
])

# 创建简单对话链
chain = prompt | model

# 执行对话
response = chain.invoke({
    "input": "请用Python写一个快速排序算法,并解释其原理"
})

print("AI回复:\n", response.content)

另外一种选择是,最新的langchain库已经提供了deepseek的扩展库 langchain-deepseek
因此直接使用该库,也可以很方便的调用DeepSeek的API。


# 安装必要库(如果未安装)
# pip install -U langchain-deepseek
export DEEPSEEK_API_KEY="your-api-key"

from langchain_deepseek import ChatDeepSeek

llm = ChatDeepSeek(
    model="deepseek-chat",
    temperature=0,
    max_tokens=None,
    timeout=None,
    max_retries=2,
    # api_key="...",
    # other params...
)

messages = [
    ("system", "You are a helpful translator. Translate the user sentence to French."),
    ("human", "I love programming."),
]
response = llm.invoke(messages)
print(response)

# Stream response
response = llm.stream(messages)
for chunk in response:
    print(chunk)

使用LangChain Go调用DeepSeek的API

Golang 非常适合开发云原生后端应用,同时相比Python,Golang的性能更高,更适合开发高性能的应用。
LangchainGo is the Go Programming Language port/fork of LangChain.
以下提供一个使用LangchainGo调用DeepSeek的API的示例。


package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    // Initialize the OpenAI client with Deepseek model
    llm, err := openai.New(
        openai.WithModel("deepseek-reasoner"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Create messages for the chat
    content := []llms.MessageContent{
        llms.TextParts(llms.ChatMessageTypeSystem, "You are a helpful assistant that explains complex topics step by step"),
        llms.TextParts(llms.ChatMessageTypeHuman, "Explain how quantum entanglement works and why it's important for quantum computing"),
    }

    // Generate content with streaming to see both reasoning and final answer in real-time
    completion, err := llm.GenerateContent(
        ctx,
        content,
        llms.WithMaxTokens(2000),
        llms.WithTemperature(0.7),
        llms.WithStreamingFunc(func(ctx context.Context, chunk []byte) error {
            fmt.Print(string(chunk))
            return nil
        }),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Access the reasoning content and final answer separately
    if len(completion.Choices) > 0 {
        choice := completion.Choices[0]
        fmt.Printf("\n\nReasoning Process:\n%s\n", choice.ReasoningContent)
        fmt.Printf("\nFinal Answer:\n%s\n", choice.Content)
    }
}

使用DeepSeek模型开发智能应用的场景

DeepSeek 模型和其他大模型一样,在多个领域具有广泛的应用:

  • 城市治理:AI 可以处理公众请求,协助政府工作人员,并通过 AI 助手和公众关切问题的智能分析来支持决策制定。
  • 客户服务:通过集成 DeepSeek API,企业可以创建 24/7 全天候可用的 AI 助手,用于回答客户问题并提高响应速度。
  • 内容创作:DeepSeek 能够快速生成高质量的文本,例如新闻报道、博客文章和营销内容,提高内容创作效率。
  • 教育:DeepSeek 可用于开发智能教育平台,根据学生的表现个性化学习计划,识别知识盲点,并提供针对性的练习。
  • 医疗:DeepSeek 的智能诊断系统可以快速分析医学影像,提供精准的诊断建议,从而辅助诊断和药物研发。
  • 金融:它可以分析金融数据,提供投资建议、风险评估以及欺诈预防。

DeepSeek 模型还可应用于智能家居,实现语音交互和场景识别;在智能交通领域,用于优化交通流量和辅助驾驶。

此外,DeepSeek 模型适用于需要高推理能力的任务,例如解决数学问题、编写代码以及处理逻辑复杂的场景。
DeepSeek V3 模型兼容 OpenAI API,具有高性价比和优异性能,能够降低获取、部署和使用大模型的成本,
加速其在商业和消费场景中的应用。

我个人的开发案例

目前我正在探索使用AI大模型来提升Linux运维效率,以下是一些探索和实践。

基于DeepSeek 的 nuwa-terminal 智能终端助手

nuwa-terminal 是一个在终端中与大语言模型(LLM)聊天的程序,该工具基于LLM,旨在使终端更加智能。这个终端可以帮助用户使用自然语言 执行命令或任务,同时它还可以作为终端智能助手,你可以询问任何关于软件开发的任何问题。

该文章基于原生deepseek开发的智能终端工具nuwa-terminal 会有详细的介绍。

GitHub地址:nuwa-terminal

基于DeepSeek 的 Linux 系统监控程序

AI Agentic Monitor 是一个基于 AI 智能体技术的系统监控工具。它旨在监控Linux及Cloud系统的状态,并提供实时警报和系统优化建议。
它还非常智能,可以帮助您找到问题的根本原因并提供解决方案。目前该项目还在开发中,欢迎感兴趣的朋友一起参与。

GitHub地址:AI Agentic Monitor

使用golang开发AI大模型应用-langchaingo介绍

使用golang开发AI大模型应用-langchaingo介绍

随着生成式大模型的发展,AI大模型应用的开发也变得越来越重要。由于Python语言在AI领域良好的生态和丰富的库,因此Python语言成为AIGC领域的绝对统治者。在AI领域,Python成为开发AI应用的首选语言。2024在tiobe编程语言排行榜中,Python成为霸榜的编程语言。

但是在后端服务及云原生领域,Golang却是首选语言,相比Python,Golang有更好的性能和并发性。因此,如果你想开发基于AI大模型的后端应用,Golang一定是个不错的选择。美中不足的是,Golang在AI领域的生态相对较弱,能够使用的现成的库并不是很多。

LangChain Go 简介

Langchain目前成为使用python开发AI智能应用的首选框架,它提供了一套工具、组件和接口,使开发人员能够更轻松地构建智能应用。

LangChain 框架包含以下主要组件:

  • Models: 作为基础构建块,提供语言理解和生成能力。
  • Prompts: 用于指导模型生成特定输出的模板。
  • Indexes: 用于高效检索和提取信息。
  • Chains: 将多个组件连接起来,实现复杂的任务流程。
  • Agents: 具有自主决策能力的智能体,可以根据任务选择合适的工具。
  • Memory: 为对话型应用提供历史记忆功能,确保对话的连贯性。

LangChain Go是用Go语言实现的langchain库,基本功能对标了Python版本的langchain库。
使用LangChain Go,开发者可以使用Golang语言快速的构建AI服务及应用。

Github 地址: https://github.com/tmc/langchaingo
开发文档:https://tmc.github.io/langchaingo/docs/
接口文档:https://pkg.go.dev/github.com/tmc/langchaingo

准备工作

在开始之前,你需要安装Go语言环境,可以参考Go语言官方文档进行安装。

由于Golang 也存在多钟版本,如果你需要从多个Golang版本之间进行切换时,可以使用 Glang version manager 进行管理。

使用Google 的Gemini模型

我个人开发过程中,起初使用的Google的Gemini 1.5模型,但是由于免费版本对于请求有一些限制,我后来使用国产的Deepseek模型,其价格非常便宜,性能也不错。

最近Google发布了最新的Gemini 2.0 模型,相比1.5版本,Gemini 2.0 模型在生成式任务上有了更好的表现。目前Gemini 2.0 Flash 版本对开发者提供免费使用,可以通过Google AI Studio申请API key: https://aistudio.google.com/apikey

以下代码示范如何使用LangChain Go调用Google Gemini 2.0模型生成文本:

编译以下代码需要添加go.mod文件:


module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    cloud.google.com/go v0.114.0 // indirect
    cloud.google.com/go/ai v0.7.0 // indirect
    cloud.google.com/go/aiplatform v1.68.0 // indirect
    cloud.google.com/go/auth v0.5.1 // indirect
    cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
    cloud.google.com/go/compute/metadata v0.3.0 // indirect
    cloud.google.com/go/iam v1.1.8 // indirect
    cloud.google.com/go/longrunning v0.5.7 // indirect
    cloud.google.com/go/vertexai v0.12.0 // indirect
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/felixge/httpsnoop v1.0.4 // indirect
    github.com/go-logr/logr v1.4.1 // indirect
    github.com/go-logr/stdr v1.2.2 // indirect
    github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
    github.com/golang/protobuf v1.5.4 // indirect
    github.com/google/generative-ai-go v0.15.1 // indirect
    github.com/google/s2a-go v0.1.7 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
    github.com/googleapis/gax-go/v2 v2.12.4 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
    go.opencensus.io v0.24.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect
    go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect
    go.opentelemetry.io/otel v1.26.0 // indirect
    go.opentelemetry.io/otel/metric v1.26.0 // indirect
    go.opentelemetry.io/otel/trace v1.26.0 // indirect
    golang.org/x/crypto v0.23.0 // indirect
    golang.org/x/net v0.25.0 // indirect
    golang.org/x/oauth2 v0.21.0 // indirect
    golang.org/x/sync v0.7.0 // indirect
    golang.org/x/sys v0.20.0 // indirect
    golang.org/x/text v0.15.0 // indirect
    golang.org/x/time v0.5.0 // indirect
    google.golang.org/api v0.183.0 // indirect
    google.golang.org/genproto v0.0.0-20240528184218-531527333157 // indirect
    google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect
    google.golang.org/grpc v1.64.0 // indirect
    google.golang.org/protobuf v1.34.1 // indirect
)

主函数:


package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/googleai"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("GOOGLE_API_KEY")
    llm, err := googleai.New(ctx, googleai.WithAPIKey(apiKey), googleai.WithDefaultModel("gemini-2.0-flash-exp"))
    if err != nil {
        log.Fatal(err)
    }

    prompt := "简单介绍下langchain go库?"
    answer, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(answer)

运行以上程序:


export GOOGLE_API_KEY="your-google-api-key"
go run main.go

使用OpenAI的模型生成内容

OpenAI几乎没有开放免费额度给开发者使用,同时国内用户也无法使用,这是比较可惜的。但是OpenAI的模型在生成式任务上表现非常优秀,因此很多开发者还是会选择使用OpenAI的模型。

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    llm, err := openai.New(openai.WithModel("gpt-4o-mini"))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "The first man to walk on the moon",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export OPENAI_API_KEY="your-openai-api-key"
go run main.go

使用Deepseek的模型生成内容

Deepseek是国产模型,性能不错,价格也便宜。以下代码示范如何使用LangChain Go调用Deepseek模型生成文本,由于Deepseek支持OpenAI的接口标准,因此使用方法与OpenAI几乎一样。另外国产模型通义千问也是一种选择,但是目前langchang go并没有提供封装和支持,希望后续版本能够提供支持。

就在我发布该文章的第二天,deepseek发布了v3版本,性能相比v2有了大部的提升,强烈推荐国内的开发者使用deepseek模型。

申请API key: https://www.deepseek.com/

go mod文件:


module module your_module_name

go 1.22.0

toolchain go1.22.1

require github.com/tmc/langchaingo v0.1.13-pre.0

require (
    github.com/dlclark/regexp2 v1.10.0 // indirect
    github.com/google/uuid v1.6.0 // indirect
    github.com/pkoukk/tiktoken-go v0.1.6 // indirect
)

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tmc/langchaingo/llms"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    apiKey := os.Getenv("DEEDSEEK_API_KEY")
    llm, err := openai.New(openai.WithModel("deepseek-coder"), openai.WithBaseURL("https://api.deepseek.com/beta"), openai.WithToken(apiKey))
    if err != nil {
        log.Fatal(err)
    }
    ctx := context.Background()
    completion, err := llms.GenerateFromSinglePrompt(ctx,
        llm,
        "介绍下docker",
        llms.WithTemperature(0.8),
        llms.WithStopWords([]string{"Armstrong"}),
    )
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("The first man to walk on the moon:")
    fmt.Println(completion)
}

运行以上程序:


export DEEDSEEK_API_KEY="your-openai-api-key"
go run main.go

其他使用示例

本文只是介绍了最基本的示例,后续文章会提供更多的示例。

关于langchain go的其他使用示例,可以参考该项目提供的exampls目录,里面包含了一些常见的使用示例。

https://github.com/tmc/langchaingo/tree/main/examples

参考文档

https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/
https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/

提示词工程-ReAct提示词(反应式)-让智能体像人一样思考和行动

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

提示词工程-ReAct

提示词工程的魅力就在于,让你可以变成现代版的祭师,能够让大模型言听计从,控制大模型做你想做的事情。

我不太确定超级智能会在未来的哪一天出现,但是从AI的快速迭代和进化来看,我们似乎可以预测,这一天不会遥远。一直以来,创造一个能够自主思考,自主学习和进化的智能体应该是AI发展的终极目标,而在这样的发展进程中,提示词工程也许只是这个进程中的一小段旅程,也许有一天,这项技术会成为历史,不过至少现在,它能够让我们对AI大模型有更加深入的了解,并且助力大模型变得更加聪明和务实。

起初,很难相信,生成模型会具有思考的能力,可当研究人员不断的探索出新的提示词技术时,这种怀疑逐渐得到了清晰的答案。

ReAct 提示词

ReAct 是 "Reasoning and Acting" 的缩写,旨在通过结合推理和行动来提高模型在复杂任务中的表现。

起初该框架由Yao 等人于2022年提出。

ReAct提示词实际上是one-shot或者few-shot提示词的一种(对于什么是one-shot,few-shot提示词,请阅读《提示词工程-少样本提示》)。
简单的说,就是给AI大模型一个思考-行动的例子,通过该例子,表明完成一件特殊任务时,思考和行动的基本框架和逻辑。ReAct本身是拟人化的,模拟人类思考和行动的基本方式,这里我可以举一个非常简单的例子,比如肚子饿了,非常想吃蛋糕:

问题:俺肚子饿了,非常想吃蛋糕。
思考:看看家里有没有买了蛋糕啊?
行动:去冰箱里看看,去厨房看看,发现没有。
思考:想吃自己做的蛋糕呢,还是去点外卖呢,哎,最近有点懒,不想动,还是外卖吧!
行动:打开手机APP,搜索蛋糕,得到种类繁多的蛋糕。
思考:我到底想吃哪一种呢,好像提拉米苏更加诱人一些。
行动:下单购买提拉米苏。
......

以上只是一个非常简单的例子,对人类来说,看起来是件非常普通和自然的事情,可是将思考方式分解,用来提示AI大模型时,会出现非常神奇的效果。

与链式思维推理类似,ReAct 是一种提示工程方法,使用少量样本学习来教模型解决问题。CoT 旨在模仿人类思考问题的方式,ReAct 也包含了这种推理元素,但更进一步地允许智能体通过文本操作与其环境进行交互。人类通过语言推理(说话或思考)来帮助制定策略和记忆事物,但我们也可以采取行动来获取更多信息并实现目标。这就是 ReAct 的基础。

ReAct 提示包括包含行动的示例,通过行动获得的观察,以及人类在过程中不同阶段的书面思考(推理策略)。LLM 学会模仿这种交替进行思考与行动的方法,使其成为环境中的智能代理。下方是 ReAct 智能体如何运作的示例,(按“思考 -> 行动 -> 观察 -> 思考”顺序)。

ReAct智能体的任务执行的大致过程:

  • 用户提出问题。
  • 思考,第一步应该做什么,决定执行动作和环境互动。
  • 行动,使用外部工具,从环境中获取需要的信息。
  • 观察,将行动的结果和收集的信息作为下一步思考的输入。
  • 思考,判断是否问题得到解决,基于上一步观察的结果,重新制定下一步需要执行的动作。
  • 重复以上循环,直到问题解决,或者得到了最终的答案,并结束。

ReAct 提示词是一种思考和行动的模版和范式,教AI大模型按照这种思维框架进行学习和解决问题,与其他提示工程不同的是,ReAct需用通过和环境的互动,获取信息,做动态的调整和规划。因此使用ReAct提示词时,同时需要实现智能体,或者智能代理,能够让智能体使用工具和外部环境进行交互。

更多ReAct提示词的例子

以下是一个来自论文的 ReAct 提示示例

你是知识问答机器人,你会帮助用户回答科学,地理等相关科普知识,给用户提供准确的答案,请以以下例子为参考,以思考-行动-观察 迭代的方式,确保你的答案是实时准确的,你可以通过搜索引擎获取外部知识。

问题:科罗拉多造山运动的东部区域延伸到的区域的海拔范围是多少? 
思考 1:我需要搜索“科罗拉多造山运动”,找出其东部区域延伸到的地方,然后找出该区域的海拔范围。 
行动 1:搜索[科罗拉多造山运动] 
观察 1:科罗拉多造山运动是科罗拉多及周边地区发生的造山事件。 
思考 2:资料中没有提到东部区域,因此我需要查找“东部区域”。 
行动 2:查找[东部区域] 
观察 2:(结果 1 / 1)东部区域延伸到大平原,被称为中央平原造山运动。 
思考 3:科罗拉多造山运动的东部区域延伸到大平原。因此,我需要搜索“大平原”的海拔范围。 
行动 3:搜索[大平原] 
观察 3:“大平原”指的是两种不同的土地区域之一。 
思考 4:我需要改为搜索“美国大平原”。 
行动 4:搜索[美国大平原] 
观察 4:大平原是大平原的一个子区域。从东到西,大平原的海拔从约 1,800 英尺(550 米)上升到 7,000 英尺(2,130 米)。 
思考 5:大平原的海拔范围是从约 1,800 英尺到 7,000 英尺,因此答案是 1,800 英尺到 7,000 英尺。 
行动 5:完成[1,800 英尺到 7,000 英尺]

通用ReAct智能体提示词模版

以下提供的提示词模版是对ReAct的抽象和总结,通过以下模版,开发人员可以定义 AI Agent的基本角色和用户场景,以及智能体能够和外界交互的可用工具集。同时指导智能体在执行特定任务时,需遵从“思考-》执行任务-》观察-》思考”的迭代过程。

以下的ReAct通用提示词可以使用在任何任务场景,程序员只要稍加调整和修改就可以应用在自己的工具和用例里。

TOOL_DESC = """{name_for_model}: Call this tool to interact with the {name_for_human} API. What is the {name_for_human} API useful for? {description_for_model} Parameters: {parameters} Format the arguments as a JSON object."""

REACT_PROMPT = """Answer the following questions as best you can. You have access to the following tools:

{tool_descs}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {query}"""

以下是该提示词模板的中文翻译:

TOOL_DESC = """{name_for_model}:调用此工具以与{name_for_human} API 交互。{name_for_human} API 有什么用途?{description_for_model} 参数:{parameters} 将参数格式化为 JSON 对象。"""

REACT_PROMPT = """请尽可能准确地回答以下问题。你可以使用以下工具:

{tool_descs}

使用以下格式:

问题:你必须回答的输入问题
思考:你应该始终考虑要做什么
行动:要采取的行动,应为 [{tool_names}] 之一
行动输入:行动的输入
观察:行动的结果
...(此思考/行动/行动输入/观察可以重复零次或多次)
思考:我现在知道最终答案了
最终答案:对原始输入问题的最终答案

开始!

问题:{query}"""

写在最后

由于ReAct需要通过环境来获取信息,因此从环境中获取的信息的准确性会严重影响最终的输出结果。因此开发者需要考虑环境信息的准确和可靠,才能保证ReAct应用的性能和可靠性。

ReAct的推理并不完美,但仍然是一种强大的提示工程方法,它克服了链式推理中的幻觉问题,并使大型语言模型能够成为可以与环境互动的智能体。此外,这是一种非常可解释的方法,因为智能体在行动时会输出其思维过程。

ReAct提示词可以让智能体变的更加聪明,帮助我们解决更加复杂的问题,探索ReAct智能体是一件非常有趣的过程。

我相信你一定好奇,如何使用以上的提示词模版实现一个能够自主思考的智能体,接下来后续的文章我将分析如何通过不同的Agent框架,快速的构建智能体,希望持续关注我的博客文章。

参考文章:

智能体(LLM Agent) 资料汇总(持续更新)

文章会实时同步到我的公众号,有兴趣的童鞋扫码关注我的公众号噢:

智能体(LLM Agent)资料汇总

本文致力于收集整理所有LLM Agent相关的资料,共大家参考学习。

智能体概念

提示词工程

智能体概念

智能体编程框架

智能体编程实战

智能体低代码平台

智能体应用

提示词工程-少样本提示词

少样本提示词(few-show-prompt)

少样本提示(Few-shot Prompting)是一种用于大语言模型(LLM)的技术,通过提供少量示例来引导模型生成更符合预期的输出。这种方法在处理复杂任务时相较于零样本提示(Zero-shot Prompting)表现更佳,有时候会出现事半功倍的效果,因为它为模型提供了上下文和具体的示例,有助于模型理解用户的需求。

定义与原理

少样本提示的核心在于通过给定一小部分示例,帮助模型在特定任务上进行学习和推理。与零样本提示不同,后者不提供任何示例,完全依赖模型的预训练知识。例如,在少样本提示中,可以提供一个新词的定义及其使用示例,以帮助模型理解如何在句子中正确使用该词[1][2][3]。

应用场景

少样本提示适用于多种场景,尤其是那些需要特定领域知识或复杂推理的任务。以下是一些典型应用:

  • 语言生成:通过提供语境和示例,改善文本生成的质量。
  • 情感分析:使用标记示例帮助模型识别文本中的情感倾向。
  • 特定领域任务:如法律、医学等领域,可以通过少量高质量示例来提高输出的准确性[3][4].

少样本或多样本提示词已经成为其他提示词工程的基础,比如思维链提示词就是通过少样本演变来的提示词工程技术,除了思维链提示词,其他提示词技术都涉及到提供示例来引导大模型输出更加准确可控的信息。

另外当我们使用提示词工程相关的技术应用到编程领域时,可以通过少样本提示词,精确的控制模型的输出,这样的话,程序就可以很容易的解析输出格式,增强软件的鲁棒性。

技巧与注意事项

在实施少样本提示时,有几个技巧可以提高效果:

  • 使用标签:在示例中添加标签可以帮助模型更好地理解任务要求,即使标签格式不统一也能有效提升性能[1][2]。
  • 多样性与质量:所提供示例的多样性和质量直接影响模型的输出效果。垃圾进则垃圾出,低质量的示例可能导致错误的结果[3][4]。
  • 思维链技术:结合思维链(Chain of Thought)提示,可以引导模型进行逻辑推理,从而提高复杂问题的回答准确性[4][5].

局限性

尽管少样本提示具有许多优点,但它也存在一些局限性:

  • 依赖于示例质量:如果提供的示例不够清晰或相关,可能会导致模型输出不准确或不相关的信息。
  • 过拟合风险:模型可能会过度依赖给定的示例,而无法泛化到新的、未见过的情况[2][3]。

总之,少样本提示是一种强大的工具,可以显著提升大语言模型在复杂任务中的表现,但成功实施这一技术需要精心设计和选择高质量的示例。

少样本提示词的一些实例:

  • JSON格式输出:
输入: 创建一个包含姓名和年龄的人员信息
输出: 
{
  "name": "张三",
  "age": 30
}

输入: 创建一个包含书名和作者的图书信息
输出: 
{
  "title": "三体",
  "author": "刘慈欣"
}

输入: 创建一个包含产品名称和价格的商品信息
输出:
  • 函数定义格式:
输入: 创建一个计算两数之和的Python函数
输出:
def add_numbers(a, b):
    return a + b

输入: 创建一个判断字符串是否为回文的Python函数
输出:
def is_palindrome(s):
    return s == s[::-1]

输入: 创建一个计算给定数字阶乘的Python函数
输出:
  • SQL查询格式:
输入: 从users表中选择所有用户的名字和邮箱
输出:
SELECT name, email FROM users;

输入: 从products表中选择价格高于100的所有产品
输出:
SELECT * FROM products WHERE price > 100;

输入: 从orders表中选择2023年1月1日之后的所有订单
输出:
  • HTML模板格式:
输入: 创建一个包含标题和段落的HTML结构
输出:
<div class="content">
  <h1>标题</h1>
  <p>这是一个段落。</p>
</div>

输入: 创建一个包含图片和描述的HTML结构
输出:
<figure>
  <img src="image.jpg" alt="描述">
  <figcaption>图片描述</figcaption>
</figure>

输入: 创建一个包含无序列表的HTML结构
输出:

这些例子展示了如何使用少样本提示来指导AI生成特定格式的代码或输出。通过提供一两个例子,AI可以学习并推断出所需的格式和结构。

参考文章

[1] https://www.sohu.com/a/788035576_120635785
[2] https://www.promptingguide.ai/zh/techniques/fewshot
[3] https://www.53ai.com/news/qianyanjishu/2024061397638.html
[4] https://learn.tishi.top/docs/advanced/few-shot-prompting/
[5] https://www.woshipm.com/share/6111304.html
[6] https://sspai.com/post/91879
[7] https://v2-ai.tutorial.hogwarts.ceshiren.com/ai/aigc/L2/tutorial/%E5%B0%91%E6%A0%B7%E6%9C%AC%E6%8F%90%E7%A4%BA/
[8] https://cloud.baidu.com/qianfandev/topic/267310
[9] https://www.promptingguide.ai/techniques/fewshot
[10] https://www.prompthub.us/blog/the-few-shot-prompting-guide

一文读懂LLM参数设置,实现大模型应用的最佳性能

一文读懂LLM参数设置,实现大模型应用的最佳性能

引言

可以预见的是,通过生成模型,和通用模型,AI正在不断重塑整个数字化世界,在2024年我们看到LLM 应用像雨后春笋一样,基于LLM开发大模型应用已经逐渐成为程序员掌握的必备技能。

本文将重点介绍开发LLM 应用时,LLM基本参数的重要性,指导通过LLM 参数的设定可以提高应用的性能。

如何掌握temperature、top_p、max_length参数以实现最佳LLM表现?

在设计和测试LLM 应用的提示时,通常需要通过 API 与 LLM 进行交互。API可以配置一些参数以获得不同的提示结果。调整这些设置对于提高响应的可靠性和可取性非常重要,需要进行一些实验才能找出适合您用例的设置。以下文章内容将对不同LLM 之间常见的设置进行解释,并提供设置指导。

优化LLM性能的关键设置

温度

温度是一个控制模型输出随机性的基本设置。较低的温度通过偏向高概率标记使结果更具确定性,而较高的温度则引入更多变化性和创造性。

示例:
对于基于事实的任务(如回答问题或总结文本),较低的温度(如0.2)可确保简洁准确的回答。相比之下,对于创意写作任务(如诗歌生成或头脑风暴),较高的温度(如0.8)可以产生更多样化的输出。

要点

  • 较低温度 = 更确定性的回答
  • 较高温度 = 更具创意和多样性的回答
  • 根据任务要求调整

Top P(核采样)

Top P通过仅考虑构成生成每个标记的顶级累积概率质量的标记子集来控制回答的多样性。

示例:
较低的Top P值(如0.1)将输出限制为高概率标记,适合生成事实性内容。较高的Top P值(如0.9)允许输出更多样化,适合需要创意的任务。

要点

  • 低Top P = 自信精确的答案
  • 高Top P = 多样化和创意输出
  • 使用温度Top P,但不要同时使用两者

最大长度

最大长度定义了对提示的回应中生成的标记数量。

示例:
设置适当的最大长度可以防止过长或无关的回答,同时控制与标记使用相关的成本。

要点

  • 有效管理回答长度
  • 防止无关或冗长的输出
  • 通过控制标记使用优化成本

停止序列

停止序列是一个信号模型停止生成更多标记的字符串。

示例:
要生成不超过十个项目的列表,使用"11"作为停止序列,在列出十个项目后停止输出。

要点

  • 精确控制回答长度
  • 确保结构化输出
  • 使用针对特定任务定制的停止序列

频率惩罚 & 存在惩罚

两种惩罚都减少重复,但应用方式不同:

  • 频率惩罚:较高的值会抑制回答中重复的单词。
  • 存在惩罚:对所有重复的标记施加相等的惩罚,不考虑频率。

示例:
对于多样化的文本生成,使用较高的惩罚;对于聚焦的内容重复控制,根据需求相应调整。

要点

  • 频率惩罚按比例减少单词重复。
  • 存在惩罚平等地抑制任何重复短语。
  • 根据所需结果一次调整一个惩罚。

参考原文链接https://medium.com/@justmalhar/understanding-llm-settings-for-optimal-performance-83ee29c50392

思维链提示词工程(Chain-of-Thought Prompting)

思维链提示词工程

扩大大型语言模型(LLMs)的规模在情感分析和机器翻译方面已经显示出了良好的结果,即使没有提供任何示例。然而,它们在解决复杂的多步骤问题,如算术和常识推理方面却表现不佳。为了解决这个问题,LLMs可以针对特定任务进行微调,或者通过少量示例提示(few-shot prompting)来教授。然而,这两种方法都有其局限性。微调在创造高质量推理方面成本较高,而仅使用少量示例提示对于任务来说效果不够好。

思维链(Chain-of-Thought,简称CoT)提示可以同时解决这两个问题。在本文中,我们将探讨CoT提示以及如何实施它来提升您的业务技能。

什么是提示工程?

提示工程是一种编写结构良好、精心设计的提示的实践,这些提示能被生成性AI模型更好地理解。提示告诉大型语言模型(LLM)需要执行什么任务以及生成什么样的输出。它可以包含指令、上下文、输入数据和输出指标。通过使用提示工程,我们可以利用LLM来完成各种任务,从简单的问题回答到复杂的创意文本生成。它基于一种新兴属性——上下文学习,允许LLM从提示中学习。提示工程提高了LLM在手头任务上的表现。它使用了前文提到的零样本、少样本、主动和思维链提示等技术。

零样本提示

在零样本提示中,我们给大型语言模型(LLM)一个描述任务的提示,但这个提示本身并不提供任何任务的示例。然后,我们要求LLM针对这个提示生成一个回答。这种方法增强了LLM的灵活性和泛化能力。它可以用来在多个任务上训练LLM,而无需为每个任务收集训练数据。例如,ChatGPT可以在没有任何写诗示例的情况下,根据提示工程写出一首诗。然而,零样本提示在处理复杂任务时是有限的。

少样本提示

少样本提示可以通过提供示例来引导模型获得更好的表现。这是一种向大型语言模型提供少量期望输出示例的技术,除了主要提示之外还包括这些例子。这些示例帮助模型更好地理解任务,从而生成更准确、更有信息量的回答。我们应该向模型提供丰富多样的例子,而不是多个相似的例子。这样做可以确保模型尽可能多地学习关于任务的知识。标准的少样本提示对许多任务来说是一种不错的技术,但对于复杂的推理任务则不太可靠。因此,我们需要更高级的提示技术,比如思维链、主动提示和微调等。

主动提示

主动提示通过不断给予大型语言模型(LLM)反馈来提高它们在复杂任务上的表现。这种反馈可以帮助LLM从错误中学习,生成更准确、更有价值的回答。
主动提示的过程是这样的:首先给LLM一个提示和一些期望输出的例子。然后LLM生成一个回答。接着,人类评估者会评价这个回答,并就其准确性和信息量给出反馈。LLM再利用这些反馈来改进自己生成回答的能力。这个过程会不断重复,直到LLM能够生成足够准确和有价值的回答,让人类评估者满意为止。
主动提示对于思维链(CoT)提示特别重要,因为它可以:

  • 找出需要重点标注的问题
  • 减少人工标注的工作量
  • 提高CoT提示的准确性和信息量

下图展示了如何通过主动提示配合CoT来提升性能。这是一个包含四个阶段的过程:

  • 通过多次查询LLM来估计一个问题的不确定性
  • 通过排序选出最不确定的问题进行标注
  • 由人类评估者对这些问题进行详细反馈标注
  • 利用LLM生成答案,并使用标注阶段的反馈来提高新问题答案的质量

什么是思维链提示?

思维链提示是一种提示工程技术。通过这种技术,我们能让大型语言模型(LLM)输出一系列中间步骤,最终得出所需的答案。这种方法能提高LLM的推理能力。

思维链提示的好处有:

  • 让模型能专注于一次解决一个步骤,而不是一下子考虑整个问题。
  • 对于那些难以或无法一步解决的复杂问题特别有帮助。
  • 为我们提供了一个可解释的窗口,让我们能看到模型的行为。我们可以通过跟随模型采取的步骤序列,了解它是如何得出答案的。

总的来说,思维链提示让我们能更好地理解和控制LLM的思考过程,从而得到更准确、更可靠的结果。

思维链(CoT)提示可以用于参数量很大(大约1000亿个参数)的大型语言模型,适用于多种推理任务,包括数学应用题、常识推理和符号运算。

举个例子,在PaLM模型中使用CoT提示,而不是标准的少样本提示,显著提高了在GSM8K基准测试中的表现,
从17.9%提升到了58.1%。

有趣的是,对于足够大的语言模型来说,不需要特殊训练或微调,就可以轻松引出CoT推理过程。这个特点使得CoT提示成为一种可扩展且容易使用的技术。

简单来说,CoT提示就像是给模型一个"思考的框架",让它能像人类一样一步步推理,而不是直接给出答案。这种方法特别适合大型模型,因为它们有足够的"智力"来理解和执行这种复杂的思考过程。而且,因为不需要额外训练,任何人只要有权限使用这些大模型,就可以尝试CoT提示技术。

少样本思维链

少样本提示是指给大型语言模型(LLM)提供一个问题和答案。然后,再给LLM几个解决类似问题的例子。这些例子的呈现方式会鼓励LLM对问题进行思考,形成一条通向答案的思维链。

少样本思维链比普通的少样本基准更有效地提高了LLM的推理能力,因为它为LLM提供了类似问题的例子。不过,少样本思维链的实施可能会比普通少样本基准更复杂,因为它需要创建示例提示。

尽管如此,少样本思维链带来的好处还是超过了额外的复杂性。它让LLM不只是简单地回答问题,而是学会了如何思考和推理。这种方法可以让LLM处理更复杂的问题,给出更详细、更准确的答案。

简单来说,少样本思维链就像是给LLM提供了一些"解题思路"的例子,而不仅仅是答案。这样,LLM就能学会如何一步步地思考问题,而不是只会简单地背诵答案。虽然准备这些例子可能会多花些时间,但最终得到的结果会更好,更有价值。

零样本思维链

零样本思维链是指在原始提示中加入"让我们一步步思考"这句话。它通过两个步骤来提取推理过程和答案。

  • 推理提取:
    在这一步,语言模型思考问题,形成一条通向答案的推理链。我们给语言模型一个包含问题和触发句"让我们一步步思考"的提示。然后,语言模型会生成一个解释它如何得出答案的句子。

  • 答案提取:
    在第二步,我们从语言模型的回答中提取最终答案。我们把提示、生成的句子和一个触发句"答案是"连在一起。这告诉语言模型给我们答案。然后,语言模型会生成一个包含问题答案的句子。

相比之下,零样本基准使用"答案是"这样的提示来提取答案。而少样本提示,无论是标准的还是思维链的,通过设计以正确格式结尾的示例答案,避免了使用这种答案提取提示的需要。

研究人员比较了零样本思维链和其他两种评估大型语言模型零样本推理能力的方法。结果发现,在各种推理任务中,零样本思维链的表现优于其他方法。

如果你想找一个经过思维链提示训练的较小模型,可以考虑Flan-T5模型。它可以用于零样本自然语言处理任务,包括文本摘要、自然语言推理、翻译和常识推理。

思维链能力何时出现?

思维链推理是大型语言模型(LLM)的一种涌现能力,可能是由于模型参数超过1000亿而产生的。对于较小的LLM,思维链并不能提高性能,只有在使用这种规模的模型时才能带来性能提升。这有两个原因:

  • 较小的LLM无法生成既流畅又合乎逻辑的长思维链。这导致其表现不如标准提示。
  • 思维链推理对更复杂的问题更有效。它要求LLM能够识别解决问题的关键步骤,然后生成一连串思考过程,最终得出解决方案。较小的LLM可能无法像大型LLM那样有效地做到这一点。

大型LLM出现思维链推理能力的另一个原因可能与它们的预训练数据有关。大型LLM通常在包含逐步推理的海量数据集上训练,这可能有助于它们发展出以思维链方式推理的能力。

有趣的是,遵循指令的能力似乎并不是思维链能力所必需的。研究显示,使用未经过遵循指令微调的LLM,也能展现零样本和少样本思维链推理。不过,遵循指令的能力可能会提高思维链推理的质量。

如何进行思维链提示?

要进行思维链提示,你只需在提示的末尾加上"让我们一步步思考"这句话。这会迫使模型分步思考,将问题分解成更小的部分。下面是一个例子,展示了不使用和使用思维链提示的区别:

你可以看到,使用思维链让大型语言模型(LLM)给出了更好、更复杂且正确的输出。没有分步思考的提示立即导致了错误的答案。

如果你有一个非常严格的问题,你知道只能用特定的推理模式来解决,那就是你应该使用少样本思维链的时候。你可以提供一些针对你特定问题集所需的推理步骤的例子,然后LLM会尝试用类似的步骤来解决给定的问题。或者,你可以用这种技术为你的用户以特定方法解决问题。比如,如果学生要使用你的应用,你可能想用少样本思维链以有趣、简单且易懂的方式解决问题。

这些少样本例子应该展示中间步骤和最终解决方案。一旦你开发了思维链提示和例子,你就可以将它们整合到模型中。最后,测试模型并反复调整思维链提示和例子,直到模型的表现令人满意。

思维链提示的关键方面

在这部分,我们将探讨影响大型语言模型中思维链提示性能和可靠性的重要维度。我们将深入研究敏感性、自一致性、鲁棒性和连贯性如何在塑造思维链提示技术的有效性中发挥关键作用。

自一致性

自一致性是一种提高语言模型在需要多步推理任务上表现的技术。在思维链提示的背景下,自一致性可以通过为同一个问题采样多个不同的思维链来提高模型的性能。然后,模型可以被训练从这些思维链中选择最一致的答案。

自一致性显著提高了思维链提示在许多流行的算术和常识推理基准测试上的表现。例如,在GSM8K基准测试中,自一致性将思维链提示的性能提高了17.9%。在SVAMP基准测试中提高了11.0%,在AQuA基准测试中提高了12.2%。

这是一种完全无监督的技术,可以直接在预训练的语言模型上使用。它不需要额外的人工标注,也避免了任何其他训练、模型或微调。它对采样策略和参数具有鲁棒性。在PaLM-540B上改变温度采样中的T、top-k采样中的k和核采样策略中的p时,自一致性始终能提高性能。

鲁棒性

研究人员进行了三组不同的思维链标注实验,每组由不同的标注者完成。他们发现,无论是哪个标注者,思维链提示的表现始终优于标准基准。这表明思维链提示不依赖于特定的语言风格。

研究人员还进行了使用从GSM8K训练集随机抽样的样本的实验,这是一个独立的来源。他们发现,使用这些样本的思维链提示与使用手动编写的样本的思维链提示表现相当。这表明思维链提示不依赖于使用的具体样本。

研究人员还进行了使用不同数量样本的实验。他们发现思维链提示对不同数量的样本保持稳定。这表明思维链提示不需要大量样本就能有效。

研究人员还使用了各种语言模型进行实验,包括LaMDA 137B。他们发现思维链提示对所有这些语言模型都有效。这表明思维链提示不依赖于使用的特定语言模型。

总的来说,这些实验结果表明,思维链提示是一种可以提高语言模型在各种任务上表现的稳健技术。它不依赖于特定的语言风格、标注者、样本集或语言模型。

敏感性

思维链提示中的敏感性指的是提示的设计对模型性能的影响程度。如果提示设计不好,模型的性能可能会下降。提示应该清晰、简洁,易于模型理解。应避免使用模型可能不熟悉的行话或技术术语。提示应该与模型试图解决的特定任务相匹配。如果提示与任务不匹配,模型可能无法生成正确的答案。任务越复杂,模型对提示设计的敏感性可能越高。

当提示示例问题类型和任务问题类型不匹配时,少样本思维链的性能下降。这表明少样本思维链对提示的设计高度敏感,需要仔细将提示与特定任务匹配才能获得良好的性能。

连贯性

连贯性指的是思维链推理步骤的正确顺序程度。这意味着后面的步骤不应该是前面步骤的先决条件,前面的步骤也不应该基于后面的步骤。例如,在引入"32"或"42"之前出现"32 + 42 = 74"的推理就不具有连贯性。这是因为"32 + 42 = 74"这个等式是一个后面的步骤,依赖于引入数字"32"和"42"的前面步骤。

研究人员设计了一组消融设置,以检验连贯性对类似思维链推理不同组成部分的影响。消融设置是一种测试系统不同部分重要性的方法,通过移除它们并观察对系统性能的影响。研究发现,连贯性对类似思维链推理的所有组成部分都很重要。当移除连贯性时,系统的性能会下降。

研究人员还发现,语言模板的连贯性对思维链提示的性能特别重要。语言模板是用来连接思维链推理不同步骤的短语。如果语言模板不连贯,模型可能无法理解推理过程并生成正确的答案。

思维链提示的类型

在思维链(CoT)提示领域中,有两种显著的变体作为有影响力的策略:多模态CoT和从少到多提示。让我们详细探讨这些技术。

多模态CoT

传统的CoT专注于语言模态,这意味着它只使用文本为模型提供推理背景。多模态CoT将文本和视觉整合到一个两阶段框架中。

第一步涉及基于多模态信息的推理生成。这意味着模型同时接收文本和图像,然后被要求生成一个解释文本和图像如何相关的推理。

框架的第二阶段是答案推断。在这里,模型使用第一步生成的信息丰富的推理来推断出问题的正确答案。

1B多模态CoT的表现超过GPT-3.5 16个百分点(75.17%对91.68%的准确率),并在ScienceQA基准测试中超过了人类表现。在8个问题类别中,我们的模型将带配对图像的问题的表现从67.43%提高到88.80%。

像UnifiedQA和GPT-3.5这样的方法使用图像说明来理解图像显示的内容,然而,使用图像特征更有效。未来的研究可以通过使用更好的图像特征、添加常识知识和过滤掉无关信息来改进CoT推理。

从少到多提示

思维链提示是一种强大的自然语言推理技术,但在处理比提示中显示的例子更难的问题时可能会遇到困难。为了解决这个挑战,我们提出了一种新的提示策略,称为从少到多提示。

从少到多提示的工作原理是将一个复杂问题分解成一系列更简单的子问题,然后按顺序解决它们。每个子问题都由前面子问题的答案促进。

例如,要解决一个数学应用题,我们可能首先询问语言模型将问题分解成子问题,比如"第一件物品的成本是多少?"和"总成本是多少?"然后我们会询问语言模型依次解决子问题,使用前面子问题的答案来指导我们的查询。

从少到多提示在符号操作、组合泛化和数学推理任务上可以推广到更困难的问题。使用从少到多提示的GPT-3 code-davinci-002可以用14个示例解决SCAN,准确率达到99%,而思维链提示只能达到16%的准确率。

下表显示了不同提示方法在GSM8K和DROP基准测试中仅包含数值问题的子集上的准确率。基础语言模型是code-davinci-002。

下表显示了不同提示方法在最后字母连接任务上的准确率。

自动CoT

自动CoT是一种自动创建带有问题和推理链的演示的方法。它使用大型语言模型为每个演示生成推理链,使用"让我们一步步思考"的提示。自动CoT有两个主要步骤:

  1. 将给定数据集中的问题分成几个集群。
  2. 从每个组中选择一个代表性问题,并使用零样本CoT和简单的启发式方法生成推理链。

演示问题的多样性对于减少零样本CoT在推理链中的错误很重要。通过将问题聚类成几个组,自动CoT可以确保每个演示代表不同类型的问题。这有助于减少零样本CoT在推理链中犯错的机会。

自动CoT在10个推理任务上进行了测试,包括算术推理(MultiArith, GSM8K, AQUA-RAT, SVAMP)、常识推理(CSQA, StrategyQA)和符号推理(最后字母连接,硬币翻转)。在GPT-3中,自动CoT的表现始终与手动CoT相当或超过手动CoT。

这里是自动CoT与四种基线方法的比较:零样本、零样本CoT、少样本和手动CoT。

CoT的应用

CoT的应用涉及各种领域,包括算术、常识、符号推理、自然语言推理和问答。CoT提示为大型语言模型提供了解决这些领域复杂问题的能力。

算术推理

当与540B参数的语言模型一起使用时,思维链(CoT)提示在各种任务上的表现与针对特定任务微调的模型相当,包括算术推理。解决数学应用题对语言模型来说是一项具有挑战性的任务。

为了评估大型语言模型解决数学问题的能力,使用了两个基准测试:MultiArith和GSM8K。标准提示显示这些基准测试的扩展曲线相对平坦,这意味着增加模型大小并不会显著提高性能。然而,当使用CoT提示时,增加模型规模显著提高了性能,特别是对于大型模型。

PaLM(一个540B参数的语言模型)结合CoT提示,在GSM8K基准测试中达到了58%的最高性能。自一致性技术进一步提高了CoT提示的性能,在GSM8K上达到74%的准确率。CoT提示在数学应用题解决方面达到了最高水平,超过了微调的GPT-3基线。

常识推理

思维链提示也可以用于常识推理任务。这些任务需要基于一般知识对物理和人类互动进行推理。常识推理对当前的自然语言理解系统来说是具有挑战性的。

CoT提示在常识推理基准测试上进行了评估,如CommonsenseQA、StrategyQA、日期理解和体育理解。这些任务的性能通常随着模型规模的增加而提高。CoT提示比常规提示有小幅改进。CoT提示在提高体育理解任务的性能方面最为有效。

使用CoT的PaLM 540B在体育理解方面以95%对84%的分数超过了未经辅助的体育爱好者,在StrategyQA上以75.6%对69.4%的分数超过了先前的最高水平,在体育理解上以95.4%对84%的分数超过了先前的最高水平。但在CommonsenseQA(CSQA)上看到的改进很小。

符号推理

思维链提示使语言模型能够执行标准提示难以完成的符号推理任务。它还支持长度泛化,允许模型处理比少样本示例中看到的更长的推理时间输入。

在研究过程中,为了测试CoT提示,使用了两个玩具任务进行评估。第一个是最后字母连接,模型将名字中单词的最后字母连接起来。第二个是硬币翻转,模型确定在人们翻转硬币后,硬币是否仍然正面朝上。

使用域内和域外测试集来评估使用思维链提示(CoT)和标准提示的PaLM 540B在这两个任务上的表现。对于域内评估,示例的步骤数与训练/少样本示例相同。对于域外评估,示例的步骤数比示例中的多。

在域内评估中,使用CoT的PaLM 540B几乎达到100%的解决率。标准提示在域内和域外评估中都失败了。CoT提示导致性能提高,但低于域内评估。

问答

CoT提示通过将复杂问题或提示分解成一系列更简单的逻辑步骤来改进问答(QA)。这种方法帮助语言模型理解问题的结构和其组成部分之间的关系。每个步骤都专注于问题的一个特定方面,帮助模型更有效地识别相关信息。

CoT鼓励模型执行多跳推理,在这种推理中,它迭代地从不同来源或文档中收集和组合信息。这使模型能够执行改进的推理,并将单独的知识片段连接起来,得出准确的答案。

通过明确指定推理步骤,CoT提示可以帮助防止语言模型在回答复杂问题时可能引入的常见错误或偏见。此外,CoT提示允许用户理解模型是如何得出特定响应的。

思维链(CoT)与其他方法的比较

在这部分,我们深入比较思维链提示与其他方法,特别是标准提示和思维树提示。评估它们的优缺点可以为选择最适合你的业务应用的方法提供有价值的见解。

思维链vs标准提示

标准提示使用输入-输出对作为例子。这些对以问题和答案的形式呈现。模型根据这些对预测答案。它在有效处理多步推理任务方面有限制,但适合直接的任务,如单轮问答。它需要较少的计算资源。它通常使用单次提示进行训练,对于复杂任务往往需要更多数据来微调。标准提示可能不会随着模型规模的增加而显著提高性能。

而思维链提示涉及生成中间推理步骤。这些步骤在提供最终答案之前进行。它擅长复杂推理,使模型能够逐步思考。它versatile应用于广泛的需要复杂推理的任务。它需要对一系列提示进行训练,并有效利用数据进行多步推理。它在更大的模型上表现更好,因此需要更多的计算能力。它在复杂推理基准测试和需要多步问题解决的任务中表现出色。

MAWPS基准测试的比较:

长度泛化任务的比较:

对于直接的任务,你可以选择标准提示;对于需要深入、多步推理和可解释性的应用,思维链提示是更好的选择。GitHub上有一个与思维链推理相关的开源数据和工具库。它有各种任务的数据集,如数学问题和常识推理。它还有一个社区论坛供讨论。

思维链vs思维树提示

思维链遵循线性方法,每个新词或想法直接与前一个相连,形成一个链条。它代表了一种顺序的思维组织。

另一方面,思维树(ToT)采用层次方法。想法组织成树状结构,每个想法分支成多个相关想法。它代表了一种更复杂和分支的思维组织。

像GPT-3这样的思维链模型通常擅长在短跨度内生成连贯和与上下文相关的文本。像Transformer模型这样的思维树模型通常更擅长在更长的文本中保持连贯性,并且可以同时跟踪多个相关想法。

由于思维树的层次性,思维链模型在结构上更简单,计算强度也较低。此外,思维树引入了通过强化学习(RL)训练的"ToT控制器"概念。这个控制器可以潜在地从新数据或自我对弈中学习,允许思维树系统在固定语言模型的情况下进化和获取新知识。

思维链-SC(带有思维链的自一致性)使用简单的提示技术。它没有明确提到使用搜索算法。思维树采用广度优先搜索(BFS)和深度优先搜索(DFS)等搜索算法,以实现系统的思维探索。它将这些算法与树结构结合用于问题解决。因此,思维树的表现显著优于其他方法。

对于简单、较短的文本,你可以选择思维链;对于复杂、较长的文本和问题解决任务,思维树可能更合适。

本文翻译自该原文:
https://www.mercity.ai/blog-post/guide-to-chain-of-thought-prompting

提示词工程技术图谱-prompt engineering

提示词工程技术栈

提示词工程技术的不同方法和分类

无需大量训练的新任务(New Tasks Without Extensive Training)

  • 零样本提示(Zero-shot Prompting)
  • 少样本提示(Few-shot Prompting)
  • 连续链提示(Chain-of-Thought (CoT) Prompting)
  • 自动化连续链提示(Automatic Chain-of-Thought (Auto-CoT))
  • 自我一致性(Self-Consistency)
  • 逻辑链提示(Logical CoT (LogiCoT) Prompting)
  • 符号链提示(Chain-of-Symbol (CoS) Prompting)
  • 思维树提示(Tree-of-Thoughts (ToT) Prompting)
  • 思维图提示(Graph-of-Thought (GoT) Prompting)
  • 系统2注意力提示(System 2 Attention Prompting)
  • 思维线程提示(Thread of Thought (ThoT) Prompting)
  • 表格链提示(Chain of Table Prompting)

推理与逻辑(Reasoning and Logic)

  • 检索增强生成(Retrieval Augmented Generation (RAG))
  • 反应式提示(ReAct Prompting)
  • 验证链提示(Chain-of-Verification (CoVe) Prompting)
  • 注释链提示(Chain-of-Note (CoN) Prompting)
  • 知识链提示(Chain-of-Knowledge (CoK) Prompting)

减少幻觉(Reduce Hallucination)

  • 主动提示(Active-Prompt)

用户交互(User Interaction)

  • 自动提示工程师(Automatic Prompt Engineer (APE))
  • 自动化推理和工具使用(Automatic Reasoning and Tool-use (ART))

微调和优化(Fine-Tuning and Optimization)

– 对比连续链提示(Contrastive Chain-of-Thought Prompting (CCoT))

基于知识的推理和生成(Knowledge-Based Reasoning and Generation)

  • 情绪提示(Emotion Prompting)

提高一致性和连贯性(Improving Consistency and Coherence)

  • 抓取提示(Scratchpad Prompting)
  • 思维程序提示(Program of Thought (PoT) Prompting)

情绪和语气管理(Managing Emotions and Tone)

  • 程序化连续链提示(Structured Chain-of-Thought Prompting (SCoT))

代码生成和执行(Code Generation and Execution)

  • 代码链提示(Chain of Code (CoCo) Prompting)

优化和效率(Optimization and Efficiency)

  • 提示优化(Optimization by Prompting)

理解用户意图(Understanding User Intent)

  • 重述和响应提示(Rephrase and Respond Prompting)

元认知和自我反思(Metacognition and Self-Reflection)

  • 退一步思考提示(Take a Step Back Prompting)

如何使用Gemini的Golang API

如何使用Gemini的Golang API

在本文中,我们将讨论如何使用Gemini的Golang API来生成内容。我们会提供一个示例代码并详细解释每个部分的功能。

使用Gemini API前提条件

在开始之前,请确保您已经设置了Gemini API密钥,并将其作为环境变量GEMINI_API_KEY

Gemini API示例代码

以下是一个使用Gemini API的完整Golang示例:

package gemini

import (
    "context"
    "fmt"
    "os"

    "nuwa-engineer/pkg/llms"

    "github.com/google/generative-ai-go/genai"
    "google.golang.org/api/option"
)

// Gemini是Gemini API的包装器。
type Gemini struct {
    Client *genai.Client
    Model  *genai.GenerativeModel
}

// NewGemini返回一个新的Gemini客户端。
func NewGemini(ctx context.Context, modelName string) (llms.Model, error) {
    // 从环境变量中获取API密钥
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    if err != nil {
        return nil, fmt.Errorf("创建Gemini客户端失败: %w", err)
    }

    model := client.GenerativeModel(modelName)

    return &Gemini{
        Client: client,
        Model:  model,
    }, nil
}

// ContentToString将内容转换为字符串
func (g *Gemini) ContentToString(content *genai.Content) string {
    var str string
    for _, part := range content.Pparts {
        // 检查part是否是Text类型
        if _, ok := part.(genai.Text); ok {
            str += string(part.(genai.Text))
        }
    }
    return str
}

// GenerateContent根据提示生成内容。
func (g *Gemini) GenerateContent(ctx context.Context, prompt string) (string, error) {
    resp, err := g.Model.GenerateContent(ctx, genai.Text(prompt))
    if err != nil {
        return "", fmt.Errorf("生成内容失败: %w", err)
    }

    // 将响应转换为字符串
    return g.ContentToString(resp.Candidates[0].Content), nil
}

// 关闭客户端。
func (g *Gemini) CloseBackend() error {
    return g.Client.Close()
}

详细解释

包和依赖导入

首先,我们导入了需要的包和依赖:

import (
    "context"
    "fmt"
    "os"

    "nuwa-engineer/pkg/llms"

    "github.com/google/generative-ai-go/genai"
    "google.golang.org/api/option"
)

定义Gemini结构体

定义一个Gemini结构体来封装Gemini API客户端和模型:

type Gemini struct {
    Client *genai.Client
    Model  *genai.GenerativeModel
}

创建新的Gemini客户端

NewGemini函数用于创建一个新的Gemini客户端:

func NewGemini(ctx context.Context, modelName string) (llms.Model, error) {
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    if err != nil {
        return nil, fmt.Errorf("创建Gemini客户端失败: %w", err)
    }

    model := client.GenerativeModel(modelName)

    return &Gemini{
        Client: client,
        Model:  model,
    }, nil
}

将内容转换为字符串

ContentToString方法将genai.Content转换为字符串:

func (g *Gemini) ContentToString(content *genai.Content) string {
    var str string
    for _, part := range content.Parts {
        if _, ok := part.(genai.Text); ok {
            str += string(part.(genai.Text))
        }
    }
    return str
}

根据提示生成内容

GenerateContent方法根据给定的提示生成内容:

func (g *Gemini) GenerateContent(ctx context.Context, prompt string) (string, error) {
    resp, err := g.Model.GenerateContent(ctx, genai.Text(prompt))
    if err != nil {
        return "", fmt.Errorf("生成内容失败: %w", err)
    }

    return g.ContentToString(resp.Candidates[0].Content), nil
}

关闭客户端

CloseBackend方法用于关闭Gemini客户端:

func (g *Gemini) CloseBackend() error {
    return g.Client.Close()
}

Main 函数

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "your/package/path/gemini" // 替换为您的实际包路径
)

func main() {
    // 设置上下文
    ctx := context.Background()

    // 定义模型名称(替换为您实际使用的模型名称)
    modelName := "your-model-name"

    // 创建Gemini客户端
    client, err := gemini.NewGemini(ctx, modelName)
    if err != nil {
        log.Fatalf("创建Gemini客户端失败: %v", err)
    }
    defer func() {
        if err := client.CloseBackend(); err != nil {
            log.Fatalf("关闭Gemini客户端失败: %v", err)
        }
    }()

    // 定义提示
    prompt := "请生成一段关于人工智能的文章。"

    // 生成内容
    content, err := client.GenerateContent(ctx, prompt)
    if err != nil {
        log.Fatalf("生成内容失败: %v", err)
    }

    // 打印生成的内容
    fmt.Println("生成的内容:")
    fmt.Println(content)
}

Coze 如何自定义插件-获取公众号文章列表

Coze 如何自定义插件-获取公众号文章列表

关于Coze

毫无疑问,2023年是大模型元年,那么2024年,将会是LLM Agent应用爆发的一年。通过LLM agent 模式,AI 大模型将会释放自己的能力,助力更多的应用智能化。

Coze 平台是字节跳动开发的一款能够低代码创建AI agent的平台,无论你是否有编程经验,Coze 平台都能让你轻松创建各种聊天机器人,并将它们部署到不同的社交平台和消息应用中。该平台通过提供友好的界面和强大的功能,使得用户可以快速上手,开发出具有个性化和智能交互功能的机器人。简而言之,Coze 平台为聊天机器人的开发和应用提供了一个简单、高效、多功能的环境。

关于如何使用Coze,及了解更多的信息,可以阅读Coze 操作文档

本篇文章将主要聚焦于如何自定义Coze的工具(插件)。

创建Coze的插件

进入 Coze 主页

  • 1 选择个人空间
  • 2 选择插件
  • 3 点击创建插件按钮,进入创建插件界面。

根据上图:

  • 填写插件命名,可以使用中文。
  • 填写插件描述,简单描述插件的用途。
  • 选择在Coze IDE 中创建
  • 有两种编程语言可选,Node.js 和 Python3, 本实例使用python,因此选择Python3
  • 点击 确认

点击按钮 在IDE中创建工具

命名工具,必须以字母数字下划线格式命名,跟函数命名一致。
描写工具的用途。点击 确认

此时,你可以通过编程实现handler函数,来实现你的插件功能。
如果该工具需要自定义输入输出参数,则可通过元数据标签页,添加输入参数和输出参数。

分别使用输入参数和输出参数的编辑按钮,编辑输入参数和输出参数。
由于获取公众号文章时,公众号API需要使用公众号的appid和secret来获取访问资源的token,因此在此定义输入参数为appid和secret。
同时输出为公众号文章的列表,因此输出是一个数组,并且数组的每个item是一个对象,该对象具有如下字段:title,author,digest,url,如下图所示。

编辑完成后记得点击保存。然后切换到代码标签页。
由于公众号的API依赖于requests, 因此需要使用添加依赖,添加依赖的库。
添加依赖以后,就可以编程实现相应的功能,以下是获取公众号文章的代码。


from runtime import Args
from typings.GetArticleList.GetArticleList import Input, Output

import json
import requests

def get_stable_access_token(appid, secret, force_refresh=False):
    """
    获取稳定的访问令牌

    参数:
    appid (str):微信小程序的 appid
    secret (str):微信小程序的 secret
    force_refresh (bool):是否强制刷新令牌,默认为 False

    返回:
    dict:访问令牌的 JSON 数据
    """
    url = "https://api.weixin.qq.com/cgi-bin/stable_token"
    payload = {
        "grant_type": "client_credential",
        "appid": appid,
        "secret": secret,
        "force_refresh": force_refresh
    }
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    response = requests.post(url, headers=headers, data=bytes(json.dumps(payload), encoding='utf-8'))
    print(response)
    if response.status_code == 200:
        return response.json()
    else:
        response.raise_for_status()

def extract_info(articles):
    """
    提取文章列表中所有文章的信息

    Args:
        articles (dict):包含文章列表的 JSON 数据

    Returns:
        list:包含所有文章信息的列表,每个元素是一个字典
    """

    result = []
    if "item" in articles:
        for item in articles["item"]:
            if "content" in item and "news_item" in item["content"]:
                for news_item in item["content"]["news_item"]:
                    # 获取文章的标题、作者、摘要和 URL,如果没有则为空字符串
                    title = news_item.get("title", "")
                    author = news_item.get("author", "")
                    digest = news_item.get("digest", "")
                    url = news_item.get("url", "")
                    # 创建一个新的 JSON 对象来存储提取的信息
                    article = {
                        "title": title,
                        "author": author,
                        "digest": digest,
                        "url": url
                    }
                    result.append(article)
    return result

def get_published_articles(access_token, offset, count, no_content):
    """
    获取已发布的文章列表

    参数:
        access_token (str):调用接口的 access_token
        offset (int):要获取的文章列表的起始位置
        count (int):要获取的文章数量
        no_content (bool):是否返回文章内容

    返回:
        str:返回的文章列表的 JSON 字符串
    """
    url = f"https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token={access_token}"
    payload = {
        "offset": offset,
        "count": count,
        "no_content": no_content
    }
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    response = requests.post(url, headers=headers, data=json.dumps(payload))
    text = response.content.decode('utf-8')

    if response.status_code == 200:
        return text
    else:
        response.raise_for_status()

"""
Each file needs to export a function named <code>handler</code>. This function is the entrance to the Tool.

Parameters:
args: parameters of the entry function.
args.input - input parameters, you can get test input value by args.input.xxx.
args.logger - logger instance used to print logs, injected by runtime.

Remember to fill in input/output in Metadata, it helps LLM to recognize and use tool.

Return:
The return data of the function, which should match the declared output parameters.
"""
def handler(args: Args[Input])->Output:
    offset = 0
    count = 100
    no_content = 0

    appid = args.input.appid
    appsecret = args.input.appsecret

    access_token = get_stable_access_token(appid, appsecret)
    token = access_token['access_token']
    content = get_published_articles(token, offset, count, no_content)
    articles = json.loads(content)
    result = extract_info(articles)
    return result

运行测试时,输入以下参数,运行可以查看结果。

{
    "appid":"your appid",
    "appsecret":"your appsecret"
}

测试通过即可将你的插件进行发布

什么是AI智能体?

LLM 智能体

考虑一个旨在帮助金融分析师回答关于公司绩效的问题的大型语言模型(LLM)应用程序。通过一个设计良好的检索增强生成(RAG)管道,分析师可以回答类似于:“X公司2022财年的总收入是多少?”这样的问题。这些信息可以由经验丰富的分析师轻松地从财务报表中提取。

现在考虑一个问题,比如,“从2023财年第二季度的盈利电话会议中得出的三个要点是什么?重点关注公司正在构建的技术壁垒”。这是金融分析师想要回答以纳入其报告中的类型问题,但需要投入时间来回答。

我们如何开发一个解决方案来回答类似上述问题?很明显,这种信息需要更多的工作,而不仅仅是从盈利电话会议中查找。这种查询需要计划、定制焦点、记忆、使用不同工具,并将一个复杂问题分解为更简单的子部分。这些概念组合在一起基本上就是我们所谓的LLM智能体。

在这篇文章中,我介绍了由LLM提供动力的智能体,并讨论了智能体是什么以及企业应用的一些用例。有关更多信息,请参阅构建您的第一个智能体应用程序。在那篇文章中,我提供了一个生态系统概述,涵盖了构建AI智能体的可用框架以及一个入门指南,供任何尝试使用问答(Q&A)智能体的人使用。

什么是LLM智能体

虽然没有一个被广泛接受的LLM智能体的定义,但它们可以被描述为一个系统,可以使用LLM来推理问题,创建解决问题的计划,并在一组工具的帮助下执行计划。

简而言之,智能体是一个具有复杂推理能力、记忆和执行任务手段的系统。

这种能力最初是在项目中观察到的,比如AutoGPT或BabyAGI,在这些项目中,复杂的问题得到了解决,几乎没有干预。为了更详细地描述智能体,这里是一个LLM智能体应用程序的一般架构示意图(图1)。

一个智能体由以下关键组件组成(稍后会详细介绍):

  • 智能体核心
  • 记忆模块
  • 工具
  • 规划模块

智能体核心模块

智能体核心是管理智能体的核心逻辑和行为特征的中央协调模块。可以将其视为智能体的“关键决策模块”。在这里我们也定义了:

  • 智能体的总体目标:包含智能体的总体目标和目标。
  • 执行工具:基本上是智能体可以访问的所有工具的简要列表或“用户手册”。
  • 如何利用不同的规划模块:关于不同规划模块的效用以及在何种情况下使用哪个的详细说明。
  • 相关记忆:这是一个动态部分,在推理时填充与用户过去对话中最相关的记忆项。 “相关性”是根据用户提出的问题确定的。
  • 智能体的角色(可选):此角色描述通常用于偏好使用某些类型的工具或在智能体的最终响应中赋予典型的特殊性。

智能体的记忆模块

记忆模块在AI智能体中扮演着至关重要的角色。记忆模块基本上可以被看作是智能体的内部日志以及与用户的互动的存储库。

记忆模块有两种类型:

  • 短期记忆:智能体经历的行动和思考的记录,试图回答用户的单个问题:智能体的“思维线索”。
  • 长期记忆:关于用户和智能体之间发生的事件的行动和思考的记录。它是一个日志簿,包含了跨越数周或数月的对话历史。

记忆不仅需要基于语义相似性的检索。通常,复合分数由语义相似性、重要性、最近性和其他特定于应用程序的指标组成。它用于检索特定信息。

工具集

工具是经过明确定义的可执行工作流程,智能体可以使用它们来执行任务。通常情况下,它们可以被看作是专门的第三方API。

例如,智能体可以使用RAG管道生成上下文感知答案,使用代码解释器解决复杂的编程任务,使用API在互联网上搜索信息,甚至可以使用任何简单的API服务,比如天气API或即时消息应用程序的API。

规划模块

复杂问题,比如分析一组财务报告以回答一个分层业务问题,通常需要细致入微的方法。借助LLM动力智能体,可以通过以下两种技术的组合来处理这种复杂性:

  • 任务和问题分解
  • 反思或评论

问题分解

复合问题或推断信息需要某种形式的分解。举个例子,问题是:“NVIDIA最近的盈利电话会议中有哪三个要点?”

回答这个问题所需的信息不能直接从一个小时的会议记录中提取出来。然而,这个问题可以分解成多个问题主题:

  • “哪些技术转变被讨论得最多?”
  • “是否存在任何业务阻力?”
  • “财务结果如何?”

每个问题都可以进一步分解成子部分。也就是说,一个专业的AI智能体必须引导这种分解过程。

反思和评论

诸如ReAct、Reflexion、Chain of Thought和Graph of Thought之类的技术已经被用作基于评论或证据的提示框架。它们被广泛应用于改进LLM的推理能力和响应。这些技术也可以用于优化智能体生成的执行计划。

企业应用智能体

虽然智能体的应用几乎是无限的,但以下是一些可能对许多企业产生巨大影响的有趣案例:

  • “与您的数据交流”的智能体
  • 智能体群
  • 推荐和体验设计智能体
  • 定制的AI作者智能体
  • 多模式智能体

“与您的数据交流”的智能体

“与您的数据交流”并不是一个简单的问题。有很多挑战是一个直接的RAG管道无法解决的:

  • 源文档的语义相似性
  • 复杂的数据结构,比如表格
  • 缺乏明显的上下文(并非每个块都包含其来源的标记)
  • 用户提出的问题的复杂性

…等等

例如,回到之前的盈利电话会议记录示例(2023年第三季度 | 2024年第一季度)。你如何回答这个问题:“数据中心收入在2023年第三季度和2024年第一季度之间增长了多少?”为了回答这个问题,你基本上必须分别回答三个问题(即,我们需要一个规划模块):

  • 2023年第三季度数据中心收入是多少?
  • 2024年第一季度数据中心收入是多少?
  • 这两者之间有什么区别?

在这种情况下,你需要一个智能体,该智能体可以访问一个进行问题分解的规划模块(生成子问题并搜索答案,直到解决更大的问题),一个RAG管道(用作工具)来检索特定信息,以及记忆模块来准确处理子问题。在“LLM动力智能体:构建您的第一个智能体应用程序”一文中,我详细介绍了这种类型的案例。

智能体群

一群智能体可以被理解为一组智能体共同努力在单一环境中共存,并能相互合作解决问题。分散式的智能体生态系统非常类似于多个“智能”微服务协同解决问题。

像生成式智能体和ChatDev这样的多智能体环境在社区中非常受欢迎(图3)。为什么呢?像ChatDev这样的框架使您能够建立一个工程师、设计师、产品管理、首席执行官和智能体的团队,以低成本构建基本软件。像Brick Breaker或Flappy Bird这样的热门游戏甚至可以以50美分的低价进行原型设计!

通过一群智能体,您可以为数字公司、社区甚至整个城镇创建人口,用于行为模拟经济研究、企业营销活动、物理基础设施的用户体验等应用。

这些应用目前无法在没有大型语言模型的情况下进行模拟,并且在现实世界中运行非常昂贵。

推荐和体验设计的智能体

互联网运作依赖于推荐。由智能体驱动的对话推荐系统可用于打造个性化体验。

例如,考虑一个在电子商务网站上的人工智能智能体,它可以帮助您比较产品,并根据您的一般请求和选择提供建议。还可以构建完整的礼宾式体验,多个智能体协助最终用户在数字商店中导航。选择观看哪部电影或预订哪间酒店房间等体验可以构建为对话形式,而不仅仅是一系列决策树式的对话!

定制的AI作者智能体

另一个强大的工具是拥有一个个人AI作者,可以帮助您处理诸如共同撰写电子邮件或为您准备时间紧迫的会议和演示等任务。常规创作工具的问题在于不同类型的材料必须根据不同的受众进行定制。例如,投资者演讲必须与团队演示有所不同。

智能体可以利用您以前的工作。然后,您可以让智能体根据您的个人风格塑造智能体生成的演讲,并根据您的具体用例和需求定制工作。这个过程对于普通的LLM微调来说通常过于微妙。

多模态智能体

仅使用文本作为输入,您无法真正地“与数据交流”。通过构建能够处理各种输入的多模态智能体,例如图像和音频文件,可以增强所有提到的用例。

这只是解决企业挑战的几个方向的一些例子。数据整理、社交图和领域专业知识的智能体都是开发社区正在积极探索的企业应用领域。

请进一步学习

由LLM驱动的智能体与典型的聊天机器人应用有所不同,因为它们具有复杂的推理能力。智能体由一个智能体核心、记忆模块、工具集和规划模块组成,可以在各种企业环境中生成高度个性化的答案和内容,从数据整理到高级电子商务推荐系统。

要了解有关智能体周围技术生态系统的概述,如实现框架、必读论文、帖子和相关主题,请参阅《构建您的第一个智能体应用》。对问答智能体的无框架实现进行的步骤说明将帮助您更好地与您的数据交流。

要深入了解其他类型的LLM智能体,请参阅《构建一个LLM驱动的API智能体以执行任务》和《构建一个LLM驱动的数据智能体以进行数据分析》。

本位翻译自,感兴趣的话阅读原文:
https://developer.nvidia.com/blog/introduction-to-llm-agents/

本文系本站原创文章,著作版权属于作者,未经允许不得转载,如需转载或引用请注明出处或者联系作者。