LangChain+通义千问+AnalyticDB向量引擎保姆级教程

阿里云开发者 发表于 1年以前  | 总阅读数:830 次

阿里妹导读
本文以构建AIGC落地应用ChatBot和构建AI Agent为例,从代码级别详细分享AI框架LangChain、阿里云通义大模型和AnalyticDB向量引擎的开发经验和最佳实践,给大家快速落地AIGC应用提供参考。

前言

9月13日,通义千问大模型已首批通过备案,并正式向公众开放。

通义模型具备的能力包括:

  1. 创作文字,如写故事、写公文、写邮件、写剧本、写诗歌等;
  2. 编写代码;
  3. 提供各类语言的翻译服务,如英语、日语、法语、西班牙语等;
  4. 进行文本润色和文本摘要等工作;
  5. 扮演角色进行对话;
  6. 制作图表等。

我们在可以登录通义千问官网体验的同时,也可以充分发挥想象力通过调用通义千问API的方式来构建属于自己的AI应用了。如果直接使用通义千问API从0到1来构建应用,技术成本还是相对比较高的。幸运的是,当前已经有非常优秀的框架LangChain来串联AIGC相关的各类组件,让我们轻松构建自己的应用。

由于业务上对客户支持的需要,我在几个月前已经在LangChain模块中添加了调用通义千问API的模块代码。在这个时间点,刚好可以直接拿来使用。

在过去的一段时间,已经有很多同学分享了LangChain的框架和原理,本文则从实际开发角度出发,以构建应用过程中遇到的问题,和我们实际遇到的客户案例出发,来详细讲解LangChain的代码,希望给大家在基于通义API构建应用入门时提供一些启发和思路。

本文主要包括几个部分:

1)LangChain的简单介绍 。 2)LangChain的源码解读,以通义千问API调用为例 。 3.)学习和构建一些基于不同Chain的小应用Demo,比如基于通义和向量数据库的ChatBot;构建每日金融资讯收集和分析的AI Agent。 4)如何提高大模型的问答准确率,比如如何更好地处理现有数据,如何使用思维链能力提升Agent的实际思考能力等。

LangChain是什么

LangChain是一个基于语言模型开发应用程序的框架。其通过串联开发应用需要的各个模块和组件,简化和加速程序的构建和开发。

LangChain模块

LLM模块 提供统一的大语言模型调用接口,屏蔽各种大语言模型因调用方式和实现细节的不同带来的开发复杂度。比如OpenAI和Tongyi模块。实现一个LLM模块需要实现LLM基类的call和generate接口。

class LLM(BaseLLM):
    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> str:
        """Run the LLM on the given prompt and input."""

  def _generate(
        self,
        prompts: List[str],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> LLMResult:
        """Run the LLM on the given prompt and input."""

Embedding模块 提供统一的embedding能力接口,与LLM一样,也提供不同的厂商实现,比如OpenAIEmbeddings,DashScopeEmbeddings。同样需要集成和实现Embeddings基类的两个方法embed_documents和embed_query。

class Embeddings(ABC):
    """Interface for embedding models."""

    @abstractmethod
    def embed_documents(self, texts: List[str]) -> List[List[float]]:
        """Embed search docs."""

    @abstractmethod
    def embed_query(self, text: str) -> List[float]:

VectorStore模块 向量存储模块,用于存储由Embedding模块生成的向量和生产向量的数据,主要作为记忆和检索模块向LLM提供服务。比如AnalytiDB VectorStore模块。实现VectorStore模块主要需要实现几个写入和查询接口。

class VectorStore(ABC):
    """Interface for vector store."""

    @abstractmethod
    def add_texts(
        self,
        texts: Iterable[str],
        metadatas: Optional[List[dict]] = None,
        **kwargs: Any,
    ) -> List[str]:


    def search(self, query: str, search_type: str, **kwargs: Any) -> List[Document]:

Chain模块 用于串联上面的这些模块,使得调用更加简单,让用户不需要关心繁琐的调用链路,在LangChain中已经集成了很多chain,最主要的就是LLMChain,在其内部根据不同的场景定义和使用了不同的PromptTemplate来达到目标。Agents模块 和chain类似,提供了丰富的agent模版,用于实现不同的agent,后面会详细介绍。

还有一些模块比如indexes,retrievers等都是上面这些模块的变种,以及提供一些可调用的工具类,比如tools等。这里就不再详细展开。我们会在后面的案例中讲解如何使用这些模块来构建自己的应用。

应用案例

构建ChatBot

ChatBot是LLM应用的一个比较典型的场景,这个场景又可以细分为问答助手(知识库),智能客服,Copilot等。比较典型的案例是LangChain-chatchat.构建ChatBot主要需要以下模块:TextSplitter一篇文档的内容往往篇幅较长,由于LLM和Embedding token限制,无法将其全部传给LLM,因此将需要存储的文档按照一定的规则切分成内聚的小块chunk进行存储。

LLM模块 用于总结问题和回答问题。

Embedding模块 用于生产知识和问题的向量表示。

VectorStore模块 用于存储和检索匹配的本地知识内容。

一个比较清晰的调用链路图如下(比较经典清晰,老图借用):

Example

基于通义API和ADB-PG向量数据库的ChatBot

首先我们从Google拉取一些问答数据,然后调用Dashscope上的Embedding模型进行向量化,并写入AnalyticDB PostgreSQL。

import os
import json
import wget
from langchain.vectorstores.analyticdb import AnalyticDB

CONNECTION_STRING = AnalyticDB.connection_string_from_db_params(
    driver=os.environ.get("PG_DRIVER", "psycopg2cffi"),
    host=os.environ.get("PG_HOST", "localhost"),
    port=int(os.environ.get("PG_PORT", "5432")),
    database=os.environ.get("PG_DATABASE", "postgres"),
    user=os.environ.get("PG_USER", "postgres"),
    password=os.environ.get("PG_PASSWORD", "postgres"),
)

# All the examples come from https://ai.google.com/research/NaturalQuestions
# This is a sample of the training set that we download and extract for some
# further processing.
wget.download("https://storage.googleapis.com/dataset-natural-questions/questions.json")
wget.download("https://storage.googleapis.com/dataset-natural-questions/answers.json")

# 导入数据
with open("questions.json", "r") as fp:
    questions = json.load(fp)

with open("answers.json", "r") as fp:
    answers = json.load(fp)


from langchain.vectorstores import AnalyticDB
from langchain.embeddings import DashScopeEmbeddings
from langchain import VectorDBQA, OpenAI

embeddings = DashScopeEmbeddings(
    model="text-embedding-v1", dashscope_api_key="your-dashscope-api-key"
)

doc_store = AnalyticDB.from_texts(
    texts=answers, embedding=embeddings, connection_string=CONNECTION_STRING,
    pre_delete_collection=True,
)

然后创建LangChain内集成的tongyi模块。

from langchain.chains import RetrievalQA
from langchain.llms import Tongyi

os.environ["DASHSCOPE_API_KEY"] = "your-dashscope-api-key"
llm = Tongyi()

查询和检索数据,然后回答问题。

from langchain.prompts import PromptTemplate
custom_prompt = """
Use the following pieces of context to answer the question at the end. Please provide
a short single-sentence summary answer only. If you don't know the answer or if it's
not present in given context, don't try to make up an answer, but suggest me a random
unrelated song title I could listen to.
Context: {context}
Question: {question}
Helpful Answer:
"""

custom_prompt_template = PromptTemplate(
    template=custom_prompt, input_variables=["context", "question"]

custom_qa = VectorDBQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    vectorstore=doc_store,
    return_source_documents=False,
    chain_type_kwargs={"prompt": custom_prompt_template},
)

random.seed(41)
for question in random.choices(questions, k=5):
    print(">", question)
    print(custom_qa.run(question), end="\n\n")
> what was uncle jesse's original last name on full house
Uncle Jesse's original last name on Full House was Cochran.

> when did the volcano erupt in indonesia 2018
No information about a volcano erupting in Indonesia in 2018 is present in the given context. Suggested song title: "Volcano" by U2.

> what does a dualist way of thinking mean
A dualist way of thinking means believing that humans possess a non-physical mind or soul which is distinct from their physical body.

> the first civil service commission in india was set up on the basis of recommendation of
The first Civil Service Commission in India was not set up on the basis of a recommendation.

> how old do you have to be to get a tattoo in utah
In Utah, you must be at least 18 years old to get a tattoo.

问题和挑战

在我们实际给用户提供构建一站式ChatBot的过程中,我们依然遇到了很多问题,比如文本切分过碎,导致语义丢失,文本包含图表,切分后导致段落无法被理解等。

  1. 文本切分器 向量的匹配度直接影响召回率,而向量的召回率又和内容本身以及问题紧密联系在一起,哪怕有一个很强大的embedding模型,如果文本切分本身做的不好,也无法达到用户的预期效果。比如LangChain本身提供的CharacterTextSplitter,其会根据标点符号和换行符等来切分段落,在一些多级标题的场景下,小标题会被切分成单独的chunk,与正文分割开,导致被切分的标题和正文都无法很内聚地表达需要表达的内容。
  2. 优化切分长度,过长的chunk会导致在召回后达到token限制,过小的chunk又可能丢失想要找到的关键信息。我们尝试过很多切分策略,发现如果不做深度的优化,将文本直接按照200-500个token长度来切分反而效果比较好。
  3. 召回优化1. 回溯上下文,在某些场景,我们能够准确地召回内容,但是这部分内容并不全,因此我们可以在写入时为chunk按照文章级别构建id,在召回时额外召回最相关chunk的相邻chunk,随后做拼接。
  4. 召回优化2. 构建标题树,在富文本场景,用户非常喜欢使用多级标题,有些文本内容在脱离标题之后就无法了解其究竟在说什么,这时我们可以通过构建内容标题树的方式来优化chunk.比如把chunk按照下面的方式构建。
#大标题1-中标题1-小标题1#:内容1
#大标题1-中标题1-小标题1#:内容2
#大标题1-中标题1-小标题2#:内容1
#大标题2-中标题1-小标题1#:内容1
  1. 双路召回,纯向量召回有时候会因为对专有名词的不理解导致无法召回相关内容,这时可以考虑使用向量和全文检索进行双路召回,在召回后再做精排去重。在全文检索时,我们可以通过额外增加自定义专有名词库和虚词屏蔽的方式来进一步优化召回效果。
  2. 问题优化,有时候用户的问题本身并不适合做向量匹配,这时我们可以根据聊天历史让模型来总结独立问题,来提升召回率,提高回答准确度。

虽然我们做了很多优化,但是由于用户的文档本身五花八门,现在依然无法找到一个完全通用的方案来应对所有的数据源.比如某一切分器在markdown场景表现很好,但是对于pdf就效果下降得厉害。比如有的用户还要求能够在召回文本的同时召回图片,视频甚至ppt的slice.目前我们也只是通过metadata link的方式召回相关内容,而不是把相关内容直接做向量化。如果有同学有很好的办法,欢迎在评论区交流。

构建AI Agent

以LLM构建AI Agent是大语言模型的另一个典型的应用场景。一些开源的非常火热的项目,如AutoGPT、BabyAGI都是非常典型的示例。让我们明白LLM的潜力不仅限于生成写作精彩的文本、故事、文章等;它可以被视为一个强大的自我决策的系统。用AI做决策存在一定的风险,但在一些简单,只是处理繁琐工作的场景,让AI代替人工决策是可取的。

Agent System组成

在以LLM为核心的自主代理系统中,LLM是Agent的大脑,我们还需要一些其他的组件来补全它的四肢。AI Agent主要借助思维链和思维树的思想,提高Agent的思考和决策能力。

Planning

planning的作用有两个:

  1. 进行子任务的设定和拆解: 实际生活中的任务往往是复杂的,需要将大任务分解为更小、可管理的子目标,从而能够有效处理复杂任务。
  2. 进行自我反思和迭代: 通过对过去的行动进行自我批评和反思,从错误中学习并为将来的步骤进行完善,从而提高最终结果的质量。

Memory

短期记忆:将所有上下文学习(参见提示工程)视为利用模型的短期记忆来学习。

长期记忆:这为代理提供了在长时间内保留和检索(无限)信息的能力,通常通过利用外部向量存储和快速检索来实现。

Tools

Tools模块可以让Agent调用外部API以获取模型权重中缺失的额外信息(通常在预训练后难以更改),包括实时信息、代码执行能力、访问专有信息源等。通常是通过设计API的方式让LLM调用执行。

Planning模块

一个复杂的任务通常包括许多步骤。代理需要知道这些步骤并提前规划。

任务拆解

思维链(Chain of thought) (CoT; Wei et al. 2022)已经成为提高模型在复杂任务上性能的标准提示技术。模型被指示“逐步思考”,以利用更多的测试时间计算来将困难任务分解成更小更简单的步骤。CoT将大任务转化为多个可管理的任务,并揭示了模型思考过程的解释。

思维树(Tree of Thoughts) (Yao et al. 2023) 通过在每一步探索多种推理可能性来扩展了CoT。它首先将问题分解为多个思维步骤,并在每一步生成多种思考,创建一个树状结构。搜索过程可以是广度优先搜索(BFS)或深度优先搜索(DFS),每个状态都由分类器(通过提示)或多数投票进行评估。

任务拆解可以通过以下方式完成:(1)LLM使用简单的提示,如“完成任务X需要a、b、c的步骤。\n1。”,“实现任务X的子目标是什么?”,(2)使用任务特定的指令;例如,“撰写文案大纲。”,或者(3)通过交互式输入指定需要操作的步骤。

自我反思(Self-Reflection)是一个非常重要的思想,它允许Agent通过改进过去的行动决策和纠正以前错误的方式来不断提高。在可以允许犯错和试错的现实任务中,它发挥着关键作用。比如写一段某个用途的脚本代码。

ReAct (Yao et al. 2023)通过将行动空间扩展为任务特定的离散行动和语言空间的组合,将推理和行动整合到LLM中。前者使LLM能够与环境互动(例如使用搜索引擎API),而后者促使LLM生成自然语言中的推理轨迹。

ReAct的prompt template包含了明确的步骤,供LLM思考,大致格式如下:

Thought: ...
Action: ...
Observation: ...
... (Repeated many times)

在对知识密集型任务和决策任务的两个实验中,ReAct都表现比仅包含行动(省略了“思考:…”步骤)更好的回答效果。

Memory模块

记忆可以定义为用于获取、存储、保留和以后检索信息的过程。对于人类大脑,有几种类型的记忆。

感觉记忆:这是记忆的最早阶段,它使我们能够在原始刺激结束后保留感觉信息(视觉、听觉等)的能力。感觉记忆通常只持续几秒钟。子类别包括图像记忆(视觉)、声音记忆(听觉)和触觉记忆(触觉)。

短期记忆(Short-Term Memory):它存储我们当前意识到的信息,需要执行复杂的认知任务,如学习和推理。短期记忆的容量被认为约为7个项目(Miller 1956),持续时间为20-30秒。

长期记忆(Long-Term Memory):长期记忆可以存储信息很长时间,范围从几天到数十年,具有本质上无限的存储容量。长期记忆有两个子类型:

显式/陈述性记忆:这是关于事实和事件的记忆,指的是那些可以有意识地回忆起来的记忆,包括情节记忆(事件和经历)和语义记忆(事实和概念)。

隐式/程序性记忆:这种记忆是无意识的,涉及自动执行的技能和例行程序,如骑自行车,在键盘上打字等。

我们可以粗略地考虑以下映射关系:

感觉记忆是为原始输入内容(包括文本、图像或其他模态),其可以在embedding之后作为输入。

短期记忆就像上下文内容,也就是聊天历史,它是短暂而有限的,因为受到Token长度的限制。

长期记忆就像Agent可以在查询时参考的外部向量存储,可以通过快速检索访问。

外部存储可以缓解有限注意力跨度的限制。一个标准的做法是将信息的嵌入表示保存到一个向量存储数据库中,该数据库可以支持快速的最大内积搜索(Maximum Inner Product Search)。为了优化检索速度,常见的选择是使用近似最近邻(ANN)算法,以返回近似的前k个最近邻,可以在略微损失一些准确性的情况下获得巨大的速度提升。对于相似性算法有兴趣的同学可以阅读这篇文章《ChatGPT都推荐的向量数据库,不仅仅是向量索引》。

Tool模块

使用工具可以使LLM完成一些其本身不能直接完成的事情。

Modular Reasoning, Knowledge and Language (Karpas et al. 2022)提出了一个MRKL系统,包含一组专家模块,通用的LLM作为路由器,将查询路由到最合适的专家模块。这些模块可以是其他模型(文生图,领域模型等)或功能模块(例如数学计算器、货币转换器、天气API)。现在最典型的方式就是使用ChatGPT的function call功能。通过对ChatGPT注册和描述接口的含义,就可以让ChatGPT帮我们调用对应的接口,返回正确的答案。

典型案例-AUTOGPT

autogpt通过类似下面的prompt可以成功完成一些复杂的任务,比如review开源项目的代码,给开源项目代码写注释。最近看到了Aone Copilot,其主要focus在代码补全和代码问答两个场景。那么如果我们可以调用Aone Copilot的API,是否也可以在我们推送mr之后,让agent帮我们完成一些代码风格,语法校验的代码review工作,和单元测试用例编写工作。

You are {{ai-name}}, {{user-provided AI bot description}}.
Your decisions must always be made independently without seeking user assistance. Play to your strengths as an LLM and pursue simple strategies with no legal complications.

GOALS:

1. {{user-provided goal 1}}
2. {{user-provided goal 2}}
3. ...
4. ...
5. ...

Constraints:
1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.
2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.
3. No user assistance
4. Exclusively use the commands listed in double quotes e.g. "command name"
5. Use subprocesses for commands that will not terminate within a few minutes

Commands:
1. Google Search: "google", args: "input": "<search>"
2. Browse Website: "browse_website", args: "url": "<url>", "question": "<what_you_want_to_find_on_website>"
3. Start GPT Agent: "start_agent", args: "name": "<name>", "task": "<short_task_desc>", "prompt": "<prompt>"
4. Message GPT Agent: "message_agent", args: "key": "<key>", "message": "<message>"
5. List GPT Agents: "list_agents", args:
6. Delete GPT Agent: "delete_agent", args: "key": "<key>"
7. Clone Repository: "clone_repository", args: "repository_url": "<url>", "clone_path": "<directory>"
8. Write to file: "write_to_file", args: "file": "<file>", "text": "<text>"
9. Read file: "read_file", args: "file": "<file>"
10. Append to file: "append_to_file", args: "file": "<file>", "text": "<text>"
11. Delete file: "delete_file", args: "file": "<file>"
12. Search Files: "search_files", args: "directory": "<directory>"
13. Analyze Code: "analyze_code", args: "code": "<full_code_string>"
14. Get Improved Code: "improve_code", args: "suggestions": "<list_of_suggestions>", "code": "<full_code_string>"
15. Write Tests: "write_tests", args: "code": "<full_code_string>", "focus": "<list_of_focus_areas>"
16. Execute Python File: "execute_python_file", args: "file": "<file>"
17. Generate Image: "generate_image", args: "prompt": "<prompt>"
18. Send Tweet: "send_tweet", args: "text": "<text>"
19. Do Nothing: "do_nothing", args:
20. Task Complete (Shutdown): "task_complete", args: "reason": "<reason>"

Resources:
1. Internet access for searches and information gathering.
2. Long Term memory management.
3. GPT-3.5 powered Agents for delegation of simple tasks.
4. File output.

Performance Evaluation:
1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.
2. Constructively self-criticize your big-picture behavior constantly.
3. Reflect on past decisions and strategies to refine your approach.
4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.

You should only respond in JSON format as described below
Response Format:
{
    "thoughts": {
        "text": "thought",
        "reasoning": "reasoning",
        "plan": "- short bulleted\n- list that conveys\n- long-term plan",
        "criticism": "constructive self-criticism",
        "speak": "thoughts summary to say to user"
    },
    "command": {
        "name": "command name",
        "args": {
            "arg name": "value"
        }
    }
}
Ensure the response can be parsed by Python json.loads

LangChain Agent模块

LangChain已经内置了很多agent实现的框架模块,主要包含:

agent_toolkits

这个模块目前是实验性的,其目的是为了模拟代替甚至超越ChatGPT plugin的能力,通过提供一系列的工具集提供链式调用,来让用户组装自己的workflow.比较典型的包括发送邮件功能, 执行python代码,执行用户提供的sql,调用zapier api等。

toolkits主要通过注册机制向agent返回一系列可以调用的tool。其基类代码为BaseToolkit。

class BaseToolkit(BaseModel, ABC):
    """Base Toolkit representing a collection of related tools."""

    @abstractmethod
    def get_tools(self) -> List[BaseTool]:
        """Get the tools in the toolkit."""

我们可以通过继承BaseToolkit的方式来实现不同的toolkit,每一个toolkit都会实现一系列的tools,一个Tool则包含几个部分,必须要包含的内容有name,description。通过这几个字段来告知LLM这个工具的作用和调用方法,这里就要求注册的tool最好能够通过name明确表达其用途,同时也可以在description中增加few-shot来做调用example,使得LLM能够更好地理解tool。同时在LangChain内部已经集成了很多工具,我们可以直接调用这些工具来组成Tools。

class BaseTool(BaseModel, Runnable[Union[str, Dict], Any]):
    name: str
    """The unique name of the tool that clearly communicates its purpose."""

    description: str
    """Used to tell the model how/when/why to use the tool.
    You can provide few-shot examples as a part of the description.
    """
    ...

class Tool(BaseTool):
    """Tool that takes in function or coroutine directly."""

    description: str = ""
    func: Optional[Callable[..., str]]
    """The function to run when the tool is called."""
Example1 Calculate Agent

接下来我们做一个简单的agent demo,这个agent主要做两件事情。1. 从网上检索收集问题需要的数据 2.利用收集到的数据进行科学计算,回答用户的问题。在这个流程中,我们主要用到Search和Calculator两个工具。

from langchain.agents import initialize_agent, AgentType, Tool
from langchain.chains import LLMMathChain
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
from langchain.utilities import SerpAPIWrapper
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613")
search = SerpAPIWrapper()
llm_math_chain = LLMMathChain.from_llm(llm=llm, verbose=True)

tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events. You should ask targeted questions"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    )
]

agent = initialize_agent(tools, llm, agent=AgentType.OPENAI_FUNCTIONS, verbose=True)

agent.run("Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?")

> Entering new  chain...
Invoking: `Search` with `{'query': 'Leo DiCaprio girlfriend'}`


Amidst his casual romance with Gigi, Leo allegedly entered a relationship with 19-year old model, Eden Polani, in February 2023.
Invoking: `Calculator` with `{'expression': '19^0.43'}`


> Entering new  chain...
19^0.43```text
19**0.43
```
...numexpr.evaluate("19**0.43")...

Answer: 3.547023357958959
> Finished chain.
Answer: 3.547023357958959Leo DiCaprio's girlfriend is reportedly Eden Polani. Her current age raised to the power of 0.43 is approximately 3.55.

> Finished chain.


"Leo DiCaprio's girlfriend is reportedly Eden Polani. Her current age raised to the power of 0.43 is approximately 3.55."

可以看到,这个agent可以成功地完成意图检索寻求知识和科学计算得到结果。

Example2 SQL Agent

这个case是结合大模型和数据库,通过查询表里的数据来回答用户问题,用的关键prompt为

_postgres_prompt = """You are a PostgreSQL expert. Given an input question, first create a syntactically correct PostgreSQL query to run, then look at the results of the query and return the answer to the input question.
Unless the user specifies in the question a specific number of examples to obtain, query for at most {top_k} results using the LIMIT clause as per PostgreSQL. You can order the results to return the most informative data in the database.
Never query for all columns from a table. You must query only the columns that are needed to answer the question. Wrap each column name in double quotes (") to denote them as delimited identifiers.
Pay attention to use only the column names you can see in the tables below. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.
Pay attention to use CURRENT_DATE function to get the current date, if the question involves "today".

Use the following format:

Question: Question here
SQLQuery: SQL Query to run
SQLResult: Result of the SQLQuery
Answer: Final answer here

"""

下面是实际的工作代码,目前在这个场景,openai的推理能力最强,能够正确完成这个复杂的Agent工作。


## export your openai key first export OPENAI_API_KEY=sk-xxxxx

from langchain.agents import create_sql_agent from langchain.agents.agent_toolkits import SQLDatabaseToolkit from langchain.agents import AgentExecutor from langchain.llms.tongyi import Tongyi

from langchain.sql_database import SQLDatabase import psycopg2cffi as psycopg2 # pip install psycopg-binary if on linux, just use psycopg2 from langchain.chat_models import ChatOpenAI

db = SQLDatabase.from_uri('postgresql+psycopg2cffi://admin:password123@localhost/admin')

llm = ChatOpenAI(model_name="gpt-3.5-turbo")

toolkit = SQLDatabaseToolkit(db=db,llm=llm)

agent_executor = create_sql_agent( llm=llm, toolkit=toolkit, verbose=True )

agent_executor.run("using the teachers table, find the first_name and last name of teachers who earn less the mean salary?")

可以看到大模型经过多轮思考,正确回答了我们的问题。

Entering new AgentExecutor chain...
Action: sql_db_list_tables
Action Input: ""
Observation: teachers
Thought:I can query the "teachers" table to find the first_name and last_name columns.
Action: sql_db_schema
Action Input: "teachers"
Observation: 
CREATE TABLE teachers (
        id INTEGER, 
        first_name VARCHAR(25), 
        last_name VARCHAR(50), 
        school VARCHAR(50), 
        hire_data DATE, 
        salary NUMERIC
)

/*
3 rows from teachers table:
id      first_name      last_name       school  hire_data       salary
None    Janet   Smith   F.D. Roosevelt HS       2011-10-30      36200
None    Lee     Reynolds        F.D. Roosevelt HS       1993-05-22      65000
None    Samuel  Cole    Myers Middle School     2005-08-01      43500
*/
Thought:I can now construct a query to find the first_name and last_name of teachers who earn less than the mean salary.
Action: sql_db_query
Action Input: "SELECT first_name, last_name FROM teachers WHERE salary < (SELECT AVG(salary) FROM teachers) LIMIT 10"
Observation: [('Janet', 'Smith'), ('Samuel', 'Cole'), ('Samantha', 'Bush'), ('Betty', 'Diaz'), ('Kathleen', 'Roush')]
Thought:Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-FDYSniIsv0FIQBi9p4P9Dinn on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-FDYSniIsv0FIQBi9p4P9Dinn on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-FDYSniIsv0FIQBi9p4P9Dinn on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-gpt-3.5-turbo in organization org-FDYSniIsv0FIQBi9p4P9Dinn on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
The first_name and last_name of teachers who earn less than the mean salary are Janet Smith, Samuel Cole, Samantha Bush, Betty Diaz, and Kathleen Roush.
Final Answer: Janet Smith, Samuel Cole, Samantha Bush, Betty Diaz, Kathleen Roush

> Finished chain.
'Janet Smith, Samuel Cole, Samantha Bush, Betty Diaz, Kathleen Roush'

问题和挑战

和ChatBot不同,agent的构建是对LLM的推理能力提出了更高的要求。ChatBot的回答可能是不正确的,但这依然可以通过人类的判别回馈来确定问答结果是否有益,对于无效的回答可以容忍地直接忽略或者重新回答。 但是agent对模型的错误判断的容忍度则更低。虽然我们可以通过自我反思机制减少agent的出错率,但是其当前可以应用的场景依然较小。需要我们不断去探索和开拓新的场景,同时不断提高大模型的推理能力,从而能够搭建更加复杂的agent。

同时,agent目前能够在比较小的场景胜任工作,比如我们的意图是明确的,同时也只给agent提供了比较少量的toolkit来执行任务(10个以内),且每个tool的用差异明显,在这种情况下,LLM能够正确选择tool进行任务,并得到期望的结果。但是当一个agent里注册了上百个甚至更多工具时,LLM就可能无法正确地选择tool执行操作了。这里的一个解法是通过多层agent树的方式来解决,父agent负责路由分发任务给不同的子agent。每一个子agent则仅仅包含和使用有限的toolkit来执行任务,从而提高agent复杂场景的任务完成率。

References

  • 通义千问 官网API文档:https://help.aliyun.com/zh/dashscope/developer-reference/api-details?spm=a2c4g.11186623.0.0.1ea416e9s2tYEJ
  • LangChain官方文档:https://python.langchain.com/docs/get_started/introduction
  • https://github.com/langchain-ai/langchain LangChain源码仓库
  • https://github.com/chatchat-space/Langchain-Chatchat LangChain优秀的中文大模型集成项目
  • OpenAI Cookbook 拥有很多使用LLM构建应用的优秀案例:https://github.com/openai/openai-cookbook
  • https://github.com/RGGH/OpenAI_SQL/blob/master/LangChain_01.ipynb ChatBI example source code
  • Zhao et al. “Calibrate Before Use: Improving Few-shot Performance of Language Models." ICML 2021:https://arxiv.org/abs/2102.09690
  • Yao et al. “ReAct: Synergizing reasoning and acting in language models." ICLR 2023.:https://arxiv.org/abs/2210.03629
  • Yao et al. “Tree of Thoughts: Dliberate Problem Solving with Large Language Models." arXiv preprint arXiv:2305.10601 (2023).:https://arxiv.org/abs/2305.10601
  • Liu et al. “Chain of Hindsight Aligns Language Models with Feedback “ arXiv preprint arXiv:2302.02676 (2023).:https://arxiv.org/abs/2302.02676
  • Zhang et al. “Automatic chain of thought prompting in large language models." arXiv preprint arXiv:2210.03493 (2022).:https://arxiv.org/abs/2210.03493
  • Schick et al. “Toolformer: Language Models Can Teach Themselves to Use Tools." arXiv preprint arXiv:2302.04761 (2023).:https://arxiv.org/abs/2302.04761
  • Yao et al. “Tree of Thoughts: Deliberate Problem Solving with Large Language Models." arXiv preprint arXiv:2305.10601 (2023).:https://arxiv.org/abs/2305.10601
  • https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/#chain-of-thought-cot
  • https://lilianweng.github.io/posts/2023-06-23-agent/ LLM使用优秀的博客文章

本文由微信公众号阿里云开发者原创,哈喽比特收录。
文章来源:https://mp.weixin.qq.com/s/GiOTpJOK5tr1Bat3R-Jbyg

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 目录