当前位置:   article > 正文

【吴恩达deeplearning.ai】基于LangChain开发大语言应用模型(上)_openai.chatcompletion.create structured output par

openai.chatcompletion.create structured output parser

以下内容均整理来自deeplearning.ai的同名课程

Location 课程访问地址

DLAI - Learning Platform Beta (deeplearning.ai)

一、什么是LangChain

1、LangChain介绍

LangChain是一个框架,用于开发由大语言模型驱动的应用程序。开发者相信,最强大的、差异化的应用不仅会调用语言模型,而且还会具备以下原则:
数据感知:将语言模型与其他数据源连接起来。
代理性:允许语言模型与环境互动

LangChain支持python和javascript两种语言。专注于组合和模块化。
官方文档:https://python.langchain.com/en/latest/
中文文档:https://www.langchain.com.cn/

2、LangChain的模块化能力

包括大量的整合对话模型、聊天模型;提示词模板,输出分析器,示例选择器。

支持检索和调用其他数据源,包括不限于文本、数组,支持多个数据检索工具。

支持搭建对话链模板,按输入信息,自动生成标准化加工后的输出结果。

可调用多个预设或者自定义的算法和小工具。

二、模型、提示词和输出解析器Models, Prompts and Output Parsers

1、Prompt template提示词模板

通常来说,我们通过以下方式调用gpt

  1. def get_completion(prompt, model="gpt-3.5-turbo"):
  2. messages = [{"role": "user", "content": prompt}]
  3. response = openai.ChatCompletion.create(
  4. model=model,
  5. messages=messages,
  6. temperature=0,
  7. )
  8. return response.choices[0].message["content"]
  9. # 创建一个调用函数
  10. prompt = f"""Translate the text \
  11. that is delimited by triple backticks
  12. into a style that is {style}.
  13. text: ```{customer_email}```
  14. """
  15. # 编写提示语
  16. response = get_completion(prompt)
  17. #调用生成结果

现在看下langchain怎么基于模型进行调用

  1. from langchain.chat_models import ChatOpenAI
  2. chat = ChatOpenAI(temperature=0.0)
  3. # 加载langchain对话模型,并设置对话随机性为0
  4. template_string = """Translate the text \
  5. that is delimited by triple backticks \
  6. into a style that is {style}. \
  7. text: ```{text}```
  8. """
  9. # 设计模板信息
  10. from langchain.prompts import ChatPromptTemplate
  11. prompt_template = ChatPromptTemplate.from_template(template_string)
  12. # 加载提示语模板,载入模板信息
  13. customer_style = """American English \
  14. in a calm and respectful tone
  15. """
  16. customer_email = """
  17. Arrr, I be fuming that me blender lid \
  18. flew off and splattered me kitchen walls \
  19. with smoothie! And to make matters worse, \
  20. the warranty don't cover the cost of \
  21. cleaning up me kitchen. I need yer help \
  22. right now, matey!
  23. """
  24. # 定义模板中可变字段的变量信息
  25. customer_messages = prompt_template.format_messages(
  26. style=customer_style,
  27. text=customer_email)
  28. # 调用模板,对模板中的变量进行赋值,并生成最终提示语
  29. customer_response = chat(customer_messages)
  30. # 调用提示语,生成对话结果

通过“创建包含变量信息的提示词模板”,可以按照需求场景,灵活的通过改变变量信息,生成新的提示词。实现了模板的复用。
 

2、Output Parsers输出解析器

将大语言模型生成的结果,转换为特定结构的输出,如字典,数组等

  1. from langchain.output_parsers import ResponseSchema
  2. from langchain.output_parsers import StructuredOutputParser
  3. # 加载输出解析器
  4. gift_schema = ResponseSchema(name="gift",
  5. description="Was the item purchased\
  6. as a gift for someone else? \
  7. Answer True if yes,\
  8. False if not or unknown.")
  9. delivery_days_schema = ResponseSchema(name="delivery_days",
  10. description="How many days\
  11. did it take for the product\
  12. to arrive? If this \
  13. information is not found,\
  14. output -1.")
  15. price_value_schema = ResponseSchema(name="price_value",
  16. description="Extract any\
  17. sentences about the value or \
  18. price, and output them as a \
  19. comma separated Python list.")
  20. response_schemas = [gift_schema,
  21. delivery_days_schema,
  22. price_value_schema]
  23. # 创建一组解析规则
  24. output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
  25. format_instructions = output_parser.get_format_instructions()
  26. #编译解析规则
  27. review_template_2 = """\
  28. For the following text, extract the following information:
  29. gift: Was the item purchased as a gift for someone else? \
  30. Answer True if yes, False if not or unknown.
  31. delivery_days: How many days did it take for the product\
  32. to arrive? If this information is not found, output -1.
  33. price_value: Extract any sentences about the value or price,\
  34. and output them as a comma separated Python list.
  35. text: {text}
  36. {format_instructions}
  37. """
  38. # 创建一个提示词模板,将编译好的解析规则添加到模板中
  39. prompt = ChatPromptTemplate.from_template(template=review_template_2)
  40. messages = prompt.format_messages(text=customer_review,
  41. format_instructions=format_instructions)
  42. # 通过模板生成提示词信息
  43. response = chat(messages)
  44. # 生成结果
  45. output_dict = output_parser.parse(response.content)
  46. # 将生成结果存入字典中

三、Memory内存组件

大语言模型在通过接口调用过程中,并不会自动记忆历史问答/上下文(来进行回答)。而通过调用memory组件。langchain提供了多种记忆历史问答/上下文的方式。

Outline概要

  • ConversationBufferMemory
  • ConversationBufferWindowMemory
  • ConversationTokenBufferMemory
  • ConversationSummaryMemory

ConversationBufferMemory对话内存

  1. from langchain.chat_models import ChatOpenAI
  2. from langchain.chains import ConversationChain
  3. from langchain.memory import ConversationBufferMemory
  4. # 加载所需包
  5. llm = ChatOpenAI(temperature=0.0)
  6. memory = ConversationBufferMemory()
  7. conversation = ConversationChain(
  8. llm=llm,
  9. memory = memory,
  10. verbose=True
  11. )
  12. # 船创建一个对话,创建一个上下文储存区,创建一个链式沟通会话。
  13. conversation.predict(input="Hi, my name is Andrew")
  14. conversation.predict(input="What is 1+1?")
  15. conversation.predict(input="What is my name?")
  16. #在会话中添加会话内容,程序会自动将提问和回答一起保存到上下文储存区
  17. print(memory.buffer)
  18. memory.load_memory_variables({})
  19. #显示上下文储存区内保存的会话内容
  20. memory.save_context({"input": "Hi"},
  21. {"output": "What's up"})
  22. #直接对上下文储存区内的会话内容进行赋值(赋值内容为问答对)

ConversationBufferWindowMemory有限对话内存

  1. from langchain.memory import ConversationBufferWindowMemory
  2. # 加载组件
  3. memory = ConversationBufferWindowMemory(k=1)
  4. # 添加一个只有1空间的记忆内存
  5. memory.save_context({"input": "Hi"},
  6. {"output": "What's up"})
  7. memory.save_context({"input": "Not much, just hanging"},
  8. {"output": "Cool"})
  9. # 此时,上下文储存区里面,只有第二个对话的记忆,即在1空间情况下,程序只会记忆最新的1空间的问答记忆。

ConversationTokenBufferMemory有限词汇内存

  1. from langchain.memory import ConversationTokenBufferMemory
  2. from langchain.llms import OpenAI
  3. llm = ChatOpenAI(temperature=0.0)
  4. # 加载组件
  5. memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=30)
  6. # 创建一个只有30词汇大小的记忆空间(因为有限空间的判断也会用到大预言模型,所以需要加载llm)
  7. memory.save_context({"input": "AI is what?!"},
  8. {"output": "Amazing!"})
  9. memory.save_context({"input": "Backpropagation is what?"},
  10. {"output": "Beautiful!"})
  11. memory.save_context({"input": "Chatbots are what?"},
  12. {"output": "Charming!"})
  13. # 在这种情况下,程序只会保存不大于30个词汇的最新的问答,此时并不会强行保证问答都存在,仅包含答案也行。
  14. memory.load_memory_variables({})
  15. # 显示结果:{'history': 'AI: Beautiful!\nHuman: Chatbots are what?\nAI: Charming!'}

ConversationSummaryMemory总结式记忆内存

  1. from langchain.memory import ConversationSummaryBufferMemory
  2. # 加载包
  3. schedule = "There is a meeting at 8am with your product team. \
  4. You will need your powerpoint presentation prepared. \
  5. 9am-12pm have time to work on your LangChain \
  6. project which will go quickly because Langchain is such a powerful tool. \
  7. At Noon, lunch at the italian resturant with a customer who is driving \
  8. from over an hour away to meet you to understand the latest in AI. \
  9. Be sure to bring your laptop to show the latest LLM demo."
  10. # 一个长内容
  11. memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)
  12. # 创建一个最大词汇量为100的上下文总结式记忆空间(需要大预言模型进行总结,所以加载模型)
  13. memory.save_context({"input": "Hello"}, {"output": "What's up"})
  14. memory.save_context({"input": "Not much, just hanging"},
  15. {"output": "Cool"})
  16. memory.save_context({"input": "What is on the schedule today?"},
  17. {"output": f"{schedule}"})
  18. # 添加对话
  19. memory.load_memory_variables({})
  20. # 显示结果为总结后的内容,通过总结将记忆内容缩短到100个词汇以内:{'history': "System: The human and AI engage in small talk before discussing the day's schedule. The AI informs the human of a morning meeting with the product team, time to work on the LangChain project, and a lunch meeting with a customer interested in the latest AI developments."}
  21. conversation = ConversationChain(
  22. llm=llm,
  23. memory = memory,
  24. verbose=True
  25. )
  26. conversation.predict(input="What would be a good demo to show?")
  27. # 特别的,在对话中调用总结式记忆空间。会自动保存最新一段AI答的原文(不总结归纳)
  28. # 并把其他对话内容进行总结。这样做可能是为了更好的获取回答,最后一段AI答价值很大,不宜信息缩减。

三、Chains对话链

Outline

  • LLMChain
  • Sequential Chains
    • SimpleSequentialChain
    • SequentialChain
  • Router Chain

LLMChain基础链

  1. from langchain.chat_models import ChatOpenAI
  2. from langchain.prompts import ChatPromptTemplate
  3. from langchain.chains import LLMChain
  4. llm = ChatOpenAI(temperature=0.9)
  5. # 加载包
  6. prompt = ChatPromptTemplate.from_template(
  7. "What is the best name to describe \
  8. a company that makes {product}?"
  9. )
  10. # 创建一个待变量product的提示词
  11. chain = LLMChain(llm=llm, prompt=prompt)
  12. # 创建一个基础对话链
  13. product = "Queen Size Sheet Set"
  14. chain.run(product)
  15. # 提示词变量赋值,并获得回答

SimpleSequentialChain一般序列链

一般序列链可以将前一个链的输出结果,作为后一个链的输入。一般序列链有唯一输入和输出变量。

  1. from langchain.chains import SimpleSequentialChain
  2. llm = ChatOpenAI(temperature=0.9)
  3. # 加载包
  4. first_prompt = ChatPromptTemplate.from_template(
  5. "What is the best name to describe \
  6. a company that makes {product}?"
  7. )
  8. # 提示词模板1,变量为product
  9. chain_one = LLMChain(llm=llm, prompt=first_prompt)
  10. # 链1
  11. second_prompt = ChatPromptTemplate.from_template(
  12. "Write a 20 words description for the following \
  13. company:{company_name}"
  14. )
  15. # 提示词模板2,变量为company_name
  16. chain_two = LLMChain(llm=llm, prompt=second_prompt)
  17. # 链2
  18. overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],
  19. verbose=True)
  20. overall_simple_chain.run(product)
  21. # 组合链1、链2,获取结果

SequentialChain序列链

序列链中包含多个链,其中一些链的结果可以作为另一个链的输入。序列链可以支持多个输入和输出变量。

  1. from langchain.chains import SequentialChain
  2. llm = ChatOpenAI(temperature=0.9)
  3. # 加载
  4. first_prompt = ChatPromptTemplate.from_template(
  5. "Translate the following review to english:"
  6. "\n\n{Review}"
  7. chain_one = LLMChain(llm=llm, prompt=first_prompt,
  8. output_key="English_Review"
  9. )
  10. # 链1:输入Review,输出English_Review
  11. second_prompt = ChatPromptTemplate.from_template(
  12. "Can you summarize the following review in 1 sentence:"
  13. "\n\n{English_Review}"
  14. )
  15. chain_two = LLMChain(llm=llm, prompt=second_prompt,
  16. output_key="summary"
  17. )
  18. # 链2:输入English_Review,输出summary
  19. third_prompt = ChatPromptTemplate.from_template(
  20. "What language is the following review:\n\n{Review}"
  21. )
  22. chain_three = LLMChain(llm=llm, prompt=third_prompt,
  23. output_key="language"
  24. )
  25. # 链3:输入Review,输出language
  26. fourth_prompt = ChatPromptTemplate.from_template(
  27. "Write a follow up response to the following "
  28. "summary in the specified language:"
  29. "\n\nSummary: {summary}\n\nLanguage: {language}"
  30. )
  31. chain_four = LLMChain(llm=llm, prompt=fourth_prompt,
  32. output_key="followup_message"
  33. )
  34. # 链4:输入summary、language,输出followup_message
  35. overall_chain = SequentialChain(
  36. chains=[chain_one, chain_two, chain_three, chain_four],
  37. input_variables=["Review"],
  38. output_variables=["English_Review", "summary","followup_message"],
  39. verbose=True
  40. )
  41. # 构建完整链,输入Review,输出"English_Review", "summary","followup_message"
  42. overall_chain(review)

Router Chain路由链

路由链类似一个while else的函数,根据输入值,选择对应的路由(路径)进行后续的链路。整个路由链一般一个输入,一个输出。

 

  1. physics_template = """You are a very smart physics professor. \
  2. You are great at answering questions about physics in a concise\
  3. and easy to understand manner. \
  4. When you don't know the answer to a question you admit\
  5. that you don't know.
  6. Here is a question:
  7. {input}"""
  8. math_template = """You are a very good mathematician. \
  9. You are great at answering math questions. \
  10. You are so good because you are able to break down \
  11. hard problems into their component parts,
  12. answer the component parts, and then put them together\
  13. to answer the broader question.
  14. Here is a question:
  15. {input}"""
  16. history_template = """You are a very good historian. \
  17. You have an excellent knowledge of and understanding of people,\
  18. events and contexts from a range of historical periods. \
  19. You have the ability to think, reflect, debate, discuss and \
  20. evaluate the past. You have a respect for historical evidence\
  21. and the ability to make use of it to support your explanations \
  22. and judgements.
  23. Here is a question:
  24. {input}"""
  25. computerscience_template = """ You are a successful computer scientist.\
  26. You have a passion for creativity, collaboration,\
  27. forward-thinking, confidence, strong problem-solving capabilities,\
  28. understanding of theories and algorithms, and excellent communication \
  29. skills. You are great at answering coding questions. \
  30. You are so good because you know how to solve a problem by \
  31. describing the solution in imperative steps \
  32. that a machine can easily interpret and you know how to \
  33. choose a solution that has a good balance between \
  34. time complexity and space complexity.
  35. Here is a question:
  36. {input}"""
  37. # 创建4种提示词模板
  38. prompt_infos = [
  39. {
  40. "name": "physics",
  41. "description": "Good for answering questions about physics",
  42. "prompt_template": physics_template
  43. },
  44. {
  45. "name": "math",
  46. "description": "Good for answering math questions",
  47. "prompt_template": math_template
  48. },
  49. {
  50. "name": "History",
  51. "description": "Good for answering history questions",
  52. "prompt_template": history_template
  53. },
  54. {
  55. "name": "computer science",
  56. "description": "Good for answering computer science questions",
  57. "prompt_template": computerscience_template
  58. }
  59. ]
  60. # 提示词要点信息
  61. from langchain.chains.router import MultiPromptChain
  62. from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
  63. from langchain.prompts import PromptTemplate
  64. llm = ChatOpenAI(temperature=0)
  65. # 加载
  66. destination_chains = {}
  67. for p_info in prompt_infos:
  68. name = p_info["name"]
  69. prompt_template = p_info["prompt_template"]
  70. prompt = ChatPromptTemplate.from_template(template=prompt_template)
  71. chain = LLMChain(llm=llm, prompt=prompt)
  72. destination_chains[name] = chain
  73. destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
  74. destinations_str = "\n".join(destinations)
  75. # 根据提示词要点信息,生成4个链,存入destination中
  76. default_prompt = ChatPromptTemplate.from_template("{input}")
  77. default_chain = LLMChain(llm=llm, prompt=default_prompt)
  78. # 创建默认提示词和链
  79. MULTI_PROMPT_ROUTER_TEMPLATE = """Given a raw text input to a \
  80. language model select the model prompt best suited for the input. \
  81. You will be given the names of the available prompts and a \
  82. description of what the prompt is best suited for. \
  83. You may also revise the original input if you think that revising\
  84. it will ultimately lead to a better response from the language model.
  85. << FORMATTING >>
  86. Return a markdown code snippet with a JSON object formatted to look like:
  87. ```json
  88. {{{{
  89. "destination": string \ name of the prompt to use or "DEFAULT"
  90. "next_inputs": string \ a potentially modified version of the original input
  91. }}}}
  92. ```
  93. REMEMBER: "destination" MUST be one of the candidate prompt \
  94. names specified below OR it can be "DEFAULT" if the input is not\
  95. well suited for any of the candidate prompts.
  96. REMEMBER: "next_inputs" can just be the original input \
  97. if you don't think any modifications are needed.
  98. << CANDIDATE PROMPTS >>
  99. {destinations}
  100. << INPUT >>
  101. {{input}}
  102. << OUTPUT (remember to include the ```json)>>"""
  103. # 创建一个提示词模板,包含destination和input两个变量
  104. router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
  105. destinations=destinations_str
  106. )
  107. # 提示词模板赋值destination
  108. router_prompt = PromptTemplate(
  109. template=router_template,
  110. input_variables=["input"],
  111. output_parser=RouterOutputParser(),
  112. )
  113. # 提示词模板赋值
  114. router_chain = LLMRouterChain.from_llm(llm, router_prompt)
  115. chain = MultiPromptChain(router_chain=router_chain,
  116. destination_chains=destination_chains,
  117. default_chain=default_chain, verbose=True)
  118. # 生成路由链
  119. chain.run("xxx")

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/78034
推荐阅读
相关标签
  

闽ICP备14008679号