{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "# 🎇 LangChain\n", "\n", "\\[[English Version](./LangChainTutorial_en.ipynb)\\]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "如何打造我们自己专属的聊天机器人?如何通过简单的方式操控大语言模型(LLMs)从而学习到特定领域内的知识?如何在日常的工作流式中使用大模型激发更多的潜力?\n", ">请设想下面这几种场景:你拥有几本电子书,或几十个文本文件,抑或是利用数据库完成特定任务,我们想要LLMs模型学习用户给定的数据,并且只回答给定数据范围内的相关问题,如果问题超出范围,一律告知用户问题超出范围无法回答,也就是我们要限制LLMs模型自由发挥,不能让它随便乱说。如何基于大模型完成上述任务?LangChain可以帮你实现。点击👉[这里](https://python.langchain.com/en/latest/index.html)👈可以直接跳转到LangChain的官方文档说明。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "LangChain是一个大模型上层工具链,一个基于LLMs的应用程序开发框架, 通过可组合性来使用LLM构建应用程序. 其重点在于\"可组合性\"。设计一系列便于集成到实际应用中的接口,降低了在实际场景中部署大语言模型的难度。LangChain可用于聊天机器人、生成式问答(GQA)、文本摘要提取等。\n", "LangChain的目标在于:\n", " - 允许大语言模型处理不同来源的数据\n", " - 让大语言模型能和布置它的环境之间进行交互\n", "\n", "\n", "\n", "如上图所示,LangChain库主要包含六个部分:\n", "- **Models**: 提供基于OpenAI API封装好的大模型,包含常见的OpenAI大模型,也支持自定义大模型的封装。\n", "- **Prompt**: 支持自定义Prompt工程的快速实现以及和LLMs的对接。\n", "- **Index** 接受用户查询,索引最相关内容返回。\n", "- **Memory**: 标准的接口, 在chains/call之间保存状态。\n", "- **Chains**: 一系列的调用(LLMs或者其他, 如网络, 操作系统), Chains提供了标准的接口和设置来组合这些调用。 先从外部的源获取信息, 然后喂给LLMs。大模型针对一系列任务的顺序执行逻辑链。\n", "- **Agents**: 代理, 非常重要的一环, 关于对LLMs做何种action, 如何做。通常Utils中的能力、Chains中的各种逻辑链都会封装成一个个工具(Tools)供Agents进行智能化调用。\n", "\n", "🌟 我们将主要基于OpenAI提供商进行代码的说明与讲解,那么,我们就开始这个旅程吧!!!✊" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# 📜 文档目录结构\n", "\n", "- [Before Start](#before-start)\n", "- [Models](#models)\n", "- [Prompt](#prompt)\n", "- [Index](#index)\n", "- [Memory](#memory)\n", "- [Chains](#chains)\n", "- [Agents](#agents)\n", "- [Coding Examples](#coding-exampls)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Before Start\n", "\n", "环境配置和检查,设置代理是针对国内用户(只针对大陆,不涉及香港、澳门和台湾地区)使用OpenAI需要挂载VPN的问题,因此需要本地运行程序进行代理设置,从而避免网络原因导致的访问和调用问题。" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import os\n", "# 设置HTTP代理,本地IP地址以及端口号,查看IP可以通过Win/Linux下的IPCONFIG/IFCONFIG命令查看,也可以直接默认设置为127.0.0.1,端口要写挂载VPN的端口号。\n", "os.environ['HTTP_PROXY'] = 'http://127.0.0.1:XXX'\n", "# 设置HTTPS代理,同上\n", "os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:XXX'\n", "\n", "#检查代理是否有用\n", "def check_proxy():\n", " import urllib.request\n", " url = \"https://www.google.com\"\n", " # url = \"https://www.baidu.com\"\n", " filename = \"google.html\"\n", " urllib.request.urlretrieve(url, filename)#保存在当前文件夹下\n", "\n", "check_proxy()\n", "\n", "# openai的key\n", "os.environ[\"OPENAI_API_KEY\"] = \"填上你自己的openai api key\"\n", "\n", "#搜索api的key,仅在agent中使用,这步不是必要的\n", "os.environ['SERPAPI_API_KEY']='填上你自己的serpapi api key'" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "检查谷歌搜索API是否能用,这一步是非必要的可选步骤,如果你在下文的示例中有用到谷歌搜索API的,那就需要进行相应的注册才可以调用访问,注册网址点击👉[这里](https://serpapi.com/dashboard)👈" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'search_metadata': {'id': '643802169d158690e4963190', 'status': 'Success', 'json_endpoint': 'https://serpapi.com/searches/11aa25012aaee788/643802169d158690e4963190.json', 'created_at': '2023-04-13 13:22:30 UTC', 'processed_at': '2023-04-13 13:22:30 UTC', 'google_url': 'https://www.google.com/search?q=coffee&oq=coffee&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sourceid=chrome&ie=UTF-8', 'raw_html_file': 'https://serpapi.com/searches/11aa25012aaee788/643802169d158690e4963190.html', 'total_time_taken': 6.54}, 'search_parameters': {'engine': 'google', 'q': 'coffee', 'location_requested': 'Austin,Texas', 'location_used': 'Austin,TX,Texas,United States', 'google_domain': 'google.com', 'device': 'desktop'}, 'search_information': {'organic_results_state': 'Results for exact spelling', 'query_displayed': 'coffee', 'total_results': 4660000000, 'time_taken_displayed': 0.68, 'menu_items': [{'position': 1, 'title': 'Images', 'link': 'https://www.google.com/search?q=coffee&source=lnms&tbm=isch&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAC', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&tbm=isch'}, {'position': 2, 'title': 'Maps', 'link': 'https://maps.google.com/maps?q=coffee&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&um=1&ie=UTF-8&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAE'}, {'position': 3, 'title': 'Shopping', 'link': 'https://www.google.com/search?q=coffee&source=lnms&tbm=shop&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAG', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&tbm=shop'}, {'position': 4, 'title': 'Videos', 'link': 'https://www.google.com/search?q=coffee&source=lnms&tbm=vid&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAI', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&tbm=vid'}, {'position': 5, 'title': 'News', 'link': 'https://www.google.com/search?q=coffee&source=lnms&tbm=nws&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAK', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&tbm=nws'}, {'position': 6, 'title': 'Books', 'link': 'https://www.google.com/search?q=coffee&source=lnms&tbm=bks&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAM'}, {'position': 7, 'title': 'Flights', 'link': 'https://www.google.com/flights?q=coffee&source=lnms&tbm=flm&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAO'}, {'position': 8, 'title': 'Finance', 'link': 'https://www.google.com/finance?sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ0pQJegQIBRAQ'}]}, 'local_map': {'link': 'https://www.google.com/search?q=coffee&npsic=0&rflfq=1&rldoc=1&rllag=32070028,-99860352,38230&tbm=lcl&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQtgN6BAggEAE', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/2ceeb353df0a2b7dbacfb30245d6b608.png', 'gps_coordinates': {'latitude': 32.070028, 'longitude': -99.860352, 'altitude': 38230}}, 'local_results': {'places': [{'position': 1, 'title': 'Cup of Joe', 'rating': 4.6, 'reviews_original': '(28)', 'reviews': 28, 'type': 'Cafe', 'address': 'Winters, TX', 'description': '\"Great coffee at a good value\"', 'place_id': '6645020494937232090', 'place_id_search': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&ludocid=6645020494937232090&q=coffee', 'lsig': 'AB86z5WMhEZFuTAJ4GDnJFa6q6QI', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/0705f5877861a41dca5d37ea99dd97ef89f977fc0b365c8cf27ec04d7e618086c09b1b2ed1363660.jpeg', 'gps_coordinates': {'latitude': 31.957932, 'longitude': -99.96268}}, {'position': 2, 'title': 'The Coffee Haus on Main', 'rating': 4.8, 'reviews_original': '(36)', 'reviews': 36, 'type': 'Coffee shop', 'address': 'Ballinger, TX', 'place_id': '7920778704432590090', 'place_id_search': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&ludocid=7920778704432590090&q=coffee', 'lsig': 'AB86z5UZD5xj713sXU0khIy4IiH8', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/0705f5877861a41dca5d37ea99dd97ef0a78d9eb720337ce35a1440d44674901de89cb271256be32.jpeg', 'gps_coordinates': {'latitude': 31.737326, 'longitude': -99.94827}, 'service_options': {'dine_in': True, 'takeout': True, 'no_delivery': True}}, {'position': 3, 'title': 'Starbucks', 'rating': 4.1, 'reviews_original': '(899)', 'reviews': 899, 'price': '$$', 'type': 'Coffee shop', 'address': 'Abilene, TX', 'description': 'Iconic Seattle-based coffeehouse chain', 'place_id': '12667355487137518257', 'place_id_search': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&ludocid=12667355487137518257&q=coffee', 'lsig': 'AB86z5UP_UZ7Xmy5pKn1KyEN_jln', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/0705f5877861a41dca5d37ea99dd97efa22f666b4763d1bb8847ef0f5b7d937e6e1dbdec5b00b43d.jpeg', 'gps_coordinates': {'latitude': 32.40273, 'longitude': -99.75803}}], 'more_locations_link': 'https://www.google.com/search?tbs=lf:1,lf_ui:9&tbm=lcl&q=coffee&rflfq=1&num=10&uule=w+CAIQICIdQXVzdGluLFRYLFRleGFzLFVuaXRlZCBTdGF0ZXM&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQjGp6BAgjEAI'}, 'knowledge_graph': {'title': 'Coffee', 'type': 'Beverage', 'kgmid': '/m/02vqfm', 'knowledge_graph_search_link': 'https://www.google.com/search?kgmid=/m/02vqfm&hl=en-US&q=Coffee&kgs=b20ee92310a81805&shndl=0&source=sh/x/kp/1', 'serpapi_knowledge_graph_search_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&hl=en-US&kgmid=%2Fm%2F02vqfm&location=Austin%2CTexas&q=Coffee', 'header_images': [{'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199679b67c7e38cfee5d269be063747a036a99fba652bbfbf7afe.jpeg', 'source': 'https://en.wikipedia.org/wiki/Coffee'}, {'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199679b67c7e38cfee5d2494a19d1b8b89f6366a3aec97ea21ede.jpeg', 'source': 'https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/'}, {'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199679b67c7e38cfee5d2c856230e8a98377b70dca233c2119e9d.jpeg', 'source': 'https://www.rush.edu/news/health-benefits-coffee'}, {'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199679b67c7e38cfee5d255d27c8f4046047c96132e92d1c347c3.jpeg', 'source': 'https://www.healthline.com/nutrition/top-evidence-based-health-benefits-of-coffee'}, {'image': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfWpPUDBL9AWrANOJSorna-dMqhtYRtK8VhPYgoFfF3g&s', 'source': 'https://www.tastingtable.com/794355/different-types-of-coffee-explained/'}], 'description': 'Coffee is a beverage prepared from roasted coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans, primarily due to its caffeine content. It has the highest sales in the world market for hot drinks.', 'source': {'name': 'Wikipedia', 'link': 'https://en.wikipedia.org/wiki/Coffee'}, 'acidity_level': '4.85 to 5.10', 'acidity_level_links': [{'text': 'Acidity level', 'link': 'https://www.google.com/search?q=coffee+acidity+level&stick=H4sIAAAAAAAAAOPgE-LUz9U3MCorTMvVksjPttIvzsgvKklLTC6xSkzOTInPSS1LzVnEKpKcn5aWmqoAEsssqVQACwMA6FvyLz4AAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ6BMoAHoFCI8BEAI'}, {'text': 'healthline.com', 'link': 'https://www.healthline.com/nutrition/is-coffee-acidic'}], 'buttons': [{'text': 'Price', 'subtitle': 'Price Of Coffee', 'title': 'Two tablespoons', 'link': 'https://twochimpscoffee.com/guides/how-to-use-coffee-syrup/#:~:text=Two%20tablespoons%20(30ml%20or%20one,for%20a%20regular%20coffee%20cup.', 'displayed_link': 'https://twochimpscoffee.com › guides › how-to-use-coff...', 'snippet': \"Two tablespoons (30ml or one ounce) of syrup is a good go-to if you're wondering how much coffee syrup to put in coffee. This is for a regular coffee cup.\", 'snippet_highlighted_words': ['Two tablespoons (30ml or one ounce)'], 'answer': 'Two tablespoons', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199675fd122d14c827c9e3e8fed4a470f851e3e84adff4a23eb4f.png', 'search_link': 'https://www.google.com/search?q=price+of+coffee&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQrooIegUIjAEQBA', 'serpapi_search_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=price+of+coffee'}, {'text': 'Energy Amount', 'subtitle': 'How Many Calories In Coffee', 'table': [['Amount Per 1 fl oz (29.6 g)100 grams6 fl oz (178 g)1 cup (8 fl oz) (237 g)1 cup (8 fl oz) (237 g)'], ['Calories 1']], 'search_link': 'https://www.google.com/search?q=how+many+calories+in+coffee&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQrooIegUIjAEQCA', 'serpapi_search_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=how+many+calories+in+coffee'}, {'text': 'Protein Amount', 'subtitle': 'How Much Protein Is In Coffee', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQixTzjUfKnje6rtTLWUrleiMFyY4UusMCuTGsIgABnHjJ3&s', 'title': 'Protein Coffee: How it works & 8 benefits you should be aware of', 'link': 'https://healthcareweekly.com/protein-coffee-benefits/#:~:text=Is%20Coffee%20On%20Its%20Own,meaningful%2C%20to%20say%20the%20least.', 'displayed_link': 'https://healthcareweekly.com › protein-coffee-benefits', 'snippet': 'Is Coffee On Its Own a Good Source of Protein? The short answer: no, coffee is not a good source of protein. However, protein content depends on the type of coffee. For instance, one cup (about 6 fluid ounces) of black coffee contains approximately 0.21 grams of protein, which is not meaningful, to say the least.', 'snippet_highlighted_words': ['no, coffee is not a good source of protein'], 'search_link': 'https://www.google.com/search?q=how+much+protein+is+in+coffee&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQrooIegUIjAEQDg', 'serpapi_search_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=how+much+protein+is+in+coffee'}, {'text': 'Ph level', 'subtitle': 'Ph Of Coffee', 'title': 'about 5', 'link': 'https://byjus.com/question-answer/ph-of-black-coffee/#:~:text=Black%20coffee%20typically%20has%20a,beans%2C%20roasting%2C%20and%20brewing.', 'displayed_link': 'https://byjus.com › question-answer › ph-of-black-coffee', 'snippet': 'Black coffee typically has a pH of about 5 and is thus slightly acidic. It is acidic, with pH between 4 and 5, depending on the beans, roasting, and brewing.', 'snippet_highlighted_words': ['about 5'], 'answer': 'about 5', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba7199675fd122d14c827c9ec36fd87acab3f7ae25c98ca17a4aace0.png', 'search_link': 'https://www.google.com/search?q=ph+of+coffee&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQrooIegUIjAEQEg', 'serpapi_search_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=ph+of+coffee'}], 'compounds_in_coffee': [{'name': 'Chlorogenic acid', 'link': 'https://www.google.com/search?q=Chlorogenic+acid&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwL87IiddiWMQq4JyRk1-Un56al5mskJicmbKDlREA-TI5fCcAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiIARAF', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Chlorogenic+acid&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwL87IiddiWMQq4JyRk1-Un56al5mskJicmbKDlREA-TI5fCcAAAA', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967401e973bf2272dfc16e2c8cfafa7c4cc39c553489d2631b66274c812e7446727.png'}, {'name': 'Quinic acid', 'link': 'https://www.google.com/search?q=Quinic+acid&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwL042tdBiWMTKHViamZeZrJCYnJmyg5URAI7HIvkiAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiIARAH', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Quinic+acid&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwL042tdBiWMTKHViamZeZrJCYnJmyg5URAI7HIvkiAAAA', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967401e973bf2272dfc16e2c8cfafa7c4cc2362001c04c2f1d2044b09e83d185675.png'}, {'name': 'Trigonelline', 'link': 'https://www.google.com/search?q=Trigonelline&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwrTKojNdiWMTKE1KUmZ6fl5qTk5mXuoOVEQBGl_DeIwAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiIARAJ', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Trigonelline&stick=H4sIAAAAAAAAAONgFmJQ4tTP1TcwrTKojNdiWMTKE1KUmZ6fl5qTk5mXuoOVEQBGl_DeIwAAAA', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967401e973bf2272dfc16e2c8cfafa7c4cc8a99acca8218dd6ae69d6e62b343a898.png'}, {'name': 'Melanoidin', 'link': 'https://www.google.com/search?q=Melanoidin&stick=H4sIAAAAAAAAAONgFmJQ4tLP1TcwKso2M8zQYljEyuWbmpOYl5-Zkpm3g5URAEiv4kMiAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiIARAL', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Melanoidin&stick=H4sIAAAAAAAAAONgFmJQ4tLP1TcwKso2M8zQYljEyuWbmpOYl5-Zkpm3g5URAEiv4kMiAAAA', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967401e973bf2272dfc16e2c8cfafa7c4ccfcc2b1e8a30cf831eff946b2458c1940.png'}], 'compounds_in_coffee_link': 'https://www.google.com/search?q=compounds+in+coffee&stick=H4sIAAAAAAAAAONgFuLUz9U3MCorTMtVQjC1RLKTrfST83Nz8_OsUvLL88oTi1KKVzEKOmek5mYmJ-Y45-cW5JfmpRQvYhVOhrEVMvMUkvPT0lJTd7AyAgA94efZWwAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQMSgAegUIiAEQAQ', 'compounds_in_coffee_stick': 'H4sIAAAAAAAAAONgFuLUz9U3MCorTMtVQjC1RLKTrfST83Nz8_OsUvLL88oTi1KKVzEKOmek5mYmJ-Y45-cW5JfmpRQvYhVOhrEVMvMUkvPT0lJTd7AyAgA94efZWwAAAA', 'people_also_search_for': [{'name': 'Tea', 'link': 'https://www.google.com/search?q=Tea&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMgjPPDr-bVSwS7IwMGJZrTdb97oset9qkWSGGc8Wrx0cWPU0xfD2y8UwLcWHQST1bjafkmRjiQwYRe_3Itgz9qVSCKdZzbGbuLy9QXEb0Z8fNkExbIqMPt_n-TOdD4t0ZhyGHDkRXkCD3stHPYlkI9F6NqruSkOP8q19qSCJwA-F-iIzZCw4sk6NwHFknXQGz29sgmuriUCUg3JKKEr9yO6rD_j0gO7sFpA_vyMkVnlD2E-eVQ%3D%3D&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiJARAF', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Tea&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMgjPPDr-bVSwS7IwMGJZrTdb97oset9qkWSGGc8Wrx0cWPU0xfD2y8UwLcWHQST1bjafkmRjiQwYRe_3Itgz9qVSCKdZzbGbuLy9QXEb0Z8fNkExbIqMPt_n-TOdD4t0ZhyGHDkRXkCD3stHPYlkI9F6NqruSkOP8q19qSCJwA-F-iIzZCw4sk6NwHFknXQGz29sgmuriUCUg3JKKEr9yO6rD_j0gO7sFpA_vyMkVnlD2E-eVQ%3D%3D', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967e72d5e765855f08c845d5d1bff276fdeeaa0922bc08dd464936d4e065df28d61.jpeg'}, {'name': 'Espresso', 'link': 'https://www.google.com/search?q=Espresso&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMjyaN62njrr4Y2vVD-0W98vYZcIInyX3v-g5zZZpHjjG-Poxv3XLD0drTfOgpVcCf-zFRIPvsy9oT9UP_w35iIRi9Dl7PJ4-ldCIJDe667xhyIl72gjAFfOKZBu3XGinHDe096zuvjykLeb_xXU3DhU-1QmnhQUqLZaEFgHJmWWQuA0wE2cEjLHtjh10JWDgzqQv2KOWtaNv-dvOLwEiFloEH3I1N1rrm0NY4CZcMZcqugn660gEsBi5JGVH9mmfP4wv-CI%3D&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiJARAH', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Espresso&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMjyaN62njrr4Y2vVD-0W98vYZcIInyX3v-g5zZZpHjjG-Poxv3XLD0drTfOgpVcCf-zFRIPvsy9oT9UP_w35iIRi9Dl7PJ4-ldCIJDe667xhyIl72gjAFfOKZBu3XGinHDe096zuvjykLeb_xXU3DhU-1QmnhQUqLZaEFgHJmWWQuA0wE2cEjLHtjh10JWDgzqQv2KOWtaNv-dvOLwEiFloEH3I1N1rrm0NY4CZcMZcqugn660gEsBi5JGVH9mmfP4wv-CI%3D', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967e72d5e765855f08c845d5d1bff276fde5336e38b7da39c82f50576790ba2d2e1.jpeg'}, {'name': 'Cappuccino', 'link': 'https://www.google.com/search?q=Cappuccino&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMklZ6vtN6-8AY4RsUb9j1aMcn5_Fx0RVtguKTSjYOzJGH7WEnPl_82g6G4ZmQ47a0aQn5OaDfWitFqB1UyoD-3DPX9OrIzCD9nADAxnBhkOFxJrA8pSHWbkRwBQLlUjMBh218i1GQwoy1lyiRUKtITtVX99LqKB4Vnw74JG_9e88ZJr1WoMkOQoqE67xGs1BZHT4Q8YggMDNYAvtEZClZcNRxN3i715e-oP_ZO0WK7VtSx7RbP8PO9dSe9qaWJAVAfAFW7k%3D&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiJARAJ', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Cappuccino&si=AMnBZoFk_ppfOKgdccwTD_PVhdkg37dbl-p8zEtOPijkCaIHMklZ6vtN6-8AY4RsUb9j1aMcn5_Fx0RVtguKTSjYOzJGH7WEnPl_82g6G4ZmQ47a0aQn5OaDfWitFqB1UyoD-3DPX9OrIzCD9nADAxnBhkOFxJrA8pSHWbkRwBQLlUjMBh218i1GQwoy1lyiRUKtITtVX99LqKB4Vnw74JG_9e88ZJr1WoMkOQoqE67xGs1BZHT4Q8YggMDNYAvtEZClZcNRxN3i715e-oP_ZO0WK7VtSx7RbP8PO9dSe9qaWJAVAfAFW7k%3D', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967e72d5e765855f08c845d5d1bff276fde30bbff2f88cf8f3a124c859ded15a3a2.jpeg'}, {'name': 'Latte', 'link': 'https://www.google.com/search?q=Latte&si=AMnBZoEofOODruSEFWFjdccePwMH96ZlZt3bOiKSR9t4pqlu2E2Y95jVypGw5nHfEGbzdy_B-mJrk7TV3R0_l7ZUBiUkk1BiloRi17mH8ufqGqbkUhe0c8_KO5vzQNZ-nrEeAaA8my_qJpcAz8qE92rIWhWLdi2-Y-wRjvz59t6q5db5z6-tVBvk31oUge5WvKN_KY-abBJwuAmRcDVTFFkzJExr2ij50aEqL8xoQy48LtRLUoNcARf8G9RPDtEL8wYJDyK5-OlqfXP74-MHX3KmEH_oT5JEeAsCl9zNCisFeyvLawCXTaY%3D&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQxA16BQiJARAL', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=Latte&si=AMnBZoEofOODruSEFWFjdccePwMH96ZlZt3bOiKSR9t4pqlu2E2Y95jVypGw5nHfEGbzdy_B-mJrk7TV3R0_l7ZUBiUkk1BiloRi17mH8ufqGqbkUhe0c8_KO5vzQNZ-nrEeAaA8my_qJpcAz8qE92rIWhWLdi2-Y-wRjvz59t6q5db5z6-tVBvk31oUge5WvKN_KY-abBJwuAmRcDVTFFkzJExr2ij50aEqL8xoQy48LtRLUoNcARf8G9RPDtEL8wYJDyK5-OlqfXP74-MHX3KmEH_oT5JEeAsCl9zNCisFeyvLawCXTaY%3D', 'image': 'https://serpapi.com/searches/643802169d158690e4963190/images/56f3044ba4f6836a67196996ba719967e72d5e765855f08c845d5d1bff276fde3abe05036e61cb692c62b7db1ef7bd3f.jpeg'}], 'people_also_search_for_link': 'https://www.google.com/search?q=Coffee&stick=H4sIAAAAAAAAAONgFuLUz9U3MCorTMtVQjC1BIMzU1LLEyuL_VIrSoJLUguKF7GyOeenpaWm7mBlBABkIv_mNwAAAA&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQMSgAegUIiQEQAQ', 'people_also_search_for_stick': 'H4sIAAAAAAAAAONgFuLUz9U3MCorTMtVQjC1BIMzU1LLEyuL_VIrSoJLUguKF7GyOeenpaWm7mBlBABkIv_mNwAAAA', 'see_results_about': [{'name': 'Coffee bean', 'extensions': ['A coffee bean is a seed of the Coffea plant and the source for ...'], 'link': 'https://www.google.com/search?q=Coffee+bean&si=AMnBZoGn39e0tI_t2dCPKQ2j8QBKDHso0GZnCtfIMxO7bEcZSZ7sNGHzwtf8qdnwn3tXQ0AGsm2Ng73UcXfebGimZRXPLuphz7aw2b9GplBsHHhxGd0xEKJ8XvF1_wM5SNp0hs8oNfrzJQdeFjaOKy4f1Y1HsVo-vZbsVBt1pibEO5fKPf-Urjg%3D&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ6RN6BAhlEAE', 'image': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQlwgD-6s3Vk872C9OaOBm_9QUtkchzWBoJWCdLswp_BSHUV8pNHndshQ&s=0'}], 'list': {'total_fat': ['0 g', '0%'], 'saturated_fat': ['0 g', '0%'], 'trans_fat_regulation': ['0 g'], 'cholesterol': ['0 mg', '0%'], 'sodium': ['5 mg', '0%'], 'potassium': ['116 mg', '3%'], 'total_carbohydrate': ['0 g', '0%'], 'dietary_fiber': ['0 g', '0%'], 'sugar': ['0 g'], 'protein': ['0.3 g', '0%'], 'caffeine': ['95 mg'], 'vitamin_c': ['0%'], 'calcium': ['0%'], 'iron': ['0%'], 'vitamin_d': ['0%'], 'vitamin_b6': ['0%'], 'cobalamin': ['0%'], 'magnesium': ['1%']}}, 'inline_images': [{'link': 'https://www.google.com/search?q=coffee&tbm=isch&source=iu&ictx=1&vet=1&fir=cHhAmJrw8EtbWM%252CU6oJMnF-eeVTAM%252C%252Fm%252F02vqfm%253B9M1X2EDxsYNTZM%252CO0p2m8H_t7E6nM%252C_%253B35LBrLe6iLMgNM%252CLe_shlToZ2_z7M%252C_%253BYe55hwurmsyIDM%252Cr1UW6FGz3F41UM%252C_%253Be1xARNWS4v0NdM%252CxWwjaFHTd_fBIM%252C_&usg=AI4_-kSeRZX4tRmBDC5WzqJ72knpK80xKw&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ_B16BQiGARAB#imgrc=cHhAmJrw8EtbWM', 'source': 'https://en.wikipedia.org/wiki/Coffee', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/9965b78b2d80b21d3f5db41f337bfeec902227f017d9dd1735e3765fd889c51e.jpeg', 'original': 'https://upload.wikimedia.org/wikipedia/commons/e/e4/Latte_and_dark_coffee.jpg', 'title': 'upload.wikimedia.org/wikipedia/commons/e/e4/Latte_...', 'source_name': 'en.wikipedia.org'}, {'link': 'https://www.google.com/search?q=coffee&tbm=isch&source=iu&ictx=1&vet=1&fir=cHhAmJrw8EtbWM%252CU6oJMnF-eeVTAM%252C_%253B9M1X2EDxsYNTZM%252CO0p2m8H_t7E6nM%252C_%253B35LBrLe6iLMgNM%252CLe_shlToZ2_z7M%252C_%253BYe55hwurmsyIDM%252Cr1UW6FGz3F41UM%252C_%253Be1xARNWS4v0NdM%252CxWwjaFHTd_fBIM%252C_&usg=AI4_-kQVRu5edShja3G23xcn5YB3AJ_0Lg&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ_h16BQiHARAB#imgrc=9M1X2EDxsYNTZM', 'source': 'https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/9965b78b2d80b21d094f8ec1d3c2855e858ac1ef5bb628283bdffe67e0109546.jpeg', 'original': 'https://www.tastingtable.com/img/gallery/coffee-brands-ranked-from-worst-to-best/l-intro-1645231221.jpg', 'title': '31 Coffee Brands, Ranked From Worst To Best', 'source_name': 'Tasting Table'}, {'link': 'https://www.google.com/search?q=coffee&tbm=isch&source=iu&ictx=1&vet=1&fir=cHhAmJrw8EtbWM%252CU6oJMnF-eeVTAM%252C_%253B9M1X2EDxsYNTZM%252CO0p2m8H_t7E6nM%252C_%253B35LBrLe6iLMgNM%252CLe_shlToZ2_z7M%252C_%253BYe55hwurmsyIDM%252Cr1UW6FGz3F41UM%252C_%253Be1xARNWS4v0NdM%252CxWwjaFHTd_fBIM%252C_&usg=AI4_-kQVRu5edShja3G23xcn5YB3AJ_0Lg&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ_h16BQiFARAB#imgrc=35LBrLe6iLMgNM', 'source': 'https://www.rush.edu/news/health-benefits-coffee', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/9965b78b2d80b21d295a96d9e9320dc43b3ec3c1d728d8e2afa4eb919701e379.jpeg', 'original': 'https://www.rush.edu/sites/default/files/styles/386x217/public/media-images/Coffee_WebFeature.png?itok=gxteJ01c', 'title': 'Health Benefits of Coffee | Rush System', 'source_name': 'Rush University Medical Center'}, {'link': 'https://www.google.com/search?q=coffee&tbm=isch&source=iu&ictx=1&vet=1&fir=cHhAmJrw8EtbWM%252CU6oJMnF-eeVTAM%252C_%253B9M1X2EDxsYNTZM%252CO0p2m8H_t7E6nM%252C_%253B35LBrLe6iLMgNM%252CLe_shlToZ2_z7M%252C_%253BYe55hwurmsyIDM%252Cr1UW6FGz3F41UM%252C_%253Be1xARNWS4v0NdM%252CxWwjaFHTd_fBIM%252C_&usg=AI4_-kQVRu5edShja3G23xcn5YB3AJ_0Lg&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ_h16BQiEARAB#imgrc=Ye55hwurmsyIDM', 'source': 'https://www.healthline.com/nutrition/top-evidence-based-health-benefits-of-coffee', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/9965b78b2d80b21dc4a259fd912f9bcc346c5506f77fea62694c644a3ab00fa5.jpeg', 'original': 'https://post.healthline.com/wp-content/uploads/2020/08/coffee-worlds-biggest-source-of-antioxidants-1296x728-feature_0-732x549.jpg', 'title': '9 Health Benefits of Coffee, Based on Science', 'source_name': 'Healthline'}, {'link': 'https://www.google.com/search?q=coffee&tbm=isch&source=iu&ictx=1&vet=1&fir=cHhAmJrw8EtbWM%252CU6oJMnF-eeVTAM%252C_%253B9M1X2EDxsYNTZM%252CO0p2m8H_t7E6nM%252C_%253B35LBrLe6iLMgNM%252CLe_shlToZ2_z7M%252C_%253BYe55hwurmsyIDM%252Cr1UW6FGz3F41UM%252C_%253Be1xARNWS4v0NdM%252CxWwjaFHTd_fBIM%252C_&usg=AI4_-kQVRu5edShja3G23xcn5YB3AJ_0Lg&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ_h16BQiDARAB#imgrc=e1xARNWS4v0NdM', 'source': 'https://www.tastingtable.com/794355/different-types-of-coffee-explained/', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfWpPUDBL9AWrANOJSorna-dMqhtYRtK8VhPYgoFfF3g&s', 'original': 'https://www.tastingtable.com/img/gallery/20-different-types-of-coffee-explained/l-intro-1659544996.jpg', 'title': '35 Different Types Of Coffee Explained', 'source_name': 'Tasting Table'}], 'related_questions': [{'question': 'Is coffee good for health?', 'snippet': \"“For most people, moderate coffee consumption can be incorporated into a healthy diet.” Hu said that moderate coffee intake—about 2–5 cups a day—is linked to a lower likelihood of type 2 diabetes, heart disease, liver and endometrial cancers, Parkinson's disease, and depression.\", 'title': 'Is coffee good or bad for your health? | News', 'link': 'https://www.hsph.harvard.edu/news/hsph-in-the-news/is-coffee-good-or-bad-for-your-health/', 'displayed_link': 'https://www.hsph.harvard.edu › news › hsph-in-the-news', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/581680f060c7d368510705ded46f2c9ed01360eca462a179580c31dd0f6541e0.png', 'next_page_token': 'eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiSXMgY29mZmVlIGdvb2QgZm9yIGhlYWx0aD8iLCJsayI6IkdoNWtiMlZ6SUdOdlptWmxaU0JwY3lCbmIyOWtJR1p2Y2lCb1pXRnNkR2ciLCJicyI6ImMtT1M1NUx5TEZaSXprOUxTMDFWU01fUFQxRkl5eTlTeUVoTnpDbkpzSmU0WThDbHdDVWRucEdabktHUVZKU1lsd0pUbVZtc2tKUmFYR0l2TWR1UVM0VkxQandqc1VRaHNTaFZvU1FqVmNGRW9hU3lJTFZZSVQ4TnF0cGU0ZzA3bHlxWEFvcXFwTlM4MUxUTUVoUmxtLVVFR0FFIiwiaWQiOiJmY18xIn0=', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_related_questions&google_domain=google.com&next_page_token=eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiSXMgY29mZmVlIGdvb2QgZm9yIGhlYWx0aD8iLCJsayI6IkdoNWtiMlZ6SUdOdlptWmxaU0JwY3lCbmIyOWtJR1p2Y2lCb1pXRnNkR2ciLCJicyI6ImMtT1M1NUx5TEZaSXprOUxTMDFWU01fUFQxRkl5eTlTeUVoTnpDbkpzSmU0WThDbHdDVWRucEdabktHUVZKU1lsd0pUbVZtc2tKUmFYR0l2TWR1UVM0VkxQandqc1VRaHNTaFZvU1FqVmNGRW9hU3lJTFZZSVQ4TnF0cGU0ZzA3bHlxWEFvcXFwTlM4MUxUTUVoUmxtLVVFR0FFIiwiaWQiOiJmY18xIn0%3D'}, {'question': 'Which brand coffee is best?', 'title': 'List of Top 11 Coffee Brands in India', 'link': 'https://cashkaro.com/blog/best-coffee-brands/167279', 'list': ['Nescafe.', 'Rage Coffee.', 'Bru.', 'Davidoff.', 'Blue Tokai.', 'Starbucks.', 'Continental Coffee.', 'Country Bean.'], 'displayed_link': 'https://cashkaro.com › blog › best-coffee-brands', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4WFZ6iwvyFQiZ2wM5iLAEmFEfdSqje27fd4amMxSsFQ&s', 'next_page_token': 'eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hpY2ggYnJhbmQgY29mZmVlIGlzIGJlc3Q/IiwibGsiOiJHaHAzYUdsamFDQmljbUZ1WkNCamIyWm1aV1VnYVhNZ1ltVnpkQSIsImJzIjoiYy1PUzU1THlMRlpJems5TFMwMVZTTV9QVDFGSXl5OVN5RWhOekNuSnNKZTRZOENsd0NVZG5wR1puS0dRVkpTWWx3SlRtVm1za0pSYVhHSXZNZHVRUzRWTFBqd2pzVVFoc1NoVm9TUWpWY0ZFb2FTeUlMVllJVDhOcXRwZTRnMDdseXFYQW9xcXBOUzgxTFRNRWhSbG0tVUVHQUUiLCJpZCI6ImZjXzEifQ==', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_related_questions&google_domain=google.com&next_page_token=eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hpY2ggYnJhbmQgY29mZmVlIGlzIGJlc3Q%2FIiwibGsiOiJHaHAzYUdsamFDQmljbUZ1WkNCamIyWm1aV1VnYVhNZ1ltVnpkQSIsImJzIjoiYy1PUzU1THlMRlpJems5TFMwMVZTTV9QVDFGSXl5OVN5RWhOekNuSnNKZTRZOENsd0NVZG5wR1puS0dRVkpTWWx3SlRtVm1za0pSYVhHSXZNZHVRUzRWTFBqd2pzVVFoc1NoVm9TUWpWY0ZFb2FTeUlMVllJVDhOcXRwZTRnMDdseXFYQW9xcXBOUzgxTFRNRWhSbG0tVUVHQUUiLCJpZCI6ImZjXzEifQ%3D%3D'}, {'question': 'What are the 4 types of coffee?', 'snippet': 'There are 4 types of coffee bean. Arabica, Robusta, Excelsa and Liberica.', 'title': 'Coffee beans guide: Origin & different types | NESCAFÉ MENA', 'link': 'https://www.nescafe.com/mena/en-ae/understanding-coffee/coffee-beans-guide', 'displayed_link': 'https://www.nescafe.com › en-ae › understanding-coffee', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/581680f060c7d368510705ded46f2c9ec6ef6e60144d6ff6bcfe79a9b6526622.png', 'next_page_token': 'eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hhdCBhcmUgdGhlIDQgdHlwZXMgb2YgY29mZmVlPyIsImxrIjoiR2g1M2FHRjBJR0Z5WlNCMGFHVWdOQ0IwZVhCbGN5QnZaaUJqYjJabVpXVSIsImJzIjoiYy1PUzU1THlMRlpJems5TFMwMVZTTV9QVDFGSXl5OVN5RWhOekNuSnNKZTRZOENsd0NVZG5wR1puS0dRVkpTWWx3SlRtVm1za0pSYVhHSXZNZHVRUzRWTFBqd2pzVVFoc1NoVm9TUWpWY0ZFb2FTeUlMVllJVDhOcXRwZTRnMDdseXFYQW9xcXBOUzgxTFRNRWhSbG0tVUVHQUUiLCJpZCI6ImZjXzEifQ==', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_related_questions&google_domain=google.com&next_page_token=eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hhdCBhcmUgdGhlIDQgdHlwZXMgb2YgY29mZmVlPyIsImxrIjoiR2g1M2FHRjBJR0Z5WlNCMGFHVWdOQ0IwZVhCbGN5QnZaaUJqYjJabVpXVSIsImJzIjoiYy1PUzU1THlMRlpJems5TFMwMVZTTV9QVDFGSXl5OVN5RWhOekNuSnNKZTRZOENsd0NVZG5wR1puS0dRVkpTWWx3SlRtVm1za0pSYVhHSXZNZHVRUzRWTFBqd2pzVVFoc1NoVm9TUWpWY0ZFb2FTeUlMVllJVDhOcXRwZTRnMDdseXFYQW9xcXBOUzgxTFRNRWhSbG0tVUVHQUUiLCJpZCI6ImZjXzEifQ%3D%3D'}, {'question': 'What are the benefits of coffee?', 'title': 'Here are the top ways coffee can positively impact your health:', 'link': 'https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you', 'list': ['You could live longer. ... ', 'Your body may process glucose (or sugar) better. ... ', \"You're less likely to develop heart failure. ... \", \"You are less likely to develop Parkinson's disease. ... \", 'Your liver will thank you. ... ', 'Your DNA will be stronger.'], 'displayed_link': 'https://www.hopkinsmedicine.org › health › 9-reasons...', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSDV1_KHRKIUNXbIJYeb7G3jkEJsXv-MlZnSnAT4Qh-iw&s', 'next_page_token': 'eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hhdCBhcmUgdGhlIGJlbmVmaXRzIG9mIGNvZmZlZT8iLCJsayI6IkdoOTNhR0YwSUdGeVpTQjBhR1VnWW1WdVpXWnBkSE1nYjJZZ1kyOW1abVZsIiwiYnMiOiJjLU9TNTVMeUxGWkl6azlMUzAxVlNNX1BUMUZJeXk5U3lFaE56Q25Kc0plNFk4Q2x3Q1VkbnBHWm5LR1FWSlNZbHdKVG1WbXNrSlJhWEdJdk1kdVFTNFZMUGp3anNVUWhzU2hWb1NRalZjRkVvYVN5SUxWWUlUOE5xdHBlNGcwN2x5cVhBb3FxcE5TODFMVE1FaFJsbS1VRUdBRSIsImlkIjoiZmNfMSJ9', 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_related_questions&google_domain=google.com&next_page_token=eyJvbnMiOiIxMDA0MSIsImZjIjoiRW9zQkNreEJSWE0zYWs1UlIwTldTVTVvTTJ3NWJHMVRibXQzZEVod1JuZFdabEpMWm5ObExXSnNPSFZrYjJwbldFOHdMVXRmZG1OeVRFMWlWa3BPTlVSTWFtcGxMV3hRTkc0eVVtbHBMVTl4RWhkSGQwazBXazVITTBjMUxXRndkRkZRTW1ReU1uVkJSUm9pUVU4dE1ISnNOVzVIT0dKaWRWcEhRelJmVm1KVk0yRmlYekYwU1hSRE5teHdkdyIsImZjdiI6IjMiLCJlaSI6Ikd3STRaTkczRzUtYXB0UVAyZDIydUFFIiwicWMiOiJDZ1pqYjJabVpXVVFBSDFSTkMwXyIsInF1ZXN0aW9uIjoiV2hhdCBhcmUgdGhlIGJlbmVmaXRzIG9mIGNvZmZlZT8iLCJsayI6IkdoOTNhR0YwSUdGeVpTQjBhR1VnWW1WdVpXWnBkSE1nYjJZZ1kyOW1abVZsIiwiYnMiOiJjLU9TNTVMeUxGWkl6azlMUzAxVlNNX1BUMUZJeXk5U3lFaE56Q25Kc0plNFk4Q2x3Q1VkbnBHWm5LR1FWSlNZbHdKVG1WbXNrSlJhWEdJdk1kdVFTNFZMUGp3anNVUWhzU2hWb1NRalZjRkVvYVN5SUxWWUlUOE5xdHBlNGcwN2x5cVhBb3FxcE5TODFMVE1FaFJsbS1VRUdBRSIsImlkIjoiZmNfMSJ9'}], 'organic_results': [{'position': 1, 'title': 'Coffee', 'link': 'https://en.wikipedia.org/wiki/Coffee', 'displayed_link': 'https://en.wikipedia.org › wiki › Coffee', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a41370235e3abd98c1947069c6e9748089046bd.jpeg', 'snippet': 'Coffee is a beverage prepared from roasted coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans, ...', 'snippet_highlighted_words': ['Coffee', 'coffee', 'coffee'], 'sitelinks': {'inline': [{'title': 'List of countries by coffee...', 'link': 'https://en.wikipedia.org/wiki/List_of_countries_by_coffee_production'}, {'title': 'Coffee production', 'link': 'https://en.wikipedia.org/wiki/Coffee_production'}, {'title': 'Coffee preparation', 'link': 'https://en.wikipedia.org/wiki/Coffee_preparation'}, {'title': 'Brewed coffee', 'link': 'https://en.wikipedia.org/wiki/Brewed_coffee'}]}, 'rich_snippet': {'bottom': {'extensions': ['Region of origin: Kaffa in Horn of Africa\\u200e', 'Ingredients: Roasted coffee beans', 'Introduced: 15th century', 'Flavor: Distinctive, somewhat bitter'], 'detected_extensions': {'introduced_th_century': 15}}}, 'about_this_result': {'source': {'description': 'Wikipedia is a multilingual free online encyclopedia written and maintained by a community of volunteers, known as Wikipedians, through open collaboration and using a wiki-based editing system called MediaWiki. Wikipedia is the largest and most-read reference work in history.', 'source_info_link': 'https://en.wikipedia.org/wiki/Coffee', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a413702aa62bef54786db18713ef6486dccfb265a7385357ccdd522556c3f303ed26557.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://en.wikipedia.org/wiki/Coffee&tbm=ilp&ilps=ADJL0izANxNmAZazzpMAeGlkd2tXrw-aIQ', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0izANxNmAZazzpMAeGlkd2tXrw-aIQ&q=About+https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FCoffee', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:U6oJMnF-eeUJ:https://en.wikipedia.org/wiki/Coffee&cd=33&hl=en&ct=clnk&gl=us', 'related_pages_link': 'https://www.google.com/search?q=related:https://en.wikipedia.org/wiki/Coffee+coffee'}, {'position': 2, 'title': 'The Coffee Bean & Tea Leaf | CBTL', 'link': 'https://www.coffeebean.com/', 'displayed_link': 'https://www.coffeebean.com', 'snippet': 'Born and brewed in Southern California since 1963, The Coffee Bean & Tea Leaf® is passionate about connecting loyal customers with carefully handcrafted ...', 'snippet_highlighted_words': ['Coffee'], 'about_this_result': {'source': {'description': 'The Coffee Bean & Tea Leaf is an American coffee shop chain founded in 1963. Since 2019, it is a trade name of Ireland-based Super Magnificent Coffee Company Ireland Limited. Its 80% stake is by multinational company Jollibee Foods Corporation.', 'source_info_link': 'https://www.coffeebean.com/', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a41370236dec1b6bf726a3914d6a9d5028d25c59578b20700b175de3b92316a2e9db711.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.coffeebean.com/&tbm=ilp&ilps=ADJL0iyEMfWcc_F0sQp68evlFpMNONzA7w', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0iyEMfWcc_F0sQp68evlFpMNONzA7w&q=About+https%3A%2F%2Fwww.coffeebean.com%2F', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:WpQxSYo2c6AJ:https://www.coffeebean.com/&cd=34&hl=en&ct=clnk&gl=us', 'related_pages_link': 'https://www.google.com/search?q=related:https://www.coffeebean.com/+coffee'}, {'position': 3, 'title': 'What is Coffee?', 'link': 'https://www.ncausa.org/About-Coffee/What-is-Coffee', 'displayed_link': 'https://www.ncausa.org › About Coffee', 'snippet': 'cof·fee /ˈkôfē,ˈkäfē/ noun The berries harvested from species of Coffea plants. Everyone recognizes a roasted coffee bean, but you might not recognize an actual ...', 'snippet_highlighted_words': ['coffee'], 'about_this_result': {'source': {'description': 'The National Coffee Association or, is the main market research, consumer information, and lobbying association for the coffee industry in the United States.', 'source_info_link': 'https://www.ncausa.org/About-Coffee/What-is-Coffee', 'security': 'secure'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.ncausa.org/About-Coffee/What-is-Coffee&tbm=ilp&ilps=ADJL0ixxUUvfx6Ju5WRyyjiP05--z_0mTg', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0ixxUUvfx6Ju5WRyyjiP05--z_0mTg&q=About+https%3A%2F%2Fwww.ncausa.org%2FAbout-Coffee%2FWhat-is-Coffee', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:ENqpL6s3VPIJ:https://www.ncausa.org/About-Coffee/What-is-Coffee&cd=35&hl=en&ct=clnk&gl=us'}, {'position': 4, 'title': 'Coffee | Origin, Types, Uses, History, & Facts', 'link': 'https://www.britannica.com/topic/coffee', 'displayed_link': 'https://www.britannica.com › ... › Food', 'thumbnail': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a413702cdf1deddb67d451859d5294688e08a58.jpeg', 'date': 'Mar 22, 2023', 'snippet': 'coffee, beverage brewed from the roasted and ground seeds of the tropical evergreen coffee plants of African origin. Coffee is one of the ...', 'snippet_highlighted_words': ['coffee', 'coffee', 'Coffee'], 'rich_snippet': {'bottom': {'questions': ['What is coffee?', 'Where did coffee originate?']}}, 'about_this_result': {'source': {'description': 'britannica.com was first indexed by Google more than 10 years ago', 'source_info_link': 'https://www.britannica.com/topic/coffee', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a413702c76d8a9622e3a3b5b18646a9438a950d1c3d93c649733c1e50bf8159b64d21a1.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.britannica.com/topic/coffee&tbm=ilp&ilps=ADJL0ixB8MrWhyEfLpjZI0CfZRgB9XA7wQ', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0ixB8MrWhyEfLpjZI0CfZRgB9XA7wQ&q=About+https%3A%2F%2Fwww.britannica.com%2Ftopic%2Fcoffee', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:Wikbu4ipU28J:https://www.britannica.com/topic/coffee&cd=36&hl=en&ct=clnk&gl=us', 'related_pages_link': 'https://www.google.com/search?q=related:https://www.britannica.com/topic/coffee+coffee'}, {'position': 5, 'title': 'Coffee', 'link': 'https://www.amazon.com/coffee/s?k=coffee', 'displayed_link': 'https://www.amazon.com › coffee › k=coffee', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTX9ofuNsZqYoWn7Q955M3hXmXDY5UnwxG3LEpCMlpVyuH9d6XEpGSFfSRSoU-2AgxkvTs&s', 'snippet': \"The Original Donut Shop Regular, Single-Serve Keurig K-Cup Pods, Medium Roast Coffee Pods, 24 Count (Pack of 4) ... Chock Full o'Nuts Original Roast Ground Coffee ...\", 'snippet_highlighted_words': ['Coffee', 'Coffee'], 'images': ['https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTX9ofuNsZqYoWn7Q955M3hXmXDY5UnwxG3LEpCMlpVyuH9d6XEpGSFfSRSoU-2AgxkvTs&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHRrxTFVWH2fwyGJIwUzVkOHtqToQPGSVY3-Okffd-S2Ynzx5Cl2KTnrUunIMysfWPsns&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTPMicqxvC9FsqHIU5UmLz_gtZf2_VEsz2z7KeOGarDH639rrLKOTlOHCCpe-HiSbOFM5o&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS2fO2Mak3Y7USbiGvN4UdFgZXDn0DouDuRMgyUfPr29ANmsZGDk_zgeU_wsP6-E_9vN4c&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQZvUs5K8EeSa2U1SEwUNglwDYsb0NvxL8ZSyIHcghiIHx3o1byE_rBSzg31CuZnG-szA&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR1Qee1OmG2Yu9yS9AUYwfwAEzKH6oyYeSIqESDOSTidszlgdJOUezTH6OiszoBD5aZGBo&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJz-mmbLw9CbQzPjj7jHU5ZZetu-XJqb5POLfDrQlpHgD3Ky9Sd65QDTyY5kJ48LUmh7A&s', 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQIYAvQmQ_BbowG0CwmsnKm67ayf1kTWa0aueBTjjRzSvvLmrYoMCV6gZM30NJwMhA1mw&s'], 'rich_snippet': {'top': {'detected_extensions': {'free': 30}, 'extensions': ['Free 30', 'day returns']}}, 'about_this_result': {'source': {'description': 'Amazon.com, Inc. is an American multinational technology company focusing on e-commerce, cloud computing, online advertising, digital streaming, and artificial intelligence.', 'source_info_link': 'https://www.amazon.com/coffee/s?k=coffee', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a41370271de3cc16a260186c3b4cb3a7fd7c1ed2f6dcfc37c91066409b0b45459219d02.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.amazon.com/coffee/s?k%3Dcoffee&tbm=ilp&ilps=ADJL0iz4yaPjFE5YbA0TnbXqmN1j8Qqr0g', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0iz4yaPjFE5YbA0TnbXqmN1j8Qqr0g&q=About+https%3A%2F%2Fwww.amazon.com%2Fcoffee%2Fs%3Fk%3Dcoffee', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:wfQ5Et9Ni-kJ:https://www.amazon.com/coffee/s%3Fk%3Dcoffee&cd=37&hl=en&ct=clnk&gl=us'}, {'position': 6, 'title': 'Coffee | The Nutrition Source | Harvard T.H. Chan School of ...', 'link': 'https://www.hsph.harvard.edu/nutritionsource/food-features/coffee/', 'displayed_link': 'https://www.hsph.harvard.edu › ... › Food Features', 'snippet': 'Coffee beans are the seeds of a fruit called a coffee cherry. Coffee cherries grow on coffee trees from a genus of plants called Coffea. There are a wide ...', 'snippet_highlighted_words': ['Coffee', 'coffee', 'Coffee', 'coffee'], 'about_this_result': {'source': {'description': 'The Harvard T.H. Chan School of Public Health is the public health school of Harvard University, located in the Longwood Medical Area of Boston, Massachusetts.', 'source_info_link': 'https://www.hsph.harvard.edu/nutritionsource/food-features/coffee/', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a4137026dbd26df06a2dbaf014d13f33e6a3b6a920533e702cc436894e9cb1a14359630.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.hsph.harvard.edu/nutritionsource/food-features/coffee/&tbm=ilp&ilps=ADJL0ix24UjkA35TUhg8KpNFoGqXA4X1pg', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0ix24UjkA35TUhg8KpNFoGqXA4X1pg&q=About+https%3A%2F%2Fwww.hsph.harvard.edu%2Fnutritionsource%2Ffood-features%2Fcoffee%2F', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:aCQFR0EWgPwJ:https://www.hsph.harvard.edu/nutritionsource/food-features/coffee/&cd=38&hl=en&ct=clnk&gl=us'}, {'position': 7, 'title': \"Peet's Coffee: The Original Craft Coffee\", 'link': 'https://www.peets.com/', 'displayed_link': 'https://www.peets.com', 'snippet': \"Since 1966, Peet's Coffee has offered superior coffees and teas by sourcing the best quality coffee beans and tea leaves in the world and adhering to strict ...\", 'snippet_highlighted_words': ['Coffee', 'coffees', 'coffee'], 'about_this_result': {'source': {'description': \"Peet's Coffee is a San Francisco Bay Area-based specialty coffee roaster and retailer owned by JAB Holding Company via JDE Peet's.\", 'source_info_link': 'https://www.peets.com/', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a4137024be2581d9638efd0771f573c952f60c8149f094c13f4611da3180decb846ea6a.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.peets.com/&tbm=ilp&ilps=ADJL0iyi0Ke6jkQwj42VpDqECgl1WRdfeQ', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0iyi0Ke6jkQwj42VpDqECgl1WRdfeQ&q=About+https%3A%2F%2Fwww.peets.com%2F', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:BCjzno6zP6wJ:https://www.peets.com/&cd=39&hl=en&ct=clnk&gl=us', 'related_pages_link': 'https://www.google.com/search?q=related:https://www.peets.com/+coffee'}, {'position': 8, 'title': '31 Coffee Brands, Ranked From Worst To Best', 'link': 'https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/', 'displayed_link': 'https://www.tastingtable.com › coffee-brands-ranked-f...', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJbKwc_XPeJDMpYB72QQ9gDtxMu3fnuYp3dVPBKNRH58VXOyFxTPIK&usqp=CAE&s', 'date': 'Mar 2, 2023', 'snippet': \"From café chains to retail roasters, we've ranked some of the most popular coffee brands from worst to first.\", 'snippet_highlighted_words': ['coffee'], 'about_this_result': {'source': {'description': \"Tasting Table is a digital media company focused on food and drink. The brand's website and email newsletter report on food and drink trends in the categories of dining, wine, cocktails, cooking and food travel.\", 'source_info_link': 'https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a41370255d9fd38631e86b30b8ba5a6270a8f8f8d3fdf473f4298db2e8f3de80302c3c1.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/&tbm=ilp&ilps=ADJL0iwgbb7uiNB1U30anBQOfSid1twx2w', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0iwgbb7uiNB1U30anBQOfSid1twx2w&q=About+https%3A%2F%2Fwww.tastingtable.com%2F718678%2Fcoffee-brands-ranked-from-worst-to-best%2F', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:O0p2m8H_t7EJ:https://www.tastingtable.com/718678/coffee-brands-ranked-from-worst-to-best/&cd=40&hl=en&ct=clnk&gl=us'}, {'position': 9, 'title': 'Starbucks Coffee Company', 'link': 'https://www.starbucks.com/', 'displayed_link': 'https://www.starbucks.com', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUIjRcZRdCIqaOwWV7l1lcn8E-1M1YZNoG2_Kh_UJ8snRuD8oenfX-&usqp=CAE&s', 'snippet': 'More than just great coffee. Explore the menu, sign up for Starbucks® Rewards, manage your gift card and more.', 'snippet_highlighted_words': ['coffee'], 'about_this_result': {'source': {'description': \"Starbucks Corporation is an American multinational chain of coffeehouses and roastery reserves headquartered in Seattle, Washington. It is the world's largest coffeehouse chain.\\nAs of November 2021, the company had 33,833 stores in 80 countries, 15,444 of which were located in the United States.\", 'source_info_link': 'https://www.starbucks.com/', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a41370201fd9153a994c33cca23ce212f7b632caa714a5c58d1a195fdcc3b69b71b230c.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.starbucks.com/&tbm=ilp&ilps=ADJL0iz2L53LZLU_48M30C3XaAwABDTi8g', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0iz2L53LZLU_48M30C3XaAwABDTi8g&q=About+https%3A%2F%2Fwww.starbucks.com%2F', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:1vGXgo_FlHkJ:https://www.starbucks.com/&cd=41&hl=en&ct=clnk&gl=us', 'related_pages_link': 'https://www.google.com/search?q=related:https://www.starbucks.com/+coffee'}, {'position': 10, 'title': '9 Reasons Why (the Right Amount of) Coffee Is Good for You', 'link': 'https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you', 'displayed_link': 'https://www.hopkinsmedicine.org › health › 9-reasons...', 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRsnUcaHtehFB7MvyuymVeeL7PLkII_xVLL_v6YkOtwxYZV-rzP0RBL&usqp=CAE&s', 'snippet': 'But coffee also contains antioxidants and other active substances that may reduce internal inflammation and protect against disease, say nutrition experts from ...', 'snippet_highlighted_words': ['coffee'], 'about_this_result': {'source': {'description': 'hopkinsmedicine.org was first indexed by Google more than 10 years ago', 'source_info_link': 'https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you', 'security': 'secure', 'icon': 'https://serpapi.com/searches/643802169d158690e4963190/images/f8a7b34e2b85a11c15dcd57b4a413702a84bcbfb2440423ae0a0c5fb59f87e224f8c64115e43db3dd8cb98600b9b54aa.png'}}, 'about_page_link': 'https://www.google.com/search?q=About+https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you&tbm=ilp&ilps=ADJL0izDwqyqs6boUzNyhlVyPUkW3-dJ3Q', 'about_page_serpapi_link': 'https://serpapi.com/search.json?engine=google_about_this_result&google_domain=google.com&ilps=ADJL0izDwqyqs6boUzNyhlVyPUkW3-dJ3Q&q=About+https%3A%2F%2Fwww.hopkinsmedicine.org%2Fhealth%2Fwellness-and-prevention%2F9-reasons-why-the-right-amount-of-coffee-is-good-for-you', 'cached_page_link': 'https://webcache.googleusercontent.com/search?q=cache:MdKXyZO_8uQJ:https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you&cd=42&hl=en&ct=clnk&gl=us'}], 'related_searches': [{'query': 'coffee near me', 'link': 'https://www.google.com/search?q=Coffee+near+me&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh1EAE'}, {'query': 'coffee types', 'link': 'https://www.google.com/search?q=Coffee+types&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh6EAE'}, {'query': 'coffee beans', 'link': 'https://www.google.com/search?q=Coffee+beans&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAhzEAE'}, {'query': 'coffee machine', 'link': 'https://www.google.com/search?q=Coffee+machine&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh3EAE'}, {'query': 'coffee benefits', 'link': 'https://www.google.com/search?q=Coffee+benefits&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh7EAE'}, {'query': 'coffee starbucks', 'link': 'https://www.google.com/search?q=Coffee+Starbucks&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh4EAE'}, {'query': 'coffee origin', 'link': 'https://www.google.com/search?q=Coffee+origin&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAhyEAE'}, {'query': 'coffee plant', 'link': 'https://www.google.com/search?q=Coffee+plant&sa=X&ved=2ahUKEwiRsZ3x-ab-AhUfjYkEHdmuDRcQ1QJ6BAh0EAE'}], 'pagination': {'current': 1, 'next': 'https://www.google.com/search?q=coffee&oq=coffee&start=10&sourceid=chrome&ie=UTF-8', 'other_pages': {'2': 'https://www.google.com/search?q=coffee&oq=coffee&start=10&sourceid=chrome&ie=UTF-8', '3': 'https://www.google.com/search?q=coffee&oq=coffee&start=20&sourceid=chrome&ie=UTF-8', '4': 'https://www.google.com/search?q=coffee&oq=coffee&start=30&sourceid=chrome&ie=UTF-8', '5': 'https://www.google.com/search?q=coffee&oq=coffee&start=40&sourceid=chrome&ie=UTF-8'}}, 'serpapi_pagination': {'current': 1, 'next_link': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=10', 'next': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=10', 'other_pages': {'2': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=10', '3': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=20', '4': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=30', '5': 'https://serpapi.com/search.json?device=desktop&engine=google&google_domain=google.com&location=Austin%2CTexas&q=coffee&start=40'}}}\n" ] } ], "source": [ "from serpapi import GoogleSearch\n", "search = GoogleSearch({\n", " \"q\": \"coffee\",\n", " \"location\": \"Austin,Texas\",\n", " })\n", "result = search.get_dict()\n", "print(result)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "检查OpenAI KEY是否可用" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "response : {\n", " \"choices\": [\n", " {\n", " \"finish_reason\": \"length\",\n", " \"index\": 0,\n", " \"logprobs\": null,\n", " \"text\": \" Kaitlin. I\"\n", " }\n", " ],\n", " \"created\": 1682500219,\n", " \"id\": \"cmpl-79VSFbbtZ9ekxWgW9LTDSvimSJwd3\",\n", " \"model\": \"davinci\",\n", " \"object\": \"text_completion\",\n", " \"usage\": {\n", " \"completion_tokens\": 5,\n", " \"prompt_tokens\": 5,\n", " \"total_tokens\": 10\n", " }\n", "}\n", "--------\n", " Kaitlin. I\n" ] } ], "source": [ "import openai\n", "\"\"\"\n", "调用ChatGPT API,其中的engine是使用的chatgpt的davinci引擎,\n", "输入提示是prompt,生成文本的最大长度限制为5个tokens,一个token可以\n", "是一个单词或者一个子词,n=1是设置的生成文本的数量,即表示生成一条回复,stop是\n", "来指定生成文本结束的条件的,这里设为None,表示不设置停止的条件,temperature是\n", "用来控制文本生成的随机性的,数值越大代表生成的文本越随机,数值越小表示生成的文本\n", "很确定和保守。返回的内容就是response对象。\n", "\"\"\"\n", "response = openai.Completion.create(\n", " engine=\"davinci\",\n", " prompt=\"Hello, my name is\",\n", " max_tokens=5,\n", " n=1,\n", " stop=None,\n", " temperature=0.5,\n", ")\n", "# 输出ChatGPT的回复\n", "print(\"response : {}\".format(response))\n", "print(\"--------\")\n", "print(response.choices[0].text)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Models\n", "\n", "那么现在开始我们的第一个板块内容,该板块中的代码示例部分来源于LangChain官网教程,关于Models的详细说明文档以及指示请点击👉[此处](https://python.langchain.com/en/latest/modules/models.html)👈进行直接访问。\n", "\n", "- [LLMs](#llms)\n", "- [Chat Models](#chat-models)\n", "- [Text Embedding Models](#text-embedding-models)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### LLMs\n", "\n", "我们知道——LangChain本身不提供大语言模型,只提供各种接口和方式用以调用访问大语言模型。\n", "现在有很多LLM提供商比如OpenAI, Cohere, Hugging Face等。在LLMs中,提供了统一的接口来访问这些大模型。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.llms import OpenAI\n", "import os" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面是常规调用声明LLM的方式方法,模型选择是很多的,具体要使用哪个模型可以访问[此处](https://platform.openai.com/docs/models/overview)进行浏览和设置。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "\"\"\"model_name是选择的OpenAI的模型名称,n=2是生成的文本内容是两条,best_of是从2个里面选择出最佳的一条作为输出\"\"\"\n", "llm = OpenAI(model_name=\"text-ada-001\", n=2, best_of=2)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "那么我们看一下这个llm具体的参数情况" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1mOpenAI\u001b[0m\n", "Params: {'model_name': 'text-ada-001', 'temperature': 0.7, 'max_tokens': 256, 'top_p': 1, 'frequency_penalty': 0, 'presence_penalty': 0, 'n': 2, 'best_of': 2, 'request_timeout': None, 'logit_bias': {}}\n" ] } ], "source": [ "llm" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "生成文本:LLM最基本的功能就是能够调用它,传递一个字符串并返回一个字符串。其中的\"tell me...story\"就是query,传递进模型中调用问答模型给出回答,query的类型是字符串,没有限制它必须是疑问句还是陈述句,ChatGPT等大语言模型会对其内容进行相应的解析与了解,读者不必纠结在此处。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "\"\\n\\nOnce upon a time there was a princess who was very scared. She was sitting in her bedroom when she saw a scary scene in a movie. The princess was scared and started to cry. Her parents tried to soothe her and eventually she fell asleep. When she woke up, she found herself in a dark place. She couldn't make head or tail of what was going on and started to scream. A big part of her population felt sorry for her and helped her, but she wasn't alone. The people who were supposed to be helping her started to leave without her. The princess was scared and started to run around. She didn't know where she was going or what she was doing. Eventually she got her hands on a knife and started to kill people. She was scared and full of Syndicate, but she didn't care. The princess died in the dark, but her story is still shareable online.\"" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm(\"Tell me a scared story\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "llm可以接受文本列表,生成各个语句的回答,还包括api供应商的返回信息" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "llm_result = llm.generate([\"How to study English\", \"How to generate a new idea\"]*3)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "generations=[[Generation(text='\\n\\nThere are a few ways to study English:\\n\\n1. Use online resources.\\n\\n2. Take classes from an English teacher.\\n\\n3. Use English-speaking books and articles.\\n\\n4. Take English-speaking courses at your school.', generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text=' in a foreign country\\n\\nThere are a number of ways to study English in a foreign country. One way is to go to a training course offered by a English speaking teacher. Another way is to use online resources.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text=\"\\n\\n1. Take a step back. What is the best idea you've heard?\\n2. Ask yourself how it would be used. Is the idea unique to you, or is it something that is commonly used?\\n3. How would you create it? This might be a difficult question to answer. Try to think of ways to create the idea that is most unique to you.\\n4. What ingredients would you need? The ingredients for the idea might be different for you, but the process will be the same.\\n5. What resources do you have? You might be able to find the idea through reading articles or Watch this video on how to generate a new idea.\\n6. How do you want to create it? The idea might be something that ismopolitan or consumer-based, so it might be a challenge to create a business around it.\\n7. What resources do you have? The resources for creating a new idea are same, but the process might be different.\", generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\\n\\n1. Create a problem\\n\\n2. rescued a kitten from a euthanasia\\n\\n3. created a Pawtucket Mystic\\n\\n4. designed a one mile run\\n\\n5. written a story for the blog\\n\\n6. created a product for a product\\n\\n7. created a company in town\\n\\n8. designed a campaign', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nThere is no one-size-fits-all answer to this question, as the best way to study English will vary depending on your level of English proficientness. However, some tips on how to study English include using an online English course option, studying at a frequency that is comfortable for you, and using online resources.', generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\\n\\nThere are a few ways to study English:\\n\\n1. Use online resources.\\n\\n2. Use online textbooks.\\n\\n3. Use local resources.\\n\\n4. Use online lectures.\\n\\n5. Use online vocabulary.\\n\\n6. Use online grammar.\\n\\n7. Use online writing.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nThere is no one way to generate a new idea. You will likely have to consider what people want, what might be appealing to them, and what you think will be a strong signal to investors. You will also need to create a plan for achieving your new idea.', generation_info={'finish_reason': None, 'logprobs': None}), Generation(text='\\n\\n1. brainstorm\\n2. create a scenario\\n3. think about what it does\\n4. come up with specific steps\\n5. test out the scenario\\n6. keep track of how it goes\\n7. Jr. Album', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text=\" in a foreign country\\n\\nThere is no one-size-fits-all answer to this question, as the best way to study English in a foreign country will vary depending on the individual's individual skills and knowledge. However, some ways to study English in a foreign country include attending English-language classes, taking classes from a English-speaking tutor, or studying English content in absence-friendly websites.\", generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\\n\\nThere are a few ways to study English:\\n\\n1. Online courses: There are many online courses that teach English, including some free courses and some paid courses.\\n\\n2. Meeting English-speaking people: meeting English-speaking people can help you learn more about English culture and the language.\\n\\n3. Online groups and websites: there are many online groups and websites that teach English, and they offer resources about different topics.\\n\\n4. classroom learning: classroom learning is one of the most common ways to study English, because it is a more direct way to learning the language.', generation_info={'finish_reason': 'stop', 'logprobs': None})], [Generation(text='\\n\\nThere is no one way to generate a new idea. You will need to consider what is important to you and what is comfortable for you to talk about. You also need to create a plan in how you will go about creating the idea.', generation_info={'finish_reason': 'stop', 'logprobs': None}), Generation(text='\\n\\nThere is no one way to generate a new idea. You will need to have some kind of metaphor or metaphor with people, things, or something. For example, you could say that you are creating a new kind of product, but be specific about how you think this new product might be used. You could also use a metaphor with people or something to mean different things.\\n\\nFor example, you could create a new type of product that uses people as the main character. This could be a type of product that people use to find new things to do. The product might be called \"People\\'s Way.\" People use the product to find new ways to do things. The new way people are using the product is called \"People\\'s Way\\'s new way.\" People\\'s Way is different from the old way and people using the old way is called \"The old way.\"', generation_info={'finish_reason': 'stop', 'logprobs': None})]] llm_output={'token_usage': {'total_tokens': 1074, 'prompt_tokens': 30, 'completion_tokens': 1044}, 'model_name': 'text-ada-001'}\n" ] } ], "source": [ "llm_result" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(llm_result.generations)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[Generation(text='\\n\\n1. Open a English course in your local university or department.\\n\\n2. Find a course on English you want to take and take it in your local university.\\n\\n3. Find a tutor or course Tutor English for you to learn from.\\n\\n4. Finish your coursework and you will have completed English studies in your local university.', generation_info={'finish_reason': 'stop', 'logprobs': None}),\n", " Generation(text='\\n\\nThere are a few ways to study English:\\n\\n1. Online courses: Take online courses from various English schools.\\n\\n2. Practice tests: Performance test materials and practice questions in real time so you can become comfortable with the material.\\n\\n3. Print books: Read print books and learn key concepts in the same way as if they were video lessons.\\n\\n4. Location: Take classes and workshops near you at a nearby school or organization.\\n\\n5. Online courses: Take online courses that interest you. Check out free courses beforeempying to sink in for real.', generation_info={'finish_reason': 'stop', 'logprobs': None})]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_result.generations[0]" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[Generation(text='\\n\\n\\nThere are a few ways to generate new ideas:\\n\\n1. Look at what others have done in their line of work and experiment with different ideas.\\n\\n2. Take a step back and look at the whole work process from a different perspective.\\n\\n3. Think about different ways to do a task that is popular or efficient in another job market.\\n\\n4.Solution:\\n\\nTake a step back and think about different ways to do a task that is popular or efficient in another job market. For example, think about how to automate task completion times in a specific industry.', generation_info={'finish_reason': 'stop', 'logprobs': None}),\n", " Generation(text=' for a game\\n\\nThere is no one definitive way to generate a new idea for a game. However, some methods you may consider include searching online forums for various ideas, creating a list of specific ideas you have, or searching Google for \" game idea\" resources. Additionally, if you have any specific ideas you would like to see included in this resource, be sure to include them in a comment!', generation_info={'finish_reason': 'stop', 'logprobs': None})]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_result.generations[1]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "给出调用api的供应商返回信息" ] }, { "cell_type": "code", "execution_count": 102, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "{'token_usage': {'prompt_tokens': 42,\n", " 'completion_tokens': 1407,\n", " 'total_tokens': 1449},\n", " 'model_name': 'text-ada-001'}" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_result.llm_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "评估字符串花费Tokens数量" ] }, { "cell_type": "code", "execution_count": 103, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "29" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm.get_num_tokens(\"假设你是个教师,如何教英语\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Chat Models\n", "ChatGPT接口使用的是 turbo 的模型,对于聊天机器人的设计,这里有很重要的三个角色:system、human、AI,下面这张图展示的是聊天机器人在捕获信息并进行处理的图画展示: \n", "\n", "\n", "\n", "如上图所示,这三个角色分别是如下的定义:\n", "- system:针对现实世界中的一切描述,我们的system要决定最终想要AI做什么,一个直白的背景或者说是角色的定位,例如翻译员、银行家等; \n", "- human:具体的事情,例如想要AI翻译的语句或者想要AI写出一句酷似方文山的歌词;\n", "- AI:大模型决定返回的内容 使用langchain工具箱实现这个功能。\n", "\n", "在代码中我们将会通过langchain.schema引入的SystemMessage, HumanMessage, AIMessage来操纵具体的需求步骤,如下所示:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#导入我们所需要的相关库函数\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain import PromptTemplate, LLMChain\n", "from langchain.prompts.chat import (\n", " ChatPromptTemplate,\n", " SystemMessagePromptTemplate,\n", " AIMessagePromptTemplate,\n", " HumanMessagePromptTemplate,\n", ")\n", "from langchain.schema import (\n", " AIMessage,\n", " HumanMessage,\n", " SystemMessage\n", ")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "ChatOpenAI(verbose=False, callback_manager=, client=, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key=None, openai_organization=None, request_timeout=60, max_retries=6, streaming=False, n=1, max_tokens=None)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#定义聊天机器人使用的聊天问答模型\n", "chat = ChatOpenAI(temperature=0)\n", "chat" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "上面的输出chat如下:\n", "ChatOpenAI(verbose=False, callback_manager=, client=, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key=None, openai_organization=None, request_timeout=60, max_retries=6, streaming=False, n=1, max_tokens=None)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "由AI回复human的消息" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "AIMessage(content='我喜欢编程。', additional_kwargs={})" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#human给出的信息是一个字符串内容,给到chat之后会返回一个AIMessage信息,其中的内容将是给出的反馈答案\n", "chat([HumanMessage(content=\"Translate this sentence from English to Chinese. I love programming.\")])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "正如我们上面图中展示的那样,我们一般定义systemmessage的内容为给定它一个角色使OpenAI模型能够在一个知识领域内回答,这样做的好处就是对于给出的答案会更加准确,这里特别说明一点——Openai聊天模型支持一次输入多段信息:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "AIMessage(content='我喜欢编程。', additional_kwargs={})" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "messages = [\n", " SystemMessage(content=\"You are a helpful assistant that translates English to Chinese.\"),\n", " HumanMessage(content=\"Translate this sentence from English to Chinese. I love programming.\")\n", "]\n", "chat(messages)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "可以使用chat.generate方法处理多对儿对话内容,返回值LLMResult包含有输入信息。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "LLMResult(generations=[[ChatGeneration(text=\"J'aime programmer.\", generation_info=None, message=AIMessage(content=\"J'aime programmer.\", additional_kwargs={}))], [ChatGeneration(text='我喜欢人工智能。', generation_info=None, message=AIMessage(content='我喜欢人工智能。', additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 73, 'completion_tokens': 16, 'total_tokens': 89}, 'model_name': 'gpt-3.5-turbo'})" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "batch_messages = [\n", " [\n", " SystemMessage(content=\"You are a helpful assistant that translates English to French.\"),\n", " HumanMessage(content=\"Translate this sentence from English to French. I love programming.\")\n", " ],\n", " [\n", " SystemMessage(content=\"You are a helpful assistant that translates English to Chinese.\"),\n", " HumanMessage(content=\"Translate this sentence from English to Chinese. I love artificial intelligence.\")\n", " ],\n", "]\n", "result = chat.generate(batch_messages)\n", "result" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "上面的输出信息我们为了您的直观看到,我们将其呈现在这里:\n", "\n", "OUT:\n", "\n", "LLMResult(generations=[[ChatGeneration(text=\"J'aime programmer.\", generation_info=None, message=AIMessage(content=\"J'aime programmer.\", additional_kwargs={}))], [ChatGeneration(text='我喜欢人工智能。', generation_info=None, message=AIMessage(content='我喜欢人工智能。', additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 73, 'completion_tokens': 16, 'total_tokens': 89}, 'model_name': 'gpt-3.5-turbo'})\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "我们可以从result中得到一些信息如下:" ] }, { "cell_type": "code", "execution_count": 109, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "{'token_usage': {'prompt_tokens': 73,\n", " 'completion_tokens': 16,\n", " 'total_tokens': 89},\n", " 'model_name': 'gpt-3.5-turbo'}" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "result.llm_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 在聊天模型(chatmodel)中使用提示模板\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面使用模板包装SystemMessage和HumanMessage。方便使用。" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#首先构建模版,用几个完形待填项表示要传入的内容,input_variables在这个模版中是两个\n", "template=\"You are a helpful assistant that translates {input_language} to {output_language}.\"\n", "#定义systemmessage的提示模版,进行相应的模版格式化\n", "system_message_prompt = SystemMessagePromptTemplate.from_template(template)\n", "#构建human模版,用来传入我们想要查询的内容\n", "human_template=\"{text}\"\n", "#将human模版进行格式化\n", "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "AIMessage(content=\"J'adore la programmation.\", additional_kwargs={})" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#将上面的两类模版,也就是system和human的模版,将两个模版通过合并的方式创建\n", "chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])\n", "# 使用聊天提示模版来创建一个聊天补全,其中的各项参数都是input_variables,通过to_messages方法传递给chat模型完成聊天对话\n", "chat(chat_prompt.format_prompt(input_language=\"English\", output_language=\"French\", text=\"I love programming.\").to_messages())" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "也可以用下面的方法更直接的创建system_message模板。" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "PromptTemplate(input_variables=['input_language', 'output_language'], output_parser=None, partial_variables={}, template='You are a helpful assistant that translates {input_language} to {output_language}.', template_format='f-string', validate_template=True)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "prompt=PromptTemplate(\n", " template=\"You are a helpful assistant that translates {input_language} to {output_language}.\",\n", " input_variables=[\"input_language\", \"output_language\"],\n", ")\n", "prompt" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input_language', 'output_language'], output_parser=None, partial_variables={}, template='You are a helpful assistant that translates {input_language} to {output_language}.', template_format='f-string', validate_template=True), additional_kwargs={})" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "system_message_prompt = SystemMessagePromptTemplate(prompt=prompt)\n", "system_message_prompt" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### LLMChain\n", "结合LLMChain和Prompt、Chat model,可以更方便地开展对话" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "LLMChain(memory=None, callback_manager=, verbose=False, prompt=ChatPromptTemplate(input_variables=['text', 'output_language', 'input_language'], output_parser=None, partial_variables={}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input_language', 'output_language'], output_parser=None, partial_variables={}, template='You are a helpful assistant that translates {input_language} to {output_language}.', template_format='f-string', validate_template=True), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['text'], output_parser=None, partial_variables={}, template='{text}', template_format='f-string', validate_template=True), additional_kwargs={})]), llm=ChatOpenAI(verbose=False, callback_manager=, client=, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key=None, openai_organization=None, request_timeout=60, max_retries=6, streaming=False, n=1, max_tokens=None), output_key='text')" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chain = LLMChain(llm=chat, prompt=chat_prompt)\n", "chain" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "'我喜欢编程和游泳。'" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chain.run(input_language=\"English\", output_language=\"Chinese\", text=\"I love programming and swimming\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 流式对话\n", "通过回调函数处理对话" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "一加一等于二是因为这是我们所接受的基本数学原理之一。在十进制数系统中,我们将数字1表示为一个单位,数字2表示为两个单位。当我们将一个单位与另一个单位相加时,我们得到两个单位,即数字2。这是因为加法是一种基本的算术运算,它表示将两个或多个数值相加以得到它们的总和。因此,一加一等于二是数学中的基本原理之一,它被广泛接受并被用于各种数学和科学应用中。" ] } ], "source": [ "from langchain.callbacks.base import CallbackManager\n", "from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler\n", "\"\"\"\n", "streaming=True是启用了聊天的流式模式,也就是响应的内容将会在逐步生成的数据块中逐步返回;\n", "而callback_manger用于管理聊天过程中的回调函数的对象,流式对象将会逐步返回内容而不是整个\n", "响应完成之后一次性返回,如果不传递callback_manager参数,则聊天过程中将会以默认的方式运行,也\n", "就是响应完成之后一次性返回;verbose是详细模式,决定是否打印出具体的信息;temperature的设置\n", "则是决定随机性\n", "\"\"\"\n", "chat = ChatOpenAI(streaming=True, callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]), verbose=True, temperature=0)\n", "resp = chat([HumanMessage(content=\"帮我分析一下为什么一加一等于二?\")])" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "As an AI language model, I cannot provide instructions on how to become a fictional character like Superman. However, I can suggest some ways to become a better version of yourself:\n", "\n", "1. Set goals and work towards them consistently.\n", "2. Exercise regularly to improve physical strength and endurance.\n", "3. Learn new skills and knowledge to enhance mental abilities.\n", "4. Practice empathy and kindness towards others.\n", "5. Be courageous and stand up for what is right.\n", "6. Develop a positive mindset and attitude towards life.\n", "7. Surround yourself with supportive and positive people.\n", "8. Take care of your health by eating a balanced diet and getting enough rest.\n", "9. Continuously challenge yourself to grow and improve.\n", "10. Believe in yourself and your abilities." ] } ], "source": [ "resp_another = chat([HumanMessage(content=\"tell me how to become a superman?\")])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Text Embedding Models\n", "词嵌入支持将自然语言转变为向量。LangChain中最重要的两个embedding方法为embed_documents 和 embed_query方法。因为处理多个文本文件和处理一个文件有很大的不同,所以LangChain将其分为两个类。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "LangChain中集成了很多来自不同平台的API可以进行词嵌入编码,这里举一个用OpenAi进行词嵌入的方法" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#我们使用较多的也是OpenAI的embeddings方法\n", "from langchain.embeddings import OpenAIEmbeddings" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "embeddings = OpenAIEmbeddings()" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "text = \"This is a test document.\"" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[-0.0031265460635144116,\n", " 0.011133635493097378,\n", " -0.004037691773639618,\n", " -0.011746618046080886,\n", " -0.000993598608605281,\n", " 0.01080715570571065,\n", " -0.010440697965211392,\n", " -0.005253663322651083,\n", " -0.009874355115762394,\n", " -0.026171704933991537,\n", " 0.020348368352341755,\n", " 0.02257376179702522,\n", " -0.00752236652698065,\n", " 0.017230149476854816,\n", " -0.005986577872327018,\n", " 0.01914905397335298,\n", " 0.021254515421344024,\n", " -0.015644390243455687,\n", " 0.007642298058011785,\n", " -0.018402813128865346,\n", " -0.0006866907980891692,\n", " -0.006416332020722187,\n", " -0.010967063792870444,\n", " 0.0180030410483207,\n", " -0.022173991579125737,\n", " -0.0030682459684349844,\n", " 0.014405098842676966,\n", " -0.029982859474719296,\n", " 0.018496092535934365,\n", " -0.007935463505353126,\n", " 0.01004758949773389,\n", " -0.019442219420694323,\n", " -0.003694554583399551,\n", " -0.024279453027116777,\n", " -0.005540166088247863,\n", " 0.0038311432844533796,\n", " -0.00566676076668485,\n", " -0.029449831896638266,\n", " 0.018576046579514262,\n", " -0.016643818582172135,\n", " 0.007529029208725211,\n", " 0.012452880937455994,\n", " -0.0009711115338484352,\n", " -0.010693886390762786,\n", " 0.010034264134244767,\n", " -0.012566149321081278,\n", " 0.03358080261168561,\n", " -0.026957921868946542,\n", " -0.007935463505353126,\n", " 0.028970105772513726,\n", " 0.019735384868035666,\n", " -0.002010517301808462,\n", " -0.027397671902603716,\n", " -0.008768321075165222,\n", " -0.00623976629787841,\n", " 0.0019855315467744218,\n", " -0.007389109166799102,\n", " 0.027930699480684745,\n", " 0.00680944048819969,\n", " -0.009288023289757131,\n", " -0.022533785706557855,\n", " 0.010460686941767657,\n", " -0.013612218294654818,\n", " -0.011120309198285674,\n", " -0.004873880684323994,\n", " -0.008301921245852384,\n", " -0.0058333320012504955,\n", " 0.011120309198285674,\n", " 0.006299731830563333,\n", " 0.004460783240290227,\n", " 0.010627257710672012,\n", " 0.012452880937455994,\n", " 0.005370263512809938,\n", " 0.005436891727239422,\n", " 0.008941555457136718,\n", " 0.00428421751744645,\n", " -0.022693693793717648,\n", " -0.013212447145432755,\n", " 0.01123357851323354,\n", " -0.005710069129347079,\n", " 0.00980772643567162,\n", " -0.024439362976921734,\n", " -0.008555109671403776,\n", " 0.007875497507006914,\n", " 0.0025502087257872805,\n", " 0.007562343548770598,\n", " 0.005740052128520186,\n", " 0.028223864928026088,\n", " -0.022960208514080743,\n", " -0.015564436199875789,\n", " -0.008215303589205346,\n", " 0.02005520104235525,\n", " 0.003584617540646548,\n", " 0.012779361656165304,\n", " -0.01647058513152322,\n", " 0.031555295207274466,\n", " 0.013532264251074922,\n", " 0.030382631555263943,\n", " -0.006206451957833024,\n", " -0.049678266389642435,\n", " -0.0037212060088697317,\n", " -0.001316747287950374,\n", " -0.007055966232006522,\n", " 0.0035246517751309804,\n", " -0.03486007103425428,\n", " -0.009028172182461176,\n", " 0.021960778312719132,\n", " -0.007275840783173818,\n", " 0.015431178839694241,\n", " -0.008281932269296119,\n", " -0.016457257905388937,\n", " 0.005083760281551867,\n", " -0.006366360510654107,\n", " -0.03603273654890997,\n", " 0.01561773858515486,\n", " 0.00566676076668485,\n", " 0.006486292041685242,\n", " -0.021907476858762643,\n", " -0.010260800901495335,\n", " 0.0010419043318218987,\n", " 0.0006621215188718254,\n", " 0.016883680712911825,\n", " 0.026504848334445406,\n", " -0.02753092926278526,\n", " 0.010580618007137502,\n", " 0.013292401189012652,\n", " -0.00880829809695517,\n", " -0.04184274776707063,\n", " -0.006469634871662549,\n", " -0.005530172065631021,\n", " 0.019109076020240454,\n", " 0.021454401461616344,\n", " 0.01419188743891552,\n", " 0.017509989560707036,\n", " -0.023333328005001982,\n", " 0.037312004971478636,\n", " -0.04040357125734217,\n", " 0.024772504514730443,\n", " -0.0432286228228426,\n", " -0.008435177674711351,\n", " 0.008308583927596945,\n", " 0.027397671902603716,\n", " -0.019162379336842107,\n", " -0.016936984029513477,\n", " 0.010294115241540723,\n", " 0.01395202437685325,\n", " 0.008255280610995293,\n", " -0.024812482467842973,\n", " 0.012506184254057646,\n", " -0.021147910650785882,\n", " 0.0031082232230555777,\n", " 0.001852274419423519,\n", " 0.017763178917581012,\n", " 0.002528554544456166,\n", " 0.015551109905064087,\n", " 0.03144868857407117,\n", " 0.0038577947099235604,\n", " -0.009514560988330279,\n", " -0.018029693637944107,\n", " -0.01961545287134324,\n", " 0.0030682459684349844,\n", " 0.02218731694261486,\n", " 0.00956786337360935,\n", " 0.0018689315894462124,\n", " 0.023466585365183527,\n", " 0.034700162947094486,\n", " 0.004007708774466511,\n", " 0.007648960739756346,\n", " -0.0016307344306507275,\n", " -0.015404527181393415,\n", " -0.025039019235093538,\n", " 0.02475917915124132,\n", " -0.02537216263554741,\n", " 0.007655623421500907,\n", " -0.0201884584025368,\n", " 0.014271841482495417,\n", " 0.007202549421338483,\n", " 0.0034780118387658255,\n", " -0.0044374633885229725,\n", " -0.004037691773639618,\n", " -0.033873968059026954,\n", " 0.016883680712911825,\n", " 0.01480486999189903,\n", " 0.03179515547536899,\n", " -0.017056916026205904,\n", " -0.006936035166636677,\n", " 0.024226151573160288,\n", " -0.009534549033563962,\n", " 0.001379211559120152,\n", " -0.00461736045223903,\n", " 0.023200070644820433,\n", " 0.021880824269139235,\n", " -0.0063430406588868525,\n", " -0.01480486999189903,\n", " -0.7023184943753603,\n", " -0.016363978498319918,\n", " 0.004297543346596862,\n", " -0.017230149476854816,\n", " 0.022173991579125737,\n", " 0.03136873266784611,\n", " 0.024599271064081527,\n", " 0.002137111747414804,\n", " -0.0060098977240942725,\n", " 0.02185417354216099,\n", " -0.0226670430667394,\n", " -0.012706069363007388,\n", " -0.009201406564432673,\n", " -0.013212447145432755,\n", " -0.014111932464013044,\n", " -0.023160094554353066,\n", " -0.016963636619136885,\n", " -0.003323100297253163,\n", " -0.01761659619391034,\n", " 0.013085852466995769,\n", " 0.014924801057268873,\n", " 0.015457830497995068,\n", " -0.015711018923546458,\n", " -0.01672377262575203,\n", " 0.000518870077865774,\n", " 0.00890824111709133,\n", " 0.01309251514874033,\n", " -0.006133160595997688,\n", " 0.017483338833728792,\n", " 0.01689700793904611,\n", " -0.026211682887104064,\n", " -0.003571291711496135,\n", " -0.0009452929435963248,\n", " 0.008548446989659215,\n", " 0.033260986437366025,\n", " -0.0020588231414404023,\n", " -0.014485052886256863,\n", " -0.025039019235093538,\n", " 0.016590515265570482,\n", " 0.0008794972151389435,\n", " -0.016830379258955336,\n", " -0.000344802889780038,\n", " 0.0048205778333836324,\n", " -0.0017423372602551933,\n", " -0.004604034623088617,\n", " -0.0025218916298809595,\n", " 0.018829235936388234,\n", " 0.0003429289523317189,\n", " 0.027450973356560205,\n", " 0.017656572284377708,\n", " -0.016590515265570482,\n", " -0.0005492693200249316,\n", " 0.006656195082784458,\n", " -0.003491337435085593,\n", " 0.0010210829857088546,\n", " -0.010434035283466831,\n", " 0.021640962138399545,\n", " 0.007728915248997534,\n", " 0.010833806432688895,\n", " 0.016563864538592238,\n", " -0.0011426800707608075,\n", " 0.011879875406262435,\n", " -0.005626783279233612,\n", " -0.016883680712911825,\n", " -0.028943455045535478,\n", " -0.007495714868679824,\n", " -0.020841419839955418,\n", " 0.022547111070046977,\n", " 0.0010219158209269247,\n", " -0.019002471249682313,\n", " -0.003724537582572657,\n", " 0.012512846935802208,\n", " -0.010254138219750774,\n", " -0.01970873414105742,\n", " 0.020761463933730358,\n", " 0.015497807519785016,\n", " 0.00976108673213711,\n", " -0.009987623499387678,\n", " -0.00933466392461422,\n", " 0.016790401305842806,\n", " 0.00371454332712517,\n", " 0.003584617540646548,\n", " -0.014338470162586192,\n", " -0.015431178839694241,\n", " 0.01085379540924516,\n", " -0.02024176171913845,\n", " -0.04610697584229952,\n", " -0.01299923574167131,\n", " -0.0066761835936794325,\n", " 0.013385681527404252,\n", " 0.021547682731330526,\n", " 0.0014358458673481166,\n", " -0.007935463505353126,\n", " -0.0004426636181442092,\n", " 0.008928229162325016,\n", " -0.0027784116291352783,\n", " 0.0011585044055654307,\n", " 0.003967731752676563,\n", " 0.030142769424524252,\n", " -0.0019239002272380366,\n", " 0.0014741573351172471,\n", " 0.0024169515984363774,\n", " 0.0006317222185050064,\n", " 0.011733292682591764,\n", " 0.021161236014275005,\n", " 0.005247000640906522,\n", " 0.003637920391586909,\n", " 0.024452688340410856,\n", " 0.018256230405194675,\n", " -0.008488480991313004,\n", " -0.007169235081293096,\n", " -0.008988195160671227,\n", " -0.009554538010120227,\n", " 0.0015707686651351598,\n", " -0.016057487687489453,\n", " -0.034220438685615105,\n", " 0.008035406525489288,\n", " 0.011246903876722662,\n", " 0.0023653144179321566,\n", " 0.0033880630740771513,\n", " 0.01404530378392227,\n", " 0.017723200964468482,\n", " 0.013339040892547161,\n", " -0.0016365643935925412,\n", " 0.004580714771321362,\n", " -0.002518560289008679,\n", " 0.003941080560037028,\n", " -0.019415566831070916,\n", " -0.01719017338638745,\n", " -0.009707783415535458,\n", " -0.0194288940572052,\n", " -0.0017639915580016305,\n", " 0.03371405997186716,\n", " -0.01419188743891552,\n", " 0.007722252101591682,\n", " 0.002328668737014489,\n", " 0.0038078231998554795,\n", " -0.0052803149809519095,\n", " 0.021361122054547325,\n", " -0.009727772392091723,\n", " -0.013019223786904994,\n", " 0.013312390165568917,\n", " -0.006969349041020773,\n", " -0.009108126226041072,\n", " -0.011913189746307822,\n", " -0.02232057430279641,\n", " -0.017989715684831577,\n", " -0.0030299346170811763,\n", " 0.0009786072254340506,\n", " 0.00995430915934229,\n", " -0.022107362899034963,\n", " 0.0013617215538793885,\n", " -0.010100892814335542,\n", " -0.005843326489528627,\n", " -0.00813534954562545,\n", " -0.011106983834796552,\n", " -0.017070241389695026,\n", " -0.02627831156719484,\n", " 0.0010627257943502657,\n", " -0.0014475059096470666,\n", " -0.008601749374938286,\n", " 0.017549967513819566,\n", " -0.006196457935216181,\n", " 0.0011410144003246672,\n", " -0.02651817369793453,\n", " -0.018242905041705552,\n", " -0.03302112244398117,\n", " 0.033181030531140965,\n", " -0.009974298135898554,\n", " -0.0339006187860052,\n", " -0.018309533721796327,\n", " 0.005167046131665335,\n", " -0.013492287229284973,\n", " -0.0020704830673240297,\n", " 0.005017132067122384,\n", " -0.010527315621858432,\n", " -0.015737669650524706,\n", " 0.007842183166961527,\n", " 0.010354081239886934,\n", " -0.02133447132756908,\n", " -0.0049904804088215585,\n", " 0.0034580230950402063,\n", " 0.012279646555484499,\n", " 0.0020305058127034364,\n", " 0.01181324672617166,\n", " 0.015084710075751248,\n", " 0.013465635570984147,\n", " 0.007075954742901496,\n", " -0.012646104295983757,\n", " 0.0025885203099717336,\n", " 0.008042069207233849,\n", " 0.0033064431272304693,\n", " -0.01461831024643841,\n", " 0.009274697926268009,\n", " -0.007648960739756346,\n", " 0.01985531686472809,\n", " -0.029689694027377957,\n", " 0.010447360646955953,\n", " 0.012872641063234323,\n", " 0.02385303021959389,\n", " 0.02257376179702522,\n", " 0.008708355076819009,\n", " 0.0038544631362206344,\n", " -0.022720344520695893,\n", " 0.00016542626076378224,\n", " -0.03541975120195872,\n", " -0.01313915578359742,\n", " -0.0027151145227474302,\n", " 0.013552252296308605,\n", " 0.006339709318014572,\n", " 0.012885967358046027,\n", " -0.017643246920888585,\n", " -0.02470587583463967,\n", " 0.017390059426659773,\n", " 0.02152103014170712,\n", " 0.005450217556389835,\n", " -0.010134206223058348,\n", " -0.002833380383342425,\n", " -0.006746143614642487,\n", " -0.0020538258973013365,\n", " 0.0066895094228298455,\n", " 0.004837234537745035,\n", " 0.012559486639336717,\n", " -0.007282503464918379,\n", " -0.01624404650162749,\n", " 0.011493429620529494,\n", " 0.028596986281592487,\n", " 0.03259469963645829,\n", " 0.02300018460454811,\n", " -0.024159522893069513,\n", " -0.018362835175752816,\n", " 0.002605177479994427,\n", " 0.0008570100821744363,\n", " 0.0012476201022053896,\n", " 0.0031781832440186328,\n", " 0.010460686941767657,\n", " 0.02242717907335455,\n", " -0.01938891610409267,\n", " 0.028730243641774036,\n", " 0.00035979433115892995,\n", " 0.011486766938784932,\n", " 0.018829235936388234,\n", " 0.028650287735548976,\n", " -0.008501806354802126,\n", " 0.02290690519747909,\n", " -9.301974269190048e-05,\n", " 0.028197214201047843,\n", " 0.0085684350348929,\n", " -0.004021034603616924,\n", " 0.03147533930104941,\n", " -0.010707212685574488,\n", " 0.0018039686962069014,\n", " 0.001005258650904231,\n", " 0.004180943156438008,\n", " 0.03246144227627674,\n", " -0.026917945778479172,\n", " -0.013412332254382497,\n", " 0.0018822573021813028,\n", " 0.014338470162586192,\n", " 0.03123547717030972,\n", " 0.022227293033082227,\n", " 0.005023794748866945,\n", " -0.0026301630021978223,\n", " 0.0012159715490114653,\n", " 0.023213396008309555,\n", " -0.004550731772148256,\n", " -0.013205784463688194,\n", " 0.003389728977343937,\n", " -0.020015224951887883,\n", " -0.01304587544520582,\n", " -0.0056067947683386375,\n", " -0.0014141915696016796,\n", " 0.018082995091900596,\n", " 0.0024502659384817646,\n", " 0.0246658997441723,\n", " 0.010580618007137502,\n", " 0.02590519021362844,\n", " 0.012039784424744808,\n", " 0.01647058513152322,\n", " 0.001490814388724618,\n", " -0.009081475499062828,\n", " -0.022373875756752898,\n", " 0.0006258921973555314,\n", " 0.01218636714841548,\n", " 0.012292972850296202,\n", " -0.011719966387780062,\n", " -0.010247475538006213,\n", " 0.004657337474028978,\n", " -0.007442412017739463,\n", " 0.006479629359940681,\n", " 0.00400104609272195,\n", " -4.937281880562186e-05,\n", " 0.01709689397931843,\n", " -0.023160094554353066,\n", " -5.1793308003778376e-05,\n", " 0.01596420641777527,\n", " 0.008888252140535067,\n", " -0.0055368347473755825,\n", " -0.010147532517870051,\n", " -0.007815532439983282,\n", " 0.011180275196631888,\n", " -0.0075756693779210115,\n", " 0.008761658393420661,\n", " 0.00623643495700613,\n", " 0.02009517899546778,\n", " 0.0003102393260113764,\n", " -0.0026085088208667078,\n", " -0.012959258719881362,\n", " -0.01341899586744964,\n", " -0.010300777923285284,\n", " 0.01804301900143323,\n", " 0.003874451879946254,\n", " -0.014005326762132321,\n", " -0.005956594873153911,\n", " 0.015604413221665737,\n", " -0.005650103596662157,\n", " 0.0015449501912983721,\n", " 0.0133323782108026,\n", " 0.016830379258955336,\n", " 0.012819338677955252,\n", " -0.01537787552309259,\n", " -0.006882732315696315,\n", " -0.01809632231803488,\n", " 0.010727200730808172,\n", " 0.0489586781347782,\n", " 0.04320196837057403,\n", " 0.0025801917249603868,\n", " -0.010893772431035108,\n", " 0.0037012174979747575,\n", " -0.019308962060512774,\n", " -0.02694459650545742,\n", " -0.0135189388875858,\n", " 0.006366360510654107,\n", " -0.002205405865111073,\n", " -0.007882161120074055,\n", " -0.004354177538409504,\n", " 0.01624404650162749,\n", " 0.001379211559120152,\n", " 0.016630493218683012,\n", " 0.007122594912097296,\n", " -0.0013892058145676392,\n", " -0.0024735860230796648,\n", " -0.009487909330029453,\n", " -0.012279646555484499,\n", " 0.002900008830602554,\n", " 0.007708926272441269,\n", " 0.007688937761546295,\n", " 0.003371406136885103,\n", " 0.01209974949176844,\n", " -0.02133447132756908,\n", " 0.007722252101591682,\n", " 0.0016107459197557533,\n", " 0.0002640157490475955,\n", " -0.020361693715830877,\n", " -0.01419188743891552,\n", " 0.019215682653443755,\n", " 0.01014086983612549,\n", " 0.018109647681524003,\n", " -0.0006242264687117299,\n", " 0.03288786508379963,\n", " -0.0044308002411171206,\n", " -0.015790972967126355,\n", " 0.007755566441637069,\n", " 0.004847229026023168,\n", " 0.009254709881034323,\n", " 0.004580714771321362,\n", " -0.003394725988652358,\n", " -0.008261943292739854,\n", " -0.007149246570398122,\n", " 0.00025672823716266707,\n", " -0.016657143945661257,\n", " 0.003386397403641011,\n", " -0.008635063714983673,\n", " -0.007555680867026037,\n", " 0.012079761446534757,\n", " -0.01770987560097936,\n", " -0.0012184701710809985,\n", " -0.015417852544882538,\n", " 0.02875689436875228,\n", " 0.023306677278023737,\n", " 0.004390823219327172,\n", " 0.006816103635605542,\n", " -0.0022070715355472135,\n", " -0.017536642150330444,\n", " -0.029876254704161154,\n", " -0.006792783318176996,\n", " -0.011373498555159648,\n", " -0.009301349584568833,\n", " -0.011413475576949597,\n", " -0.03043593487186559,\n", " -0.023506561455650898,\n", " -0.013345704505614304,\n", " -0.020161807675558554,\n", " 0.0037212060088697317,\n", " 0.010980389156359566,\n", " -0.01760327083042122,\n", " -0.024785831740864725,\n", " -0.016217395774649247,\n", " 0.02899675649949197,\n", " -0.013938698082041547,\n", " 0.0005355271896808063,\n", " 0.01304587544520582,\n", " 0.0014974773032998246,\n", " 0.022533785706557855,\n", " -0.010840470045756037,\n", " -0.022507133116934447,\n", " 0.005899960681341269,\n", " -0.02413287030344611,\n", " -0.005899960681341269,\n", " 0.016843704622444458,\n", " -0.003987720263571537,\n", " 0.0067761261481543026,\n", " -0.0027351030336424044,\n", " 0.01047401230525678,\n", " -0.006076526404185046,\n", " -0.002423614513011584,\n", " -0.004863886196045861,\n", " -0.02936987785305837,\n", " 0.016350653134830796,\n", " -0.008768321075165222,\n", " 0.0019888631204773477,\n", " 0.007482389505190702,\n", " -0.00866837805502906,\n", " -0.004130971646369927,\n", " -0.015537784541574963,\n", " -0.001499975808954035,\n", " -0.009128115202597337,\n", " 0.0016174087179156372,\n", " 0.020788116523353765,\n", " -0.019055772703638802,\n", " -0.013379018845659691,\n", " 0.01689700793904611,\n", " -0.023293350051889452,\n", " -0.007715589419847121,\n", " -0.010460686941767657,\n", " -0.018162950998125656,\n", " 0.009587852350165614,\n", " -0.020015224951887883,\n", " 0.002370311662071223,\n", " 0.017443360880616262,\n", " -0.007422423506844489,\n", " 0.022014081629320784,\n", " -0.010260800901495335,\n", " -0.030169420151502497,\n", " 6.792991963538974e-05,\n", " -0.009801063753927058,\n", " 0.011086995789562869,\n", " 0.03563296446836532,\n", " 0.022080710309411555,\n", " 0.029209967903253413,\n", " -0.008768321075165222,\n", " -0.0030016175211748557,\n", " -0.014218538165893765,\n", " 0.007915475460119442,\n", " -0.00509375476983,\n", " 0.0011701644478643808,\n", " -0.007782218099937894,\n", " -0.0041976003264607015,\n", " -0.018882539252989886,\n", " -0.01143346362218328,\n", " -0.001524128728770005,\n", " 0.013672184293001032,\n", " -0.005263657810929216,\n", " -0.0106605720507174,\n", " -0.015084710075751248,\n", " 0.013658857998189328,\n", " 0.011393486600393332,\n", " -0.009168092224387286,\n", " -0.02567865344637787,\n", " -0.029822951387559502,\n", " -0.02170759081849032,\n", " 0.010107555496080103,\n", " -0.020574905119592323,\n", " 0.0008586758108182379,\n", " 0.021147910650785882,\n", " 0.0003445946809755205,\n", " -0.011626686980711043,\n", " -0.00490719455870809,\n", " 0.015830950920238885,\n", " -0.029396528580036614,\n", " -0.004813914685977781,\n", " 0.006193126128682611,\n", " 0.016217395774649247,\n", " 0.02710450459261721,\n", " 0.02270701915720677,\n", " -0.011613360685899339,\n", " 0.011773269704381712,\n", " 0.019788688184637318,\n", " -0.0034213774141225385,\n", " 0.009634492053700124,\n", " -0.009401292604704995,\n", " -0.013845418674972527,\n", " -0.016390629225298162,\n", " 0.0025635345549376936,\n", " 0.010027600521177625,\n", " 0.006729486444619793,\n", " 0.014511704544557687,\n", " -0.00942794333168324,\n", " 0.01547115586148419,\n", " 0.00895488082062584,\n", " -0.0016707115688559984,\n", " 0.001046901575960965,\n", " -0.0047073089840970585,\n", " -0.023466585365183527,\n", " -0.011933178722864087,\n", " 0.017416710153638017,\n", " -0.0086617153732845,\n", " 0.01647058513152322,\n", " -0.013685509656490154,\n", " -0.020428322395921652,\n", " 0.024559293110968997,\n", " 0.004660668814901258,\n", " 0.015724344287035584,\n", " 0.015071384712262126,\n", " 0.018589373805648544,\n", " -0.005963257554898472,\n", " 0.0007462400877880405,\n", " 0.001171830118300521,\n", " 0.005750046151137027,\n", " -0.01237958957562066,\n", " 0.017483338833728792,\n", " -0.022173991579125737,\n", " -0.015031406759149596,\n", " 0.025145625868296842,\n", " 0.0010419043318218987,\n", " 0.011326857920302559,\n", " -0.008468492014756739,\n", " 0.014671612631717481,\n", " 0.011773269704381712,\n", " 0.004297543346596862,\n", " 0.010194172221404561,\n", " 0.005030457430611506,\n", " -0.01076717775259812,\n", " 0.0067128292745971,\n", " -0.023693122132434095,\n", " -0.03152864448029622,\n", " -0.0027684173736877912,\n", " -0.008035406525489288,\n", " 0.01595088105428615,\n", " 0.012292972850296202,\n", " -0.012146390126625531,\n", " 0.012233006851949989,\n", " -0.02113458528729676,\n", " -0.013359029869103426,\n", " 0.0044874348985910525,\n", " -0.0006883564685253096,\n", " 0.04965161566266419,\n", " 0.007555680867026037,\n", " 0.005316960661869576,\n", " 0.017496664197217914,\n", " 0.000522617894554751,\n", " -0.024692550471150546,\n", " 0.017270127429967346,\n", " -0.018416138492354468,\n", " 0.0014724915482657842,\n", " 0.04035026607809535,\n", " 0.025878539486650195,\n", " -0.017016938073093374,\n", " -0.013598892931165696,\n", " -0.007768892270787481,\n", " 0.024559293110968997,\n", " 0.013299063870757213,\n", " -0.017936412368229925,\n", " -0.017829807597671783,\n", " 0.0194288940572052,\n", " -0.0027401002777814707,\n", " -0.005286977662696471,\n", " -0.0075690062305151596,\n", " -0.0401104020847105,\n", " 0.015071384712262126,\n", " -0.0008078715237397484,\n", " -0.003851131795348354,\n", " -0.02204073421894419,\n", " -0.0016540543988333048,\n", " -0.02260041438664863,\n", " 0.007275840783173818,\n", " -0.03619264463606976,\n", " 0.019975246998775356,\n", " 0.011933178722864087,\n", " -0.029023409089115375,\n", " -0.007902149165307739,\n", " 0.001842280163976032,\n", " -0.032861214356821385,\n", " 0.0014425086655080004,\n", " -0.00016022090968360585,\n", " 0.02843707633178753,\n", " -0.010753852389108998,\n", " -0.0016290687602145873,\n", " 0.01123357851323354,\n", " 0.008548446989659215,\n", " -0.01728345279345647,\n", " 0.007015989210216574,\n", " -0.0024302774275867904,\n", " 0.026264986203705716,\n", " -0.013992001398643199,\n", " -0.011027029791216655,\n", " -0.0004108068270419369,\n", " 0.006269749297051517,\n", " 0.008455166651267616,\n", " -0.003757851689787399,\n", " -0.002618503076314195,\n", " -0.0022070715355472135,\n", " -0.0085684350348929,\n", " 0.0039277547308866146,\n", " -0.002267037301062781,\n", " 0.018749281892808337,\n", " -0.0012909286976982635,\n", " -0.022826951153899194,\n", " -0.011393486600393332,\n", " -0.006266417956179236,\n", " -0.013965349740342373,\n", " -0.008748332098608957,\n", " -0.014764892970109082,\n", " -0.02629163693068396,\n", " -0.01428516684598454,\n", " 0.0058833035113185755,\n", " 0.001676541531797812,\n", " 0.021720916181979442,\n", " 0.010014275157688502,\n", " -0.014405098842676966,\n", " 0.02157433345830877,\n", " 0.027824094710126604,\n", " -0.02365314604196673,\n", " -0.0009569529276876134,\n", " -0.006299731830563333,\n", " -7.870500903152122e-05,\n", " -0.007608983717966398,\n", " 0.0029150003301891074,\n", " 0.0068960576791854385,\n", " -0.00980772643567162,\n", " 0.027477625946183613,\n", " -0.014165235780614694,\n", " -0.024119544939956987,\n", " -0.03677897553075245,\n", " -0.005889966193063137,\n", " 0.015484481224973312,\n", " -0.012792687019654426,\n", " -0.0025768601512574612,\n", " -0.005413571875472167,\n", " 0.0006854414870544027,\n", " 0.018682653212717563,\n", " 0.02494573982802452,\n", " -0.012219681488460867,\n", " 0.019402241467581793,\n", " -0.004590708793938204,\n", " -0.001802303025770761,\n", " 0.005670092107557131,\n", " -0.02403959089637709,\n", " -0.007195886273932631,\n", " 0.008988195160671227,\n", " -0.001668213063201788,\n", " 0.009041497545950298,\n", " -0.017976390321342454,\n", " -0.01794973959436421,\n", " 0.007062629379412374,\n", " 0.022720344520695893,\n", " 0.0026035115767276415,\n", " -0.015177990414142847,\n", " -0.030355980828285695,\n", " -0.0004659836154306172,\n", " -0.00495050338703161,\n", " -0.0018622687912863286,\n", " 0.007555680867026037,\n", " -0.008588424011449164,\n", " -0.021054631243716863,\n", " 0.00041455467283474455,\n", " -0.011833235702727925,\n", " 0.005690080618452105,\n", " -0.008641726396728234,\n", " 0.005213686300861135,\n", " -0.016883680712911825,\n", " -0.011879875406262435,\n", " -0.03347419597848231,\n", " -0.02098800256362609,\n", " 0.0015932559145149896,\n", " 0.0076689492506513204,\n", " 0.015497807519785016,\n", " -0.015191315777631971,\n", " -0.027211111225820515,\n", " -0.007442412017739463,\n", " -0.040510174165255146,\n", " -0.020041875678866127,\n", " -0.01728345279345647,\n", " -0.0009919329381691407,\n", " 0.0169503093930026,\n", " 0.01647058513152322,\n", " -0.012159715490114653,\n", " 0.032035019468753846,\n", " 0.0069027208265912895,\n", " 0.033314287891322514,\n", " -0.020548252529968915,\n", " -0.019468870147672568,\n", " 0.024545967747479875,\n", " -0.010593944301949206,\n", " 0.007322480486708327,\n", " 0.004217588837355676,\n", " -0.010447360646955953,\n", " -0.0213211441014348,\n", " 0.02246715702646708,\n", " 0.0023070145556833748,\n", " 0.009261372562778885,\n", " 0.02096134997400268,\n", " 0.004827240515128194,\n", " -0.028250517517649495,\n", " -0.008675040736773621,\n", " 0.01861602453262679,\n", " 0.0011318529800952502,\n", " 0.0033064431272304693,\n", " -0.0006021557533562577,\n", " -0.00714258342299227,\n", " 0.0035013316905330803,\n", " 0.0036512459879066766,\n", " 0.0003806157645834662,\n", " -0.0023869688320939165,\n", " -0.0047073089840970585,\n", " 0.004727297494992033,\n", " -0.004414143071094427,\n", " 0.0022104031092501394,\n", " -0.03379401587809222,\n", " -0.006076526404185046,\n", " -0.01000094979419938,\n", " -0.016417281814921567,\n", " 0.00985436707052871,\n", " -0.014165235780614694,\n", " -0.005670092107557131,\n", " 0.03358080261168561,\n", " 0.0038977717317135088,\n", " -0.012466207232267698,\n", " -0.011879875406262435,\n", " 0.02013515694858031,\n", " -0.013912047355063302,\n", " -0.0057766978094378535,\n", " 0.003531314689706187,\n", " -0.011486766938784932,\n", " 0.0016274029733631243,\n", " -0.0008507636434159262,\n", " -0.0008720015235533281,\n", " -0.015151338755842023,\n", " 0.002338662992461976,\n", " -0.0046440116448785655,\n", " -0.006699503445446687,\n", " -0.018269555768683797,\n", " 0.00226204028975436,\n", " 0.014511704544557687,\n", " -0.025771934716092054,\n", " -0.012712732976074531,\n", " -0.020641533799683094,\n", " 0.02013515694858031,\n", " 0.0005276150222784945,\n", " -0.005087092088085439,\n", " -0.009827715412227885,\n", " -0.010207498516216265,\n", " 0.014764892970109082,\n", " 0.023932984263173786,\n", " -0.013485624547540412,\n", " 0.000838270765898906,\n", " 0.013552252296308605,\n", " 0.014405098842676966,\n", " -0.0036212632215642158,\n", " 0.008388537971176842,\n", " 0.23197405199593576,\n", " 0.005710069129347079,\n", " 0.017390059426659773,\n", " 0.03243479154929849,\n", " -0.0063930121689549325,\n", " 0.033687409244888916,\n", " 0.007542355037875624,\n", " -0.010100892814335542,\n", " -0.008435177674711351,\n", " 0.021401100007659855,\n", " 0.01628402445474002,\n", " 0.014591658588137584,\n", " -0.005140394939025799,\n", " 0.005256994663523364,\n", " -0.002038834397714783,\n", " -0.0019338944826855237,\n", " -0.023160094554353066,\n", " -0.02166761286537779,\n", " -0.03517989093386419,\n", " -0.01671044726226291,\n", " 0.0011418472355427373,\n", " -0.022000756265831662,\n", " 0.01917570470033123,\n", " -0.010927086771080495,\n", " 0.014604983951626706,\n", " -0.01613744173106935,\n", " -0.019988574224909638,\n", " -0.001730677334371566,\n", " 0.021640962138399545,\n", " 0.020921373883535314,\n", " -0.013578903954609431,\n", " 0.0012567815224348064,\n", " 0.012739383703052776,\n", " -0.003974394434421124,\n", " -0.03136873266784611,\n", " -0.005650103596662157,\n", " 0.030542539642423733,\n", " -0.003741194752595351,\n", " 0.02557204867581973,\n", " -0.008401863334665964,\n", " 0.006229771809600279,\n", " -0.02438605966032008,\n", " 0.006462972189917988,\n", " -0.014338470162586192,\n", " 0.0044874348985910525,\n", " 0.026957921868946542,\n", " ...]" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query_result = embeddings.embed_query(text)\n", "query_result" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[[-0.0031584087512342572,\n", " 0.011094410212838685,\n", " -0.004001317166816525,\n", " -0.011747414500761147,\n", " -0.0010153218392504927,\n", " 0.010781234363886399,\n", " -0.010368109905383128,\n", " -0.0052973312542353886,\n", " -0.00988168756470157,\n", " -0.026160153195893116,\n", " 0.02037639960097617,\n", " 0.022575293225485345,\n", " -0.007522876537439858,\n", " 0.01728462465309313,\n", " -0.0060036416535162295,\n", " 0.01912369806781222,\n", " 0.02125595742330888,\n", " -0.015645450320121206,\n", " 0.007669469042167345,\n", " -0.018364081557173,\n", " -0.0006909018997805782,\n", " -0.006416767043342096,\n", " -0.010981134376956157,\n", " 0.017950956167347133,\n", " -0.022135513382996398,\n", " -0.0030767832152439494,\n", " 0.014379421560625712,\n", " -0.029984892064397486,\n", " 0.018524000822570733,\n", " -0.007916012019091008,\n", " 0.010068260351439788,\n", " -0.019456863824939222,\n", " -0.003688141783525537,\n", " -0.02424112014847516,\n", " -0.005530547004827511,\n", " 0.0038247395669963142,\n", " -0.005653818260458694,\n", " -0.029451827225523322,\n", " 0.018603960455269596,\n", " -0.016618293138839127,\n", " 0.0075295396849443304,\n", " 0.012420408696858325,\n", " -0.000990334337616773,\n", " -0.01072126463936225,\n", " 0.010001627945072464,\n", " -0.012560338054081339,\n", " 0.03352977408110101,\n", " -0.026999729339231202,\n", " -0.007929338314099954,\n", " 0.029025376472011102,\n", " 0.01969674272303582,\n", " -0.002077286642354891,\n", " -0.02739952936537072,\n", " -0.008775579001926404,\n", " -0.006213536155012048,\n", " 0.0019939954359037893,\n", " -0.007382946714555546,\n", " 0.027985899384280664,\n", " 0.006829892433167963,\n", " -0.009315306522643745,\n", " -0.022482006366454938,\n", " 0.010468059446256709,\n", " -0.013546508099130803,\n", " -0.011094410212838685,\n", " -0.0048875376709924066,\n", " -0.008275830366235902,\n", " -0.0058237324799437825,\n", " 0.0111144001210134,\n", " 0.006276837686119082,\n", " 0.004434432464817108,\n", " 0.010568008987130291,\n", " 0.012480378421382474,\n", " 0.005337311070584821,\n", " 0.005393948988526085,\n", " 0.008988804378682514,\n", " 0.0042611864387491335,\n", " -0.022681905448202103,\n", " -0.013233332250178519,\n", " 0.011201023366878036,\n", " -0.005753767801332276,\n", " 0.009828381453343192,\n", " -0.024401039413872894,\n", " -0.008582342602022416,\n", " 0.007829388773226373,\n", " 0.0025037385600203523,\n", " 0.007549529593119047,\n", " 0.005747104653827803,\n", " 0.028172473102341476,\n", " -0.022908457119967154,\n", " -0.015525510871072908,\n", " -0.00818254443852809,\n", " 0.020056561070180712,\n", " 0.003568202334477239,\n", " 0.01278689065716899,\n", " -0.016458373873441397,\n", " 0.03155743399100209,\n", " 0.013506528282781372,\n", " 0.030437997270572784,\n", " -0.006240189210691237,\n", " -0.0496816347874333,\n", " -0.003728121599874969,\n", " -0.0013001782635708487,\n", " -0.0070631081837600855,\n", " 0.003524890711544921,\n", " -0.03483578265694594,\n", " -0.009062101329538204,\n", " 0.021975594117598665,\n", " -0.007236354209828059,\n", " 0.015485531054723474,\n", " -0.008295820274410618,\n", " -0.016445048509755048,\n", " 0.005060783697060381,\n", " -0.0063901139876629065,\n", " -0.03611513678012778,\n", " 0.015618797730103313,\n", " 0.005653818260458694,\n", " 0.006503389823545434,\n", " -0.0218956344848998,\n", " -0.010248169525012235,\n", " 0.0010503041785562463,\n", " 0.0006350967006543871,\n", " 0.016938133532279777,\n", " 0.02651997154303801,\n", " -0.027506141588087472,\n", " 0.010548019078955573,\n", " 0.01327331206652795,\n", " -0.008822221500119012,\n", " -0.041872237785026835,\n", " -0.006493394869458076,\n", " -0.005567195014594058,\n", " 0.01913702529414376,\n", " 0.021482509095073935,\n", " 0.014192848773887495,\n", " 0.017511178187503376,\n", " -0.023348236962456106,\n", " 0.03734118572327384,\n", " -0.04040630994378418,\n", " 0.02477418498734933,\n", " -0.04320489708824446,\n", " -0.008409096110293146,\n", " 0.008309146569419563,\n", " 0.027372874912707637,\n", " -0.019150350657830113,\n", " -0.01696478612229767,\n", " 0.010288150272684262,\n", " 0.013992949692140332,\n", " 0.008262504071226955,\n", " -0.02484081739371665,\n", " 0.012493705647714015,\n", " -0.021056058341561715,\n", " 0.0031051021742145813,\n", " 0.0017724403098598187,\n", " 0.017764382449286322,\n", " 0.002560376710792265,\n", " 0.015565490687422339,\n", " 0.03147747435830322,\n", " 0.003858056235841274,\n", " -0.009548522738897164,\n", " -0.018004261347382918,\n", " -0.019616783090336952,\n", " 0.0031034365037537876,\n", " 0.022162167835659476,\n", " 0.00956851264707188,\n", " 0.0018540658458501265,\n", " 0.023454849185172863,\n", " 0.03467586339154821,\n", " 0.00400464897339941,\n", " 0.007669469042167345,\n", " -0.001613353763277161,\n", " -0.015418897717033555,\n", " -0.025027391111777462,\n", " 0.024760857761017788,\n", " -0.025387209458922356,\n", " 0.0076494791339926285,\n", " -0.02017650051922901,\n", " 0.014299461927926848,\n", " 0.007189710780312856,\n", " 0.003481579088612603,\n", " -0.004424437510729749,\n", " -0.0040546237438362,\n", " -0.03390291779193226,\n", " 0.016844846673249373,\n", " 0.014792546950451579,\n", " 0.031850618069134466,\n", " -0.017004765938647103,\n", " -0.006936505121546017,\n", " 0.02424112014847516,\n", " -0.009541859125731394,\n", " 0.0013884670634809538,\n", " -0.004634331546564271,\n", " 0.02314833788070894,\n", " 0.021935614301249233,\n", " -0.006290163981128028,\n", " -0.014805873245460526,\n", " -0.7023661288825848,\n", " -0.01635176165072464,\n", " 0.0042611864387491335,\n", " -0.017311277243111024,\n", " 0.02217549319934583,\n", " 0.031370860272941274,\n", " 0.02464091831196949,\n", " 0.0020939449767773707,\n", " -0.005986983551924398,\n", " 0.021855654668550367,\n", " -0.022668578221870562,\n", " -0.012700267411304355,\n", " -0.009202030686761217,\n", " -0.013206679660160626,\n", " -0.014139542662529116,\n", " -0.02314833788070894,\n", " -0.01695145889596613,\n", " -0.0033249913969671096,\n", " -0.017604463183888593,\n", " 0.013106730119287044,\n", " 0.014979119737189796,\n", " 0.015472204759714529,\n", " -0.01571208458913372,\n", " -0.016711579997869534,\n", " 0.0005126583966689254,\n", " 0.008935498267324135,\n", " 0.013100066506121274,\n", " -0.006123581568225824,\n", " 0.017484523734840295,\n", " 0.016884826489598805,\n", " -0.026240112828591983,\n", " -0.0035215591377926844,\n", " -0.0009320303999687423,\n", " 0.008535699172507214,\n", " 0.033236586277678254,\n", " -0.002067291688267533,\n", " -0.014472708419656118,\n", " -0.025040716475463815,\n", " 0.016604967775152777,\n", " 0.0009203696007976038,\n", " -0.01680486685689994,\n", " -0.0003496155334959091,\n", " 0.004830899287389846,\n", " -0.0017291288033428253,\n", " -0.004571030481118534,\n", " -0.0024737536977582778,\n", " 0.01883051212703465,\n", " 0.0003673149410602162,\n", " 0.0274528345454065,\n", " 0.017684422816587456,\n", " -0.016578313322489695,\n", " -0.0005447255216299788,\n", " 0.006663309554604462,\n", " -0.0035182273312097992,\n", " 0.0010453067015125672,\n", " -0.010421416016741507,\n", " 0.02160244854412223,\n", " 0.00775609228803198,\n", " 0.010834541406567373,\n", " 0.016604967775152777,\n", " -0.001151086671075549,\n", " 0.011860691267966269,\n", " -0.005657149601380282,\n", " -0.016871499263267264,\n", " -0.028945416839312236,\n", " -0.007496223016099372,\n", " -0.020776199627115688,\n", " 0.02253531340913591,\n", " 0.0010594661809978831,\n", " -0.01899043139243238,\n", " -0.0037581064621370437,\n", " 0.012520358237731908,\n", " -0.010261496751343776,\n", " -0.01972339531305371,\n", " 0.020749545174452606,\n", " 0.015485531054723474,\n", " 0.009761748115653274,\n", " -0.00994832090239149,\n", " -0.009355286338993176,\n", " 0.01677821240423686,\n", " 0.0037014683113651315,\n", " 0.0036215086786662663,\n", " -0.014366095265616767,\n", " -0.015418897717033555,\n", " 0.010847867701576318,\n", " -0.020283114604590955,\n", " -0.04611010204335707,\n", " -0.01296013714889826,\n", " -0.0066999575643710094,\n", " 0.013386588833733074,\n", " 0.02160244854412223,\n", " 0.001438441950333069,\n", " -0.007955991835440442,\n", " -0.00046601519998437115,\n", " 0.008908844745983647,\n", " -0.002800255841719509,\n", " 0.0011885678653184664,\n", " 0.003934684294787902,\n", " 0.03009150614975943,\n", " -0.0019306939047967551,\n", " 0.0015000775781486605,\n", " 0.00244710040924844,\n", " 0.0006804904698703595,\n", " 0.011740750887595377,\n", " 0.02112269074792904,\n", " 0.0052240347690409965,\n", " 0.003648161967176104,\n", " 0.024467671820240216,\n", " 0.018270794698142596,\n", " -0.008495719356157781,\n", " -0.0071697208721381404,\n", " -0.008995467991848284,\n", " -0.009535195512565623,\n", " 0.0015650447797164885,\n", " -0.016071902936278613,\n", " -0.03416945114269194,\n", " 0.007989308038624103,\n", " 0.011241003183227469,\n", " 0.0023404874880397367,\n", " 0.0033899585985349375,\n", " 0.014059583029830252,\n", " 0.01772440263293689,\n", " 0.013299965587868438,\n", " -0.001631677884575759,\n", " 0.0045843567761274795,\n", " -0.002488746128889315,\n", " 0.003974664111137336,\n", " -0.01943021123492133,\n", " -0.017204665020394267,\n", " -0.009701778391129125,\n", " -0.019456863824939222,\n", " -0.0017857669541147378,\n", " 0.03371634779916183,\n", " -0.014166196183869604,\n", " 0.007702785711012305,\n", " 0.0023038392454425407,\n", " 0.003831402947331436,\n", " -0.005277340880399375,\n", " 0.021349244282339284,\n", " -0.009748421820644327,\n", " -0.013020106873422409,\n", " 0.013313291882877384,\n", " -0.006963158177225206,\n", " -0.009068764011381378,\n", " -0.01195397719567408,\n", " -0.022308759874725668,\n", " -0.01801758857371446,\n", " -0.0030268084448071587,\n", " 0.0009944989794300552,\n", " 0.00994165728922572,\n", " -0.022068880976629072,\n", " 0.0014101228749471128,\n", " -0.010128230075963937,\n", " -0.005847054194701384,\n", " -0.008095921192663455,\n", " -0.011081083917829738,\n", " -0.017044745754996534,\n", " -0.026293419871272955,\n", " 0.0010411420596992851,\n", " -0.001472591337993101,\n", " -0.008648975939712335,\n", " 0.0175778105938707,\n", " -0.006223531109099406,\n", " 0.0011360942399445118,\n", " -0.02653329876936955,\n", " -0.018310774514492027,\n", " -0.03302336183224474,\n", " 0.03318328109764247,\n", " -0.009988300718740923,\n", " -0.033876267064559554,\n", " -0.01835075433084146,\n", " 0.005207376201787868,\n", " -0.013473212079597709,\n", " -0.0020423043030491374,\n", " 0.005070778651147739,\n", " -0.010587998895305007,\n", " -0.015685430136470637,\n", " 0.007862704976410034,\n", " 0.010328130089033695,\n", " -0.021349244282339284,\n", " -0.004967497303691272,\n", " 0.0034749159411081305,\n", " 0.012227173228276933,\n", " 0.002070623494850418,\n", " 0.011760740795770093,\n", " 0.015059079369888661,\n", " 0.013479874761440884,\n", " 0.007049781423089842,\n", " -0.012600317870430772,\n", " 0.002543718376369785,\n", " 0.00800263433363305,\n", " 0.0033033355855009504,\n", " -0.014659281206394335,\n", " 0.009321970135809515,\n", " -0.007702785711012305,\n", " 0.019856661988433548,\n", " -0.029718360576282996,\n", " 0.010421416016741507,\n", " 0.01288684019804257,\n", " 0.023841321984980835,\n", " 0.022588618589171695,\n", " 0.008655638621555512,\n", " 0.0038880410981033484,\n", " -0.022748537854569425,\n", " 0.00016585394401008583,\n", " -0.035422154538501074,\n", " -0.013126720027461762,\n", " -0.002710301022102637,\n", " 0.013533181804121858,\n", " 0.00628683264020644,\n", " 0.01288684019804257,\n", " -0.0175778105938707,\n", " -0.02468089812831892,\n", " 0.017364584285791997,\n", " 0.021549143364086448,\n", " 0.005447255565545761,\n", " -0.010128230075963937,\n", " -0.002821911653185668,\n", " -0.006803238911827476,\n", " -0.0020256459686266576,\n", " 0.006739937380720442,\n", " 0.004847557854642974,\n", " 0.012520358237731908,\n", " -0.007276334026177492,\n", " -0.016258474791694233,\n", " 0.011507535602664551,\n", " 0.028598923855853695,\n", " 0.03262356366875042,\n", " 0.02300174397899756,\n", " -0.024147833289444757,\n", " -0.018390734147190894,\n", " 0.0025986906238502547,\n", " 0.0008878860000136897,\n", " 0.0012443730644446575,\n", " 0.0031684037053216155,\n", " 0.010474722128099884,\n", " 0.02240204673375607,\n", " -0.01941688400858979,\n", " 0.028758843121251425,\n", " 0.0003606516189327567,\n", " 0.011480882081324065,\n", " 0.018857166579697732,\n", " 0.028625578308516777,\n", " -0.008495719356157781,\n", " 0.022921784346298695,\n", " -0.00012087659968526976,\n", " 0.028172473102341476,\n", " 0.008575678988856646,\n", " -0.004051291937253315,\n", " 0.03153077953833901,\n", " -0.010707938344353305,\n", " 0.0018573975360176873,\n", " 0.0009944989794300552,\n", " 0.004204548055146573,\n", " 0.032463644403352684,\n", " -0.02685313730016501,\n", " -0.013399915128742019,\n", " 0.0019190331638332789,\n", " 0.014326115449267334,\n", " 0.03115763582750776,\n", " 0.02221547301569526,\n", " 0.0050208038807109485,\n", " -0.002633672963156008,\n", " 0.0012277147300221777,\n", " 0.023188317697058373,\n", " -0.004537713812273574,\n", " -0.013226669568335342,\n", " 0.0034066169329574174,\n", " -0.019976601437481846,\n", " -0.013040096781597127,\n", " -0.005637159693205566,\n", " -0.0014459381658985875,\n", " 0.01805756839006389,\n", " 0.0024820827485541935,\n", " 0.02464091831196949,\n", " 0.010581335282139236,\n", " 0.02590694707146498,\n", " 0.012020610533364,\n", " 0.016458373873441397,\n", " 0.0014925813625831419,\n", " -0.009102081145887635,\n", " -0.022428699323773966,\n", " 0.0006725777784819802,\n", " 0.012207183320102217,\n", " 0.012280479339635312,\n", " -0.011687444776236998,\n", " -0.010228179616837519,\n", " 0.0046576532613218724,\n", " -0.007462906812915709,\n", " 0.006500058482623847,\n", " 0.004001317166816525,\n", " -1.1660791895180796e-05,\n", " 0.01709805279767751,\n", " -0.02316166324439529,\n", " -5.3124274259723366e-05,\n", " 0.015978616077248205,\n", " 0.008835548726450553,\n", " -0.0055572000605067,\n", " -0.010148219984138653,\n", " -0.007816062478217426,\n", " 0.011201023366878036,\n", " -0.007576182648798236,\n", " 0.00879556891010112,\n", " 0.00620354120092469,\n", " 0.020149847929211116,\n", " 0.0002575785675953825,\n", " -0.002617014861564177,\n", " -0.01295347353573249,\n", " -0.013466548466431938,\n", " -0.010301476567693209,\n", " 0.01801758857371446,\n", " 0.0038114130391567196,\n", " -0.014006276918471873,\n", " -0.005980320404419925,\n", " 0.015565490687422339,\n", " -0.005697129417729715,\n", " 0.0015317282272868532,\n", " 0.013319955496043154,\n", " 0.01681819222058629,\n", " 0.012826870473518421,\n", " -0.015352265310666231,\n", " -0.00684988234134268,\n", " -0.018097548206413325,\n", " 0.01072126463936225,\n", " 0.04882873328040887,\n", " 0.04315159190820868,\n", " 0.0025637082845445013,\n", " -0.010941154560606724,\n", " 0.003691473357277773,\n", " -0.019363576965908815,\n", " -0.026959749522881767,\n", " -0.013499864669615601,\n", " 0.006393445328584495,\n", " -0.0021755705127676785,\n", " -0.00785604229456686,\n", " -0.0043211561632732825,\n", " 0.016285129244357315,\n", " 0.001352651772529479,\n", " 0.016618293138839127,\n", " 0.007116414295118464,\n", " -0.0014392749019787902,\n", " -0.0024820827485541935,\n", " -0.009448573198023582,\n", " -0.012260489431460596,\n", " 0.0029385195284817294,\n", " 0.007702785711012305,\n", " 0.007629489225817913,\n", " 0.0033932904051178227,\n", " 0.012073916644722378,\n", " -0.021349244282339284,\n", " 0.0077227756191870205,\n", " 0.0016916477255152322,\n", " 0.00025570451370400283,\n", " -0.02036307423728982,\n", " -0.014152868957538063,\n", " 0.019230310290528976,\n", " 0.010101577485946044,\n", " 0.018097548206413325,\n", " -0.0006234359014832486,\n", " 0.03286344256684701,\n", " -0.004447759225487351,\n", " -0.01573873717915161,\n", " 0.00778940895687694,\n", " 0.004840894241477204,\n", " 0.009222020594935933,\n", " 0.004571030481118534,\n", " -0.00339162450182638,\n", " -0.008269166753070132,\n", " -0.007129741055788707,\n", " 0.00024820826903465315,\n", " -0.016604967775152777,\n", " 0.0033999535526222954,\n", " -0.008662302234721283,\n", " -0.00755619274062352,\n", " 0.012080580257888149,\n", " -0.01773772985926843,\n", " -0.0012060590349713433,\n", " -0.015445551238374041,\n", " 0.028732190531233534,\n", " 0.02326827732975724,\n", " 0.004401115795972148,\n", " 0.006843218728176909,\n", " -0.0021672414619717632,\n", " -0.017564483367539158,\n", " -0.02987827984168073,\n", " -0.0067499323348078006,\n", " -0.011367606245441537,\n", " -0.009301980227634798,\n", " -0.011380932540450483,\n", " -0.030411344680554894,\n", " -0.023494829001522295,\n", " -0.013333282722374695,\n", " -0.02017650051922901,\n", " 0.0037381165539623275,\n", " 0.010987797058799332,\n", " -0.01759113782020224,\n", " -0.024760857761017788,\n", " -0.016231822201676342,\n", " 0.02899872201934802,\n", " -0.0139529698757909,\n", " 0.0005209875056725032,\n", " 0.013106730119287044,\n", " 0.0015358928691001352,\n", " 0.022588618589171695,\n", " -0.010861193996585264,\n", " -0.02249533359278648,\n", " 0.005863712296293216,\n", " -0.024147833289444757,\n", " -0.005843722388118499,\n", " 0.016858173899580914,\n", " -0.00397133230455445,\n", " 0.006753264141390686,\n", " -0.0027519467417435124,\n", " 0.010421416016741507,\n", " -0.006043621469865662,\n", " -0.0024654244141317136,\n", " -0.004880874057826637,\n", " -0.029371867592824456,\n", " 0.01635176165072464,\n", " -0.008728935572411202,\n", " 0.0019939954359037893,\n", " 0.007442916904740993,\n", " -0.008668965847887053,\n", " -0.004154573284709782,\n", " -0.015538838097404448,\n", " -0.0015217332731994949,\n", " -0.009128733735905527,\n", " 0.0016108550247553213,\n", " 0.020749545174452606,\n", " -0.019030411208781815,\n", " -0.013373262538724128,\n", " 0.016911479079616695,\n", " -0.02329492991977513,\n", " -0.0077094488585167775,\n", " -0.010488049354431424,\n", " -0.018137528022762757,\n", " 0.009601828850255543,\n", " -0.020003255890144928,\n", " 0.002393793832228764,\n", " 0.01741789132847297,\n", " -0.007442916904740993,\n", " 0.021948941527580774,\n", " -0.010301476567693209,\n", " -0.03019811837247619,\n", " 7.584720315855387e-05,\n", " -0.009808391545168476,\n", " 0.011094410212838685,\n", " 0.03563537898393459,\n", " 0.022068880976629072,\n", " 0.029211948327426726,\n", " -0.008762251775594863,\n", " -0.003048464023442669,\n", " -0.014206176000219036,\n", " 0.007909348405925238,\n", " -0.005074109992069326,\n", " 0.001172742482541708,\n", " -0.0077960721043814135,\n", " -0.004184558146971856,\n", " -0.01884383935336619,\n", " -0.011447565878140402,\n", " -0.0015292294887650135,\n", " 0.013646457640004385,\n", " -0.005264014585390429,\n", " -0.010661294914838101,\n", " -0.015059079369888661,\n", " 0.013673111161344871,\n", " 0.01139425883545943,\n", " -0.009168713552254959,\n", " -0.02572037521604936,\n", " -0.029824972798999753,\n", " -0.021655755586803205,\n", " 0.010108240167789221,\n", " -0.020602953135386418,\n", " 0.000884554309846129,\n", " 0.021096038157911147,\n", " 0.0003396205503047198,\n", " -0.011647464959887565,\n", " -0.004904195772584238,\n", " 0.015818696811850476,\n", " -0.029371867592824456,\n", " -0.004824236139885373,\n", " 0.006163561384575258,\n", " 0.016231822201676342,\n", " 0.0271196687882795,\n", " 0.022681905448202103,\n", " -0.01163413866487862,\n", " 0.011707434684411714,\n", " 0.01986998921476509,\n", " -0.00342494117067134,\n", " 0.009635145053439206,\n", " -0.009441909584857812,\n", " -0.013779724315384224,\n", " -0.01637841424074253,\n", " 0.0025637082845445013,\n", " 0.010008290626915639,\n", " 0.0067599272888951584,\n", " 0.014486034714665065,\n", " -0.009415256063517325,\n", " 0.015485531054723474,\n", " 0.009002130673691459,\n", " -0.0016783210812603131,\n", " 0.0010244838416921295,\n", " -0.0046709800219921155,\n", " -0.023508156227853835,\n", " -0.011907333766158877,\n", " 0.01741789132847297,\n", " -0.00862898603153762,\n", " 0.016551660732471805,\n", " -0.01363979495816121,\n", " -0.020389726827307712,\n", " 0.024547631452939082,\n", " 0.0046443265006516285,\n", " 0.015698757362802178,\n", " 0.015045753074879716,\n", " 0.018590633228938055,\n", " -0.005986983551924398,\n", " 0.0007916844505075432,\n", " 0.0011752412210635475,\n", " 0.005747104653827803,\n", " -0.01234044906415946,\n", " 0.017471198371153945,\n", " -0.02221547301569526,\n", " -0.015059079369888661,\n", " 0.025080696291813247,\n", " 0.0010053267687478102,\n", " 0.011334289110935281,\n", " -0.008489056674314606,\n", " 0.014699261022743769,\n", " 0.011847364041634728,\n", " 0.004257854632166248,\n", " 0.010148219984138653,\n", " 0.005030798834798306,\n", " -0.010767908068877454,\n", " 0.006743269187303327,\n", " -0.023681402719583106,\n", " -0.0315041288109663,\n", " -0.0027719366499182286,\n", " -0.00801596155996459,\n", " 0.015978616077248205,\n", " 0.012300469247810027,\n", " -0.012140549982412298,\n", " 0.012200519706936447,\n", " -0.021136017974260582,\n", " -0.013393252446898844,\n", " 0.004514392097515973,\n", " -0.0007025626989517168,\n", " 0.04962832960739752,\n", " 0.007536202832448804,\n", " 0.005323984309914578,\n", " 0.017511178187503376,\n", " 0.000552638213018358,\n", " -0.024707550718336812,\n", " 0.017231317610412158,\n", " -0.018364081557173,\n", " 0.0014717585027627042,\n", " 0.040379655491121096,\n", " 0.02589361984513344,\n", " -0.017044745754996534,\n", " -0.013606477823654952,\n", " -0.0077361023798572645,\n", " 0.024534306089252732,\n", " 0.013326619109208925,\n", " -0.017950956167347133,\n", " -0.017817689491967294,\n", " 0.01944353659860768,\n", " -0.0027286252598165595,\n", " -0.005277340880399375,\n", " -0.007569519501293764,\n", " -0.040113122140361425,\n", " 0.015085732891229149,\n", " -0.000767529958727207,\n", " -0.003831402947331436,\n", " -0.022068880976629072,\n", " -0.0016899818222237896,\n", " -0.022588618589171695,\n", " 0.007322976990031397,\n", " -0.03619509641282665,\n", " 0.019936621621132414,\n", " 0.011894007471149931,\n", " -0.02899872201934802,\n", " -0.007876032202741575,\n", " 0.0018640607999374846,\n", " -0.03286344256684701,\n", " 0.0014317785699979471,\n", " -0.00015939885979405666,\n", " 0.028465657180473856,\n", " -0.010747918160702738,\n", " -0.001590865116580605,\n", " 0.011227676888218524,\n", " 0.008529036490664037,\n", " -0.0172446448367437,\n", " 0.007029791514915126,\n", " -0.0024487663125398827,\n", " 0.026293419871272955,\n", " -0.013992949692140332,\n", " -0.01102111419330559,\n", " -0.00037626876379808486,\n", " 0.006300158935215386,\n", " 0.008462403152974118,\n", " -0.0037414483605452127,\n", " -0.002617014861564177,\n", " -0.002217216232408554,\n", " -0.008595668897031363,\n", " 0.003914694386613187,\n", " -0.0022521985717143074,\n", " 0.018750552494335788,\n", " -0.0013176694332237254,\n", " -0.022855151939931373,\n", " -0.011407586061790969,\n", " -0.006263510925448839,\n", " -0.013979623397131387,\n", " -0.008742261867420147,\n", " -0.014792546950451579,\n", " -0.026240112828591983,\n", " -0.014246155816568469,\n", " 0.005870375443797688,\n", " 0.0016699919140490734,\n", " 0.021709062629484178,\n", " 0.009974974423731978,\n", " -0.014406075081966199,\n", " 0.021549143364086448,\n", " 0.027852632708900826,\n", " -0.023694728083269456,\n", " -0.0009420253540561005,\n", " -0.006356797318817948,\n", " -5.944921341908747e-05,\n", " -0.0076161629308089665,\n", " 0.0029018712858845334,\n", " 0.006876535397021868,\n", " -0.009801727932002706,\n", " 0.0274528345454065,\n", " -0.014152868957538063,\n", " -0.024174485879462648,\n", " -0.036728163114346,\n", " -0.0058603804897103305,\n", " 0.01551218457606396,\n", " -0.01279355427033476,\n", " -0.0024937436059329944,\n", " -0.005430596998292632,\n", " 0.0006709119916058619,\n", " 0.018697247314300003,\n", " 0.02497408406909649,\n", " -0.012200519706936447,\n", " 0.019390231418571897,\n", " -0.004587688582710365,\n", " -0.001805756862289454,\n", " 0.005710456178399958,\n", " -0.024001241250378568,\n", " -0.007203037540983099,\n", " 0.008988804378682514,\n", " -0.0016566652697941543,\n", " 0.009028784195031945,\n", " -0.017964281531033487,\n", " -0.017950956167347133,\n", " 0.0070631081837600855,\n", " 0.022735212490883075,\n", " 0.0026203464353164135,\n", " -0.015232325861617933,\n", " -0.030358037637873918,\n", " -0.00045768606187696233,\n", " -0.0049475073955165556,\n", " -0.0018623950130613664,\n", " 0.007576182648798236,\n", " -0.008589006215188186,\n", " -0.021042731115230175,\n", " 0.000430616384855757,\n", " -0.011854027654800498,\n", " 0.005647154647292924,\n", " -0.00862898603153762,\n", " 0.005214039814953638,\n", " -0.016831519446917832,\n", " -0.011880681176140986,\n", " -0.03347646517577485,\n", " -0.020962771482531308,\n", " 0.0015800372108475257,\n", " 0.007689458950342062,\n", " 0.015458877533382988,\n", " -0.015179018818936959,\n", " -0.027199628420978363,\n", " -0.007422926530904979,\n", " -0.04048626957648305,\n", " -0.02004323570649436,\n", " -0.017217992246725808,\n", " -0.0010144888876047714,\n", " 0.016938133532279777,\n", " 0.016458373873441397,\n", " -0.012160539890587014,\n", " 0.03203719178719528,\n", " 0.006903188452701057,\n", " 0.033316545910377124,\n", " -0.02052299350268755,\n", " -0.01943021123492133,\n", " 0.024534306089252732,\n", " -0.010594662508470777,\n", " 0.007263007265507248,\n", " 0.004221206622399701,\n", " -0.010461395833090938,\n", " -0.021349244282339284,\n", " 0.022468679140123397,\n", " 0.0023488165388356524,\n", " 0.009235346889944878,\n", " 0.021042731115230175,\n", " 0.004810909379215129,\n", " -0.02822577828237726,\n", " -0.008682292142895998,\n", " 0.018590633228938055,\n", " 0.001141091716988191,\n", " 0.0033066673920838356,\n", " -0.0005917851941373937,\n", " -0.0071230779082842345,\n", " 0.0035015692296179683,\n", " 0.003654825347511226,\n", " 0.0003721041801924649,\n", " -0.002355479919170774,\n", " -0.004674311828575001,\n", " 0.0047309497465162645,\n", " -0.004387789500963202,\n", " 0.002200557897986074,\n", " -0.03382295815923339,\n", " -0.006120249761642939,\n", " -0.010001627945072464,\n", " -0.016458373873441397,\n", " 0.009895014791033111,\n", " -0.014139542662529116,\n", " -0.005670476362050526,\n", " 0.03355642480847372,\n", " 0.003901367625942943,\n", " -0.0124737157395393,\n", " -0.011887343857984161,\n", " 0.020123195339193226,\n", " -0.013873010243092034,\n", " -0.005813737525856425,\n", " 0.003534885665632279,\n", " -0.011414248743634146,\n", " 0.001613353763277161,\n", " -0.000857068186105894,\n", " -0.0008274997414590181,\n", " -0.01511238548124704,\n", " 0.0023571458224622165,\n", " -0.004654321454738987,\n", " -0.006696626223449422,\n", " -0.018297447288160486,\n", " 0.002287180911020061,\n", " 0.014486034714665065,\n", " -0.02573370057973571,\n", " -0.012666951208120692,\n", " -0.02062960572540431,\n", " 0.02017650051922901,\n", " 0.0005101596581470859,\n", " -0.005104094854331401,\n", " -0.00988168756470157,\n", " -0.010221516934994342,\n", " 0.014779220655442633,\n", " 0.02390795439134816,\n", " -0.013513191895947142,\n", " 0.0008241681094991194,\n", " 0.01356649800730552,\n", " 0.014419401376975146,\n", " -0.003648161967176104,\n", " 0.008382443520275253,\n", " 0.23198977615478417,\n", " 0.005717119325904431,\n", " 0.017337931695774106,\n", " 0.0324369899506896,\n", " -0.006416767043342096,\n", " 0.033663038893835665,\n", " 0.007542866445614574,\n", " -0.010101577485946044,\n", " -0.008415759723458916,\n", " 0.02138922409868872,\n", " 0.016245149428007883,\n", " 0.01456599434736393,\n", " -0.005157401431351077,\n", " 0.005254019631303071,\n", " -0.0020373068260054585,\n", " -0.0019356913818404343,\n", " -0.02314833788070894,\n", " -0.021709062629484178,\n", " -0.035208926367777185,\n", " -0.016711579997869534,\n", " 0.0011485879325537096,\n", " -0.022002248570261746,\n", " 0.01913702529414376,\n", " -0.010961144468781442,\n", " 0.014605974163713363,\n", " -0.01620516774901326,\n", " -0.019989928663813387,\n", " -0.0016983109894350295,\n", " 0.02161577577045377,\n", " 0.020882811849832445,\n", " -0.013593151528646007,\n", " 0.0012893503578377693,\n", " 0.012740248158976382,\n", " -0.00397133230455445,\n", " -0.03131755509290549,\n", " -0.005627164739118207,\n", " 0.03051795690327165,\n", " -0.0037581064621370437,\n", " 0.02557378131433798,\n", " -0.008429086949790457,\n", " 0.006250184164778595,\n", " -0.024334407007505568,\n", " 0.00644675190560417,\n", " -0.014326115449267334,\n", " 0.004461085520496297,\n", " 0.026946424159195417,\n", " ...]]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc_result = embeddings.embed_documents([text])\n", "doc_result" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面这个例子是使用HuggingFace Hub的embeddings模型,让我们看看它的一个代码样例:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "from langchain.embeddings import HuggingFaceEmbeddings" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#使用前需要保证库中有sentence_transformers\n", "%pip install sentence_transformers" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "于此同时将会下载安装相关依赖文件以及众多json格式的解析处理文件,安装之后就可以正常使用HuggingFaceEmbeddings了" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "embeddings_hf = HuggingFaceEmbeddings()" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "text_hf = \"I just test the embeddings method in huggingface\"" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[-0.02886896708001464,\n", " 0.0044634718471356595,\n", " 0.006389421280895015,\n", " -0.009913570977266759,\n", " -0.0027808003958931854,\n", " 0.023057329930755516,\n", " 0.018016073486322687,\n", " -0.007974105724918213,\n", " -0.02111110793326557,\n", " -0.030896281195072053,\n", " -0.003899202602766403,\n", " 0.009474319213141963,\n", " -0.002067861337994345,\n", " -0.0010989737706240251,\n", " -0.008920186017807362,\n", " 0.00898100603730552,\n", " 0.01804310419217851,\n", " 0.010190636643611502,\n", " 0.007784889852604894,\n", " -0.026733528278888818,\n", " 0.019691986562609287,\n", " -0.01051500790784905,\n", " -0.010170363614219635,\n", " -0.010170363614219635,\n", " -0.016096882194688564,\n", " 0.011109686230644828,\n", " 0.03597808556093373,\n", " -0.027652577865922144,\n", " -0.006450240834731895,\n", " -0.009197252615474662,\n", " 0.014083082501236506,\n", " -0.012393653140699437,\n", " -0.005676482222996175,\n", " -0.025692840515504287,\n", " -0.014461514245863142,\n", " -0.002672677106808614,\n", " 0.0069536905252642715,\n", " -0.025300891555304628,\n", " 0.025963147574062522,\n", " -0.0059940948794472105,\n", " -0.00814980624430362,\n", " 0.0155832950581377,\n", " -0.010940743387723377,\n", " -0.035086064817111115,\n", " -0.01600227286154807,\n", " 0.01851614340730053,\n", " -0.006511060388568775,\n", " -0.01908379195556304,\n", " -0.008311991410761116,\n", " 0.002961569405457198,\n", " 0.0017958632305056508,\n", " 0.0202596351108718,\n", " -0.019475740915762704,\n", " 0.003885687249838491,\n", " -0.0010710981223795684,\n", " 0.017353817467564793,\n", " 0.009433773154358227,\n", " 0.00968380811484715,\n", " -0.00799437875431008,\n", " 0.0015576537381673744,\n", " -0.011535422641841713,\n", " -0.0015263992516909397,\n", " -0.003103481542522826,\n", " 0.010325791104213175,\n", " -0.015096739558765213,\n", " -0.014110113207092328,\n", " 0.023516855655594734,\n", " 0.01372492285467918,\n", " 0.03797836897013532,\n", " 0.026922745082524693,\n", " 0.0035444224929329715,\n", " 0.014218236030515622,\n", " -0.022219372461289657,\n", " -0.005862319257077516,\n", " 0.04646606276292695,\n", " 0.007460519519689903,\n", " 0.009501349918997785,\n", " 0.0052304727824074235,\n", " 0.00515951671387461,\n", " 0.016448283233459378,\n", " -0.0019310175746920033,\n", " -0.011900339033540439,\n", " -0.009285103340828644,\n", " 0.0047675691506587825,\n", " 0.010961016417115246,\n", " 0.00806871412673615,\n", " -0.00456821676364953,\n", " 0.015029162794125655,\n", " -0.000812193129455108,\n", " 0.0037606695367633915,\n", " 0.01984065730746143,\n", " 0.006865840265571568,\n", " 0.005848803904149604,\n", " -0.0006136851609655513,\n", " -0.00512572833155483,\n", " 0.01959737909211391,\n", " -0.019178401288703534,\n", " 0.02278702100955217,\n", " 0.0033805479073594873,\n", " -0.025219799437737157,\n", " -0.026692982220105084,\n", " 0.013826288932961072,\n", " -0.03714041336331458,\n", " -0.017894435309971483,\n", " -0.012400410817163393,\n", " 0.00270984456019101,\n", " 0.0026692982685766363,\n", " -0.027666093218850055,\n", " -0.006565121800280422,\n", " 0.014475029598791055,\n", " -0.009210767968402573,\n", " 0.019489256268690615,\n", " -0.024111533047067958,\n", " -0.023314123499030948,\n", " -0.016150943606400212,\n", " -0.010596100025416519,\n", " -0.0046695823762701455,\n", " -0.02040830585572394,\n", " -0.008136290891375709,\n", " 0.0027284281704668886,\n", " 0.03189642289967285,\n", " 0.02681462039645629,\n", " 0.010913712681867554,\n", " -0.013393794845300233,\n", " 0.035572621247806156,\n", " 0.0007868516680922945,\n", " -0.008413357489043009,\n", " -0.04895290260282359,\n", " -0.016177974312256035,\n", " -0.018070134898034333,\n", " 0.01638070646881982,\n", " 0.019191916641631446,\n", " 0.017678187800479785,\n", " -0.012434199199483171,\n", " -0.003780942566155259,\n", " 0.04800682044728933,\n", " -0.001748559262427321,\n", " 0.010663677721378634,\n", " -0.016150943606400212,\n", " 0.0017620747317705521,\n", " 0.017948496721683128,\n", " 0.0215976625013155,\n", " 0.007102360338793855,\n", " 0.005504160541842746,\n", " -0.025827994044783406,\n", " 0.03197751501724032,\n", " -0.003186263544867563,\n", " 0.015691417881560994,\n", " 0.034112955681011255,\n", " -0.024895429104822165,\n", " 0.010393368800175289,\n", " -0.010244698986645704,\n", " -0.019637925150897642,\n", " -0.0008624536391940781,\n", " -0.006497545035640864,\n", " 0.016867261036869752,\n", " 0.0005528657235439905,\n", " -0.010190636643611502,\n", " -0.04438468351086767,\n", " -0.014610184059392727,\n", " -0.002968327081921154,\n", " 0.026490250063541297,\n", " -0.015718450450061927,\n", " -0.014569638000608991,\n", " 0.01455612264768108,\n", " 0.026165879730626306,\n", " 0.01952980232747435,\n", " -0.014353390491117293,\n", " -0.003211605064438036,\n", " -0.003503876201318598,\n", " -0.020367757934295093,\n", " 0.015434625244608115,\n", " -0.02513870732016969,\n", " 0.009954117036050493,\n", " 0.012981573787031261,\n", " -0.024016925576572576,\n", " 0.02293569175440431,\n", " -0.015434625244608115,\n", " -0.009663535085455281,\n", " -0.022408589264925532,\n", " -0.01804310419217851,\n", " 0.029301460236352925,\n", " 0.030517849450445417,\n", " 0.001139520062238399,\n", " -0.013961443393562745,\n", " -0.02736875359179089,\n", " -0.0066833820697222044,\n", " -0.022516712088348826,\n", " 0.017826856682686812,\n", " -0.020719160835711018,\n", " 0.015353533127040646,\n", " 0.02382771063558181,\n", " 0.008318749087225071,\n", " -0.004422925788351924,\n", " -0.6366309990135384,\n", " -0.023760132008297144,\n", " 0.032572194271358657,\n", " -0.020840799012062223,\n", " 0.03200454572309614,\n", " 0.013143758953488757,\n", " 0.0010922159777447499,\n", " -0.021867971422518843,\n", " -0.0345184162688486,\n", " 0.04233033868995443,\n", " -0.01884051560286063,\n", " -0.0013912450239199066,\n", " -0.0193676162296943,\n", " -0.003106860380754804,\n", " 0.025544169770652148,\n", " -0.005872455771773449,\n", " 0.030571910862157065,\n", " -0.03286953576106293,\n", " 0.010102786849580077,\n", " 0.02389528740022137,\n", " -0.016488829292243115,\n", " 0.027585001101282588,\n", " -0.010217668280789882,\n", " -0.005287913498012326,\n", " -0.01890809236750019,\n", " 0.00484866173388753,\n", " 0.006926659819408448,\n", " -0.014880492980596072,\n", " 0.013610041423469376,\n", " 0.002333101769019084,\n", " -0.025936116868206696,\n", " 0.01661046746859432,\n", " 0.032410010036223715,\n", " -0.012535565277765065,\n", " 0.03197751501724032,\n", " -0.015380563832896469,\n", " -0.020840799012062223,\n", " 0.01884051560286063,\n", " -0.008217383940265733,\n", " 0.03970834532077868,\n", " -0.035788870619942965,\n", " -0.013839804285888985,\n", " -0.008197110910873866,\n", " 0.011528664965377758,\n", " -0.009440530830822183,\n", " 0.02681462039645629,\n", " 0.0022722822151822033,\n", " -0.003649167176616204,\n", " -0.009068855831336946,\n", " 0.025544169770652148,\n", " 0.0028112101728116254,\n", " 0.011697607808299208,\n", " 0.0019394647866872677,\n", " 0.007811920558460717,\n", " 0.0180295888392506,\n", " -0.009947359359586537,\n", " 0.020421821208651852,\n", " -0.004277634813054318,\n", " 0.026246971848193777,\n", " 0.021962580755659336,\n", " 0.013339733433588586,\n", " 0.010589342348952563,\n", " -0.008663393380854485,\n", " -0.016475313939315204,\n", " -0.025963147574062522,\n", " 0.035572621247806156,\n", " 0.01095425874065129,\n", " 0.018205290289958563,\n", " -0.005727165262137121,\n", " -0.04727698766389188,\n", " 0.008467418900754656,\n", " 0.013042393806529419,\n", " -0.021205715403760952,\n", " -0.0064907868935156305,\n", " 0.014623699412320638,\n", " 0.03200454572309614,\n", " 0.024881913751894254,\n", " -0.014610184059392727,\n", " -0.01516431632340477,\n", " 0.025530654417724237,\n", " 0.011454330524274242,\n", " -0.0027216704940029326,\n", " -0.00803492574441637,\n", " 0.022178826402505923,\n", " 0.008339023047939494,\n", " 0.018070134898034333,\n", " -0.022976237813188045,\n", " -0.004439819979511814,\n", " -0.029625830569267913,\n", " -0.006000852555911166,\n", " 0.02208421893201054,\n", " 0.04184378225925939,\n", " -0.02430074985070383,\n", " -0.04330345155134451,\n", " 0.015623841116921434,\n", " -0.010460945564814847,\n", " 0.008933701370735275,\n", " -0.001609181370450996,\n", " 0.016718592154662724,\n", " -0.007845708940780497,\n", " 0.007014510079101152,\n", " -0.0022689033769502254,\n", " 0.017759279918047256,\n", " 0.004950027812169423,\n", " 0.01143405656355982,\n", " -0.004095176617204955,\n", " -0.006565121800280422,\n", " 0.0051324860080187865,\n", " -0.003689713468230578,\n", " 0.0006715481149341314,\n", " -0.03381561419130697,\n", " -0.019651440503825553,\n", " 0.0052946711744762814,\n", " 0.015488687587642318,\n", " -0.010933985711259421,\n", " -0.04922320966138182,\n", " 0.0037302597598449514,\n", " 0.0053284595567960604,\n", " 0.01321133664945087,\n", " -0.01031903342774922,\n", " -0.012163890278279828,\n", " -0.0022689033769502254,\n", " 0.01546165595046394,\n", " -0.005646072678908374,\n", " 0.002725049332234911,\n", " 0.001511194479647039,\n", " -0.01482643063756187,\n", " -0.021881486775446754,\n", " -0.019962295483812634,\n", " 0.02153008573667594,\n", " 0.019421677641405944,\n", " -0.015623841116921434,\n", " 0.009913570977266759,\n", " -0.013711407501751267,\n", " 0.019489256268690615,\n", " 0.028463502766887066,\n", " 0.02513870732016969,\n", " -0.009663535085455281,\n", " 0.012603142042404623,\n", " -0.008257929999049469,\n", " 0.0010001420538467544,\n", " 0.01716460066392892,\n", " 0.0034396778092497396,\n", " 0.0031609220252970895,\n", " -0.02967989198097956,\n", " -0.028139132433972078,\n", " -0.015218378666438973,\n", " 0.02048939797329141,\n", " 0.005862319257077516,\n", " 0.009339164752540291,\n", " -0.014231751383443533,\n", " -0.004977058518025246,\n", " -0.013170790590667135,\n", " -0.00022828412592801136,\n", " -0.010663677721378634,\n", " -0.014177689971731886,\n", " -0.009487834566069874,\n", " -0.025530654417724237,\n", " 0.0027402541042788114,\n", " -0.027166021435227103,\n", " 0.006835430721483767,\n", " 0.043492666492335276,\n", " 0.01875942162264805,\n", " -0.0048114945133357736,\n", " -0.012724781150078383,\n", " 0.001553430190377402,\n", " -0.01828638240752603,\n", " 0.031436900900123854,\n", " -0.004007326357512252,\n", " -0.02619291043648213,\n", " 0.004159374543612536,\n", " -0.04235736939581025,\n", " 0.01178545853365319,\n", " 0.01977308054282187,\n", " -0.002116854725188664,\n", " 0.021935548187158403,\n", " -0.02753093782692583,\n", " -0.0025831371951692828,\n", " -0.01008251382018821,\n", " -0.026057756907203015,\n", " -0.004517533724508583,\n", " 0.0040478724162959865,\n", " 0.0058690769335414715,\n", " 0.016799684272230192,\n", " 0.032653286388926124,\n", " 0.008737727821957999,\n", " 0.004125586161292757,\n", " 0.00819035323440991,\n", " -0.010487976270670671,\n", " 0.021084077227409747,\n", " 0.006889492598856691,\n", " -0.026368611887190092,\n", " -0.04135722582856435,\n", " 0.006544848770888555,\n", " -0.006078566300907935,\n", " 0.009149948880226971,\n", " 0.00794707501906239,\n", " 0.01171112316122712,\n", " 0.004774326827122738,\n", " 0.018178257721457626,\n", " 0.0056426938406763955,\n", " 0.017218662075640566,\n", " 0.0036930923064625557,\n", " -0.007967348048454257,\n", " 0.0029767744103317375,\n", " 0.001376884845018681,\n", " 0.002973395339269121,\n", " -0.013434340904083969,\n", " -0.003350138130441047,\n", " 0.010609615378344431,\n", " 0.01952980232747435,\n", " 0.005581874286839515,\n", " -0.045168581431266994,\n", " -0.013589768394077507,\n", " -0.0015424488497081544,\n", " -0.004328317852195265,\n", " -0.011021836436613404,\n", " -7.813609795677769e-06,\n", " -0.007507823720598872,\n", " 0.0021354385682951812,\n", " -0.013684376795895445,\n", " 0.010068998467260297,\n", " 0.008197110910873866,\n", " 0.020854314364990138,\n", " 0.0009004658021344685,\n", " -0.00526426163038848,\n", " 0.012373380111307569,\n", " -0.008920186017807362,\n", " 0.015367048479968557,\n", " -0.008095744832591973,\n", " -0.002578068937821316,\n", " 0.049169148249670176,\n", " 0.010427157182495069,\n", " 0.00421343642098546,\n", " 0.014623699412320638,\n", " 0.006115733987120971,\n", " 0.020854314364990138,\n", " 0.011528664965377758,\n", " 0.0025172496168150743,\n", " 0.0053723849194730515,\n", " -0.012555838307156932,\n", " 0.0020932028575648184,\n", " 0.006355632898575236,\n", " -0.025287376202376716,\n", " 0.02350334030266682,\n", " 0.020921891129629694,\n", " 0.02792288678712549,\n", " -0.0026963289744324596,\n", " -0.02205718822615472,\n", " 0.0052743981450844146,\n", " -0.014461514245863142,\n", " -0.0026895712979685036,\n", " 0.005537948924162525,\n", " 0.013704649825287312,\n", " 0.021084077227409747,\n", " -0.01606985148883274,\n", " -0.014515575657574789,\n", " 0.02816616500247301,\n", " 0.021462508972036384,\n", " 0.05149380385443187,\n", " 0.009609473673743634,\n", " 0.008278203028441336,\n", " 0.012163890278279828,\n", " 0.010143332908363813,\n", " 0.03224782580108878,\n", " -0.018962153779211836,\n", " -0.024800821634326786,\n", " -0.015610325763993523,\n", " -0.02335466955781468,\n", " -0.018408020583877235,\n", " -0.016583436762738497,\n", " -0.001876955930149718,\n", " 0.007149664539702824,\n", " -0.013711407501751267,\n", " 0.03235594862451207,\n", " 0.014718307814138576,\n", " 0.028193195708328834,\n", " 0.012224710297777986,\n", " 0.01961089444504182,\n", " 0.027895856081269665,\n", " -0.011035351789541315,\n", " -0.029869108784615437,\n", " 0.05025038393448355,\n", " 0.0008147272581290915,\n", " 0.0026490250063541296,\n", " -0.024179111674352625,\n", " -0.027409299650574624,\n", " -0.0005786294814781415,\n", " -0.02198961146151516,\n", " 0.016191489665183946,\n", " 0.014975100451091452,\n", " 0.016691561448806902,\n", " 0.028490535335388003,\n", " -0.0024851504207806453,\n", " -0.0034515039758923013,\n", " 0.03635651544291525,\n", " 0.014353390491117293,\n", " 0.006389421280895015,\n", " 0.019205431994559357,\n", " -0.001809378699848882,\n", " -0.0023685798032854906,\n", " -0.021651725775672256,\n", " -0.010217668280789882,\n", " -0.008663393380854485,\n", " 0.045898414214664444,\n", " -0.01067043539784259,\n", " 0.0056122838309273166,\n", " -0.014083082501236506,\n", " -0.006487408055283653,\n", " -0.004493881856884738,\n", " 0.005608904992695339,\n", " 0.01763764174169605,\n", " -0.018543175975801466,\n", " 0.0009291861017292599,\n", " -0.009609473673743634,\n", " 0.04343860508062363,\n", " -0.01750248634977182,\n", " -0.002000284107693509,\n", " 0.016286097135679328,\n", " 0.01344785625701188,\n", " -0.02185445606959093,\n", " -0.027111960023515458,\n", " 0.0026017210382758,\n", " -0.0032301886747139147,\n", " 0.028923028491726285,\n", " 0.028003978904692958,\n", " -0.0055784954486075376,\n", " -0.0003112773347660765,\n", " -0.011684092455371296,\n", " -0.007825435911388628,\n", " -0.018380989878021413,\n", " 0.007838951264316541,\n", " -0.005250745811799291,\n", " 0.0028635826310685606,\n", " -0.03781618473500038,\n", " -0.036653856932619536,\n", " 0.023692555243657584,\n", " -0.010967774093579201,\n", " 0.01661046746859432,\n", " 0.0018786453492657068,\n", " 0.004392515778602845,\n", " -0.010623130731272343,\n", " 0.013326218080660675,\n", " -0.0022317359235678297,\n", " -0.005923138810914396,\n", " -0.007325365059088231,\n", " -0.006625941354117302,\n", " 0.007210484093539704,\n", " 0.030031294882395487,\n", " -0.0020847557619848734,\n", " 0.008987763713769477,\n", " 0.01773224921219143,\n", " 0.013961443393562745,\n", " -0.032707351525928,\n", " 0.00794707501906239,\n", " 0.016961870370010245,\n", " -0.010481218594206714,\n", " 0.013069424512385241,\n", " -0.010636646084200254,\n", " 0.036383546148771075,\n", " 0.004017462872208185,\n", " 0.016326643194463062,\n", " 0.019881203366245163,\n", " -0.009244556350722353,\n", " 0.008764758527813823,\n", " 0.017178116016856832,\n", " -0.0015990447393397426,\n", " -0.003845140958224117,\n", " -0.018543175975801466,\n", " -0.011603000337803827,\n", " -0.01356949536468564,\n", " 0.008170080205018042,\n", " -0.0009663534969039962,\n", " -0.01898918448506766,\n", " 0.007284819000304496,\n", " 0.008088987156128017,\n", " -0.030653002979724533,\n", " -0.0145290910105027,\n", " 0.01621852037103977,\n", " 0.021097592580337658,\n", " -0.024706212301186293,\n", " 0.002817967849275581,\n", " -0.0073388804120161424,\n", " -0.006173174237064595,\n", " -0.01811068095681807,\n", " -0.013258640384698562,\n", " -0.007872740577958875,\n", " -0.017934981368755216,\n", " -0.0067610958147189745,\n", " -0.015623841116921434,\n", " -0.014137143912948152,\n", " 0.005673103384764197,\n", " -0.010346064133605042,\n", " 0.005723786423905143,\n", " -0.0008666771869840505,\n", " -0.007386184612925111,\n", " -0.04416843786402108,\n", " 0.00806871412673615,\n", " 0.009102645144979282,\n", " 0.024152080968496803,\n", " 0.01020415292786197,\n", " 0.009954117036050493,\n", " -0.010771800544801926,\n", " -0.015488687587642318,\n", " -0.0032065365742594302,\n", " -0.0101298175554359,\n", " 0.009954117036050493,\n", " -0.005075045292413884,\n", " -0.01031903342774922,\n", " 0.012603142042404623,\n", " -0.018921607720428103,\n", " 0.0068590825891076115,\n", " -0.013001847747745683,\n", " 0.0010744769606115465,\n", " 0.01600227286154807,\n", " 0.008311991410761116,\n", " 0.007676766563520323,\n", " -0.038410863989118714,\n", " 0.016421252527603555,\n", " 0.02581447869185549,\n", " 0.014569638000608991,\n", " 0.009886540271410935,\n", " -0.01515080097047686,\n", " -0.010981290377829668,\n", " 0.02281405171540799,\n", " -0.022408589264925532,\n", " 0.00032204743983816584,\n", " -0.0037403962745408852,\n", " 0.0018144469571968486,\n", " 0.0125761113365488,\n", " -0.00642658896710805,\n", " 0.020178542993304332,\n", " -0.017664672447551873,\n", " 0.0018617510416904979,\n", " 0.0008962421961368364,\n", " 4.919802804552858e-06,\n", " -0.008055198773808237,\n", " -0.00022638351487060885,\n", " 0.01135296444599235,\n", " -0.019448708347261767,\n", " -0.01977308054282187,\n", " 0.033842644897162794,\n", " -0.02731469218007924,\n", " 0.004781084503586695,\n", " -0.02705789861180381,\n", " 0.004419546950119946,\n", " 0.035653713365373624,\n", " 0.011001563407221535,\n", " -0.0034802241008641136,\n", " 0.03005832558825131,\n", " -0.0019158126862327833,\n", " -0.0037708060514593253,\n", " -0.03632948473705943,\n", " 0.014894008333523983,\n", " -0.017705218506335607,\n", " 0.03668088763847536,\n", " 0.0007898081515452752,\n", " 0.007778132176140938,\n", " -0.020313696522583448,\n", " -0.03251813285964701,\n", " -0.006044777918588156,\n", " -0.007061814280010121,\n", " 0.005169653228570543,\n", " 0.0022722822151822033,\n", " -0.005696755252388042,\n", " -0.015515718293498142,\n", " 0.0008523170662904846,\n", " -0.0030798294420683416,\n", " -0.0016801373225684905,\n", " -0.02311139134246716,\n", " -0.035572621247806156,\n", " 0.035788870619942965,\n", " 0.000670703405376137,\n", " 0.021219230756688863,\n", " 0.010575826996024652,\n", " 0.022030157520298896,\n", " -0.029544738451700445,\n", " -0.01877293697557596,\n", " 0.0017147706472769029,\n", " -0.0049905738709531584,\n", " 0.016326643194463062,\n", " 0.03797836897013532,\n", " 0.013468130217726302,\n", " 0.020448851914507675,\n", " 0.055521401378690875,\n", " -0.024152080968496803,\n", " 0.039275850301795284,\n", " -0.0026659194303446584,\n", " -0.0006204428956371669,\n", " 0.007318607382624275,\n", " -0.004095176617204955,\n", " -0.012792357914717941,\n", " -0.00013821643088599762,\n", " 0.0036525460148481817,\n", " 0.001841477895883311,\n", " -0.03295062787863041,\n", " 0.012258498680097764,\n", " 0.003155853767949123,\n", " 0.0031169968954507378,\n", " 0.005615662669159294,\n", " -0.016096882194688564,\n", " -0.008257929999049469,\n", " -0.020381273287223004,\n", " -0.015299470784006444,\n", " -0.014447998892935231,\n", " 0.02086782971791805,\n", " -0.011379995151848173,\n", " 0.01938113158262221,\n", " -0.029463646334132974,\n", " 0.0014596668473634176,\n", " 0.004743917283034937,\n", " 0.0022368044137464353,\n", " 0.017367332820492704,\n", " 0.02730117682715133,\n", " 0.02959879986341209,\n", " -0.028058040316404607,\n", " -0.00565283035537233,\n", " -0.0014148970079590714,\n", " -0.02690922786695167,\n", " -0.01130566071074466,\n", " -0.012359863827057102,\n", " -0.010481218594206714,\n", " -0.02603072620134719,\n", " 0.018637783446296845,\n", " -0.012562595983620887,\n", " 0.009109402821443237,\n", " 0.0015770821744165667,\n", " 0.017461940290988087,\n", " -0.025273860849448805,\n", " 0.018610752740441022,\n", " 0.008122775538447797,\n", " -0.024476451301411795,\n", " -0.00028445766078060255,\n", " -0.02388177204729346,\n", " -0.016096882194688564,\n", " -0.05235879016710844,\n", " -0.017826856682686812,\n", " -0.004598626307737331,\n", " -0.00894045904719923,\n", " -0.0035140127160145315,\n", " -0.024881913751894254,\n", " 0.008406599812579053,\n", " -0.0036694402060080712,\n", " -0.008643120351462618,\n", " -0.033166873525476995,\n", " 0.0036525460148481817,\n", " 0.03970834532077868,\n", " 0.007284819000304496,\n", " 0.0210300158156981,\n", " 0.01463721476524855,\n", " -0.006281297991810444,\n", " -0.02461160483069091,\n", " 0.01923246270041518,\n", " -0.0008012117887858603,\n", " -0.010771800544801926,\n", " 0.0047337807683390035,\n", " 0.029220368118785454,\n", " -0.019354100876766388,\n", " -0.032896566466918756,\n", " 0.011123201583572741,\n", " -0.005946790678538242,\n", " -0.004311423195374097,\n", " -0.023692555243657584,\n", " 0.020151512287448506,\n", " -0.008359296077331362,\n", " -0.004422925788351924,\n", " -0.012488260611194818,\n", " 0.0005790518944647985,\n", " -0.031436900900123854,\n", " 0.004095176617204955,\n", " -0.02278702100955217,\n", " -0.011102928554180873,\n", " 0.001799242185152948,\n", " -0.0029666376628051648,\n", " 0.0062002054085816966,\n", " 0.02722008284693875,\n", " -0.0016801373225684905,\n", " 0.02280053636248008,\n", " -0.005831909712989715,\n", " 0.009582442967887812,\n", " -0.003747153951004841,\n", " 0.0034498145567763124,\n", " -0.010305518074821307,\n", " 0.0155832950581377,\n", " 0.019327070170910562,\n", " 0.03500497269954364,\n", " -0.011697607808299208,\n", " 0.00016155166339282948,\n", " 0.021895002128374665,\n", " -0.008994521390233432,\n", " 0.0069536905252642715,\n", " -0.011447572847810287,\n", " -0.005744059453297011,\n", " 0.029625830569267913,\n", " -0.039275850301795284,\n", " -0.021205715403760952,\n", " -0.0036593036913121373,\n", " 0.024260203791920096,\n", " 0.014623699412320638,\n", " -0.008636362674998663,\n", " -0.016488829292243115,\n", " -0.022922176401476396,\n", " -0.004618899337129199,\n", " 0.0014115181697270936,\n", " 0.03822164532283773,\n", " -0.010521765584313005,\n", " 0.008899912988415495,\n", " -0.003493739686622664,\n", " -0.011535422641841713,\n", " 0.006838809559715745,\n", " -0.011548937994769625,\n", " 0.0025932739426958555,\n", " 0.012285529385953588,\n", " -0.012738296503006296,\n", " -0.017786310623903078,\n", " -0.002476703325200701,\n", " -0.006622562515885324,\n", " 0.04138425653442017,\n", " -0.016015788214475985,\n", " -0.0016936527919117217,\n", " 0.005054772263022016,\n", " 0.016988901075866068,\n", " -0.0013836425214826368,\n", " -0.002929470209422769,\n", " -0.0022384938328624242,\n", " -0.009278345664364689,\n", " -0.016583436762738497,\n", " -0.0193676162296943,\n", " -0.01835395917216559,\n", " 0.000876813759887644,\n", " 0.0016041129966877096,\n", " 0.006629320192349281,\n", " -0.010433914858959024,\n", " -0.01709702389928936,\n", " 0.005193305561855667,\n", " 0.01779982597683099,\n", " 0.01684023033101393,\n", " -0.0016852056963317767,\n", " -0.009744628134345307,\n", " -0.011623273367195694,\n", " 0.007778132176140938,\n", " -0.029977231608038727,\n", " -0.0003412646986978597,\n", " 0.009764901163737174,\n", " -0.006419831290644094,\n", " 0.00020188679216961967,\n", " 0.0183674745250935,\n", " -0.007237514799395528,\n", " -0.016421252527603555,\n", " -0.013866834991744808,\n", " -0.006375905927967104,\n", " -0.0019597378160791353,\n", " -0.031247682233842868,\n", " 0.0003847675028690441,\n", " -0.0106839507507705,\n", " 0.018083650250962247,\n", " -0.0011276940120111569,\n", " -0.01527244007815062,\n", " -0.00676785349118293,\n", " 0.004220194097449416,\n", " -0.01163003104365965,\n", " 0.03292359717277458,\n", " 0.0018059998616169039,\n", " -0.011994947435358377,\n", " 0.004659445861574211,\n", " 0.0042539829454304725,\n", " 0.026949775788380516,\n", " 0.015123770264621037,\n", " -0.026003695495491367,\n", " -0.009312134046684467,\n", " -0.03322093493718864,\n", " 0.003360274645136981,\n", " -0.024152080968496803,\n", " 0.010075756143724253,\n", " 0.01734030211463688,\n", " 0.023597947773162202,\n", " 0.024341295909487567,\n", " -0.026787589690600466,\n", " -0.01961089444504182,\n", " -0.006146143531208772,\n", " -0.008278203028441336,\n", " -0.006710412775578028,\n", " -0.021705787187383904,\n", " -0.0013067734860438614,\n", " 0.0018347201030040356,\n", " 0.0033264862628172016,\n", " -0.01582657327348522,\n", " 0.022449135323709266,\n", " 0.006473892702355741,\n", " -0.00018953284212437575,\n", " -0.0022165311515239287,\n", " -0.002208084055943984,\n", " -0.015921180743980603,\n", " -0.015218378666438973,\n", " -0.025746901927215935,\n", " -0.0028703403075325167,\n", " -0.03678901046189865,\n", " 0.013366764139444409,\n", " 0.027760700689345438,\n", " 0.004321560175731309,\n", " 0.011880066004148572,\n", " 0.051061308835448474,\n", " -0.0005718718050141857,\n", " -0.004757432635962849,\n", " -0.02715250608229919,\n", " 0.004558080248953596,\n", " 0.032410010036223715,\n", " 0.002426020286059754,\n", " 0.020948921835485516,\n", " -0.007940317342598433,\n", " -0.02057049009085888,\n", " 0.012805873267645854,\n", " -0.01654289070395476,\n", " 0.002365200965053513,\n", " -0.03357233783860456,\n", " 0.01071773913309028,\n", " 0.013441098580547924,\n", " 0.010041967761404475,\n", " -0.03668088763847536,\n", " 0.024016925576572576,\n", " -0.011481361230130067,\n", " -0.011156990897215075,\n", " 0.0275985164542105,\n", " -0.013589768394077507,\n", " -0.011724638514155032,\n", " 0.03381561419130697,\n", " 0.010055483114332386,\n", " 0.007325365059088231,\n", " -0.005409552605686086,\n", " 0.0330587507020537,\n", " 0.007142906863238868,\n", " 0.0005000710269233772,\n", " 0.032653286388926124,\n", " -0.021949065402731425,\n", " -0.02792288678712549,\n", " -0.019097307308490952,\n", " -0.0021337491491791923,\n", " -0.03424810921029037,\n", " -0.013231609678842737,\n", " -0.009704081144239016,\n", " -0.0028416199497300655,\n", " 0.0023516853792949623,\n", " -0.0024125049331318424,\n", " -0.0007420817704802885,\n", " -0.028003978904692958,\n", " 0.004456714170671703,\n", " -0.016745622860518547,\n", " 0.022759990303696347,\n", " -0.0014351701537662583,\n", " -0.0120219781412142,\n", " 0.017124054605145184,\n", " -0.008332265371475538,\n", " 0.013880350344672719,\n", " 0.010785315897729839,\n", " -0.011494876583057978,\n", " -0.026990321847164253,\n", " -0.019016215190923485,\n", " 0.035707774777085276,\n", " 0.02182742536373511,\n", " 0.01215713260181587,\n", " 0.2147332088184969,\n", " -0.03968131461492286,\n", " 0.019637925150897642,\n", " 0.0018516144105792446,\n", " -0.0027284281704668886,\n", " -0.02428723449777592,\n", " -0.020056902954308016,\n", " 0.011582726377089403,\n", " 0.002005352597872115,\n", " 0.009987905418370273,\n", " 0.024503482007267617,\n", " -0.0070482989270822085,\n", " -0.006909765628248558,\n", " -0.0023297229307871056,\n", " -0.004625657013593154,\n", " -0.014502060304646878,\n", " -0.035572621247806156,\n", " -0.011961159053038597,\n", " -0.019340585523838473,\n", " -0.008899912988415495,\n", " 0.008102502509055929,\n", " -0.007088844985865943,\n", " -0.008845851576703848,\n", " -0.016326643194463062,\n", " 0.018637783446296845,\n", " -0.01494806974523563,\n", " -0.012103071190104226,\n", " -0.015840088626413132,\n", " 0.014407452834151496,\n", " 0.025679325162576375,\n", " -0.00992708633019467,\n", " 0.02008393552280895,\n", " 0.02255725814713256,\n", " -0.009109402821443237,\n", " -0.012272014033025675,\n", " -0.014461514245863142,\n", " 0.019691986562609287,\n", " 0.026936260435452605,\n", " 0.020137996934520595,\n", " -0.0038620351493840067,\n", " 0.03140986646897781,\n", " -0.035302314189247924,\n", " 0.010893439652475688,\n", " 0.0013642140852334443,\n", " -0.01811068095681807,\n", " 0.020746191541566844,\n", " ...]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query_result = embeddings_hf.embed_query(text_hf)\n", "query_result" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[-0.02886896708001464,\n", " 0.0044634718471356595,\n", " 0.006389421280895015,\n", " -0.009913570977266759,\n", " -0.0027808003958931854,\n", " 0.023057329930755516,\n", " 0.018016073486322687,\n", " -0.007974105724918213,\n", " -0.02111110793326557,\n", " -0.030896281195072053,\n", " -0.003899202602766403,\n", " 0.009474319213141963,\n", " -0.002067861337994345,\n", " -0.0010989737706240251,\n", " -0.008920186017807362,\n", " 0.00898100603730552,\n", " 0.01804310419217851,\n", " 0.010190636643611502,\n", " 0.007784889852604894,\n", " -0.026733528278888818,\n", " 0.019691986562609287,\n", " -0.01051500790784905,\n", " -0.010170363614219635,\n", " -0.010170363614219635,\n", " -0.016096882194688564,\n", " 0.011109686230644828,\n", " 0.03597808556093373,\n", " -0.027652577865922144,\n", " -0.006450240834731895,\n", " -0.009197252615474662,\n", " 0.014083082501236506,\n", " -0.012393653140699437,\n", " -0.005676482222996175,\n", " -0.025692840515504287,\n", " -0.014461514245863142,\n", " -0.002672677106808614,\n", " 0.0069536905252642715,\n", " -0.025300891555304628,\n", " 0.025963147574062522,\n", " -0.0059940948794472105,\n", " -0.00814980624430362,\n", " 0.0155832950581377,\n", " -0.010940743387723377,\n", " -0.035086064817111115,\n", " -0.01600227286154807,\n", " 0.01851614340730053,\n", " -0.006511060388568775,\n", " -0.01908379195556304,\n", " -0.008311991410761116,\n", " 0.002961569405457198,\n", " 0.0017958632305056508,\n", " 0.0202596351108718,\n", " -0.019475740915762704,\n", " 0.003885687249838491,\n", " -0.0010710981223795684,\n", " 0.017353817467564793,\n", " 0.009433773154358227,\n", " 0.00968380811484715,\n", " -0.00799437875431008,\n", " 0.0015576537381673744,\n", " -0.011535422641841713,\n", " -0.0015263992516909397,\n", " -0.003103481542522826,\n", " 0.010325791104213175,\n", " -0.015096739558765213,\n", " -0.014110113207092328,\n", " 0.023516855655594734,\n", " 0.01372492285467918,\n", " 0.03797836897013532,\n", " 0.026922745082524693,\n", " 0.0035444224929329715,\n", " 0.014218236030515622,\n", " -0.022219372461289657,\n", " -0.005862319257077516,\n", " 0.04646606276292695,\n", " 0.007460519519689903,\n", " 0.009501349918997785,\n", " 0.0052304727824074235,\n", " 0.00515951671387461,\n", " 0.016448283233459378,\n", " -0.0019310175746920033,\n", " -0.011900339033540439,\n", " -0.009285103340828644,\n", " 0.0047675691506587825,\n", " 0.010961016417115246,\n", " 0.00806871412673615,\n", " -0.00456821676364953,\n", " 0.015029162794125655,\n", " -0.000812193129455108,\n", " 0.0037606695367633915,\n", " 0.01984065730746143,\n", " 0.006865840265571568,\n", " 0.005848803904149604,\n", " -0.0006136851609655513,\n", " -0.00512572833155483,\n", " 0.01959737909211391,\n", " -0.019178401288703534,\n", " 0.02278702100955217,\n", " 0.0033805479073594873,\n", " -0.025219799437737157,\n", " -0.026692982220105084,\n", " 0.013826288932961072,\n", " -0.03714041336331458,\n", " -0.017894435309971483,\n", " -0.012400410817163393,\n", " 0.00270984456019101,\n", " 0.0026692982685766363,\n", " -0.027666093218850055,\n", " -0.006565121800280422,\n", " 0.014475029598791055,\n", " -0.009210767968402573,\n", " 0.019489256268690615,\n", " -0.024111533047067958,\n", " -0.023314123499030948,\n", " -0.016150943606400212,\n", " -0.010596100025416519,\n", " -0.0046695823762701455,\n", " -0.02040830585572394,\n", " -0.008136290891375709,\n", " 0.0027284281704668886,\n", " 0.03189642289967285,\n", " 0.02681462039645629,\n", " 0.010913712681867554,\n", " -0.013393794845300233,\n", " 0.035572621247806156,\n", " 0.0007868516680922945,\n", " -0.008413357489043009,\n", " -0.04895290260282359,\n", " -0.016177974312256035,\n", " -0.018070134898034333,\n", " 0.01638070646881982,\n", " 0.019191916641631446,\n", " 0.017678187800479785,\n", " -0.012434199199483171,\n", " -0.003780942566155259,\n", " 0.04800682044728933,\n", " -0.001748559262427321,\n", " 0.010663677721378634,\n", " -0.016150943606400212,\n", " 0.0017620747317705521,\n", " 0.017948496721683128,\n", " 0.0215976625013155,\n", " 0.007102360338793855,\n", " 0.005504160541842746,\n", " -0.025827994044783406,\n", " 0.03197751501724032,\n", " -0.003186263544867563,\n", " 0.015691417881560994,\n", " 0.034112955681011255,\n", " -0.024895429104822165,\n", " 0.010393368800175289,\n", " -0.010244698986645704,\n", " -0.019637925150897642,\n", " -0.0008624536391940781,\n", " -0.006497545035640864,\n", " 0.016867261036869752,\n", " 0.0005528657235439905,\n", " -0.010190636643611502,\n", " -0.04438468351086767,\n", " -0.014610184059392727,\n", " -0.002968327081921154,\n", " 0.026490250063541297,\n", " -0.015718450450061927,\n", " -0.014569638000608991,\n", " 0.01455612264768108,\n", " 0.026165879730626306,\n", " 0.01952980232747435,\n", " -0.014353390491117293,\n", " -0.003211605064438036,\n", " -0.003503876201318598,\n", " -0.020367757934295093,\n", " 0.015434625244608115,\n", " -0.02513870732016969,\n", " 0.009954117036050493,\n", " 0.012981573787031261,\n", " -0.024016925576572576,\n", " 0.02293569175440431,\n", " -0.015434625244608115,\n", " -0.009663535085455281,\n", " -0.022408589264925532,\n", " -0.01804310419217851,\n", " 0.029301460236352925,\n", " 0.030517849450445417,\n", " 0.001139520062238399,\n", " -0.013961443393562745,\n", " -0.02736875359179089,\n", " -0.0066833820697222044,\n", " -0.022516712088348826,\n", " 0.017826856682686812,\n", " -0.020719160835711018,\n", " 0.015353533127040646,\n", " 0.02382771063558181,\n", " 0.008318749087225071,\n", " -0.004422925788351924,\n", " -0.6366309990135384,\n", " -0.023760132008297144,\n", " 0.032572194271358657,\n", " -0.020840799012062223,\n", " 0.03200454572309614,\n", " 0.013143758953488757,\n", " 0.0010922159777447499,\n", " -0.021867971422518843,\n", " -0.0345184162688486,\n", " 0.04233033868995443,\n", " -0.01884051560286063,\n", " -0.0013912450239199066,\n", " -0.0193676162296943,\n", " -0.003106860380754804,\n", " 0.025544169770652148,\n", " -0.005872455771773449,\n", " 0.030571910862157065,\n", " -0.03286953576106293,\n", " 0.010102786849580077,\n", " 0.02389528740022137,\n", " -0.016488829292243115,\n", " 0.027585001101282588,\n", " -0.010217668280789882,\n", " -0.005287913498012326,\n", " -0.01890809236750019,\n", " 0.00484866173388753,\n", " 0.006926659819408448,\n", " -0.014880492980596072,\n", " 0.013610041423469376,\n", " 0.002333101769019084,\n", " -0.025936116868206696,\n", " 0.01661046746859432,\n", " 0.032410010036223715,\n", " -0.012535565277765065,\n", " 0.03197751501724032,\n", " -0.015380563832896469,\n", " -0.020840799012062223,\n", " 0.01884051560286063,\n", " -0.008217383940265733,\n", " 0.03970834532077868,\n", " -0.035788870619942965,\n", " -0.013839804285888985,\n", " -0.008197110910873866,\n", " 0.011528664965377758,\n", " -0.009440530830822183,\n", " 0.02681462039645629,\n", " 0.0022722822151822033,\n", " -0.003649167176616204,\n", " -0.009068855831336946,\n", " 0.025544169770652148,\n", " 0.0028112101728116254,\n", " 0.011697607808299208,\n", " 0.0019394647866872677,\n", " 0.007811920558460717,\n", " 0.0180295888392506,\n", " -0.009947359359586537,\n", " 0.020421821208651852,\n", " -0.004277634813054318,\n", " 0.026246971848193777,\n", " 0.021962580755659336,\n", " 0.013339733433588586,\n", " 0.010589342348952563,\n", " -0.008663393380854485,\n", " -0.016475313939315204,\n", " -0.025963147574062522,\n", " 0.035572621247806156,\n", " 0.01095425874065129,\n", " 0.018205290289958563,\n", " -0.005727165262137121,\n", " -0.04727698766389188,\n", " 0.008467418900754656,\n", " 0.013042393806529419,\n", " -0.021205715403760952,\n", " -0.0064907868935156305,\n", " 0.014623699412320638,\n", " 0.03200454572309614,\n", " 0.024881913751894254,\n", " -0.014610184059392727,\n", " -0.01516431632340477,\n", " 0.025530654417724237,\n", " 0.011454330524274242,\n", " -0.0027216704940029326,\n", " -0.00803492574441637,\n", " 0.022178826402505923,\n", " 0.008339023047939494,\n", " 0.018070134898034333,\n", " -0.022976237813188045,\n", " -0.004439819979511814,\n", " -0.029625830569267913,\n", " -0.006000852555911166,\n", " 0.02208421893201054,\n", " 0.04184378225925939,\n", " -0.02430074985070383,\n", " -0.04330345155134451,\n", " 0.015623841116921434,\n", " -0.010460945564814847,\n", " 0.008933701370735275,\n", " -0.001609181370450996,\n", " 0.016718592154662724,\n", " -0.007845708940780497,\n", " 0.007014510079101152,\n", " -0.0022689033769502254,\n", " 0.017759279918047256,\n", " 0.004950027812169423,\n", " 0.01143405656355982,\n", " -0.004095176617204955,\n", " -0.006565121800280422,\n", " 0.0051324860080187865,\n", " -0.003689713468230578,\n", " 0.0006715481149341314,\n", " -0.03381561419130697,\n", " -0.019651440503825553,\n", " 0.0052946711744762814,\n", " 0.015488687587642318,\n", " -0.010933985711259421,\n", " -0.04922320966138182,\n", " 0.0037302597598449514,\n", " 0.0053284595567960604,\n", " 0.01321133664945087,\n", " -0.01031903342774922,\n", " -0.012163890278279828,\n", " -0.0022689033769502254,\n", " 0.01546165595046394,\n", " -0.005646072678908374,\n", " 0.002725049332234911,\n", " 0.001511194479647039,\n", " -0.01482643063756187,\n", " -0.021881486775446754,\n", " -0.019962295483812634,\n", " 0.02153008573667594,\n", " 0.019421677641405944,\n", " -0.015623841116921434,\n", " 0.009913570977266759,\n", " -0.013711407501751267,\n", " 0.019489256268690615,\n", " 0.028463502766887066,\n", " 0.02513870732016969,\n", " -0.009663535085455281,\n", " 0.012603142042404623,\n", " -0.008257929999049469,\n", " 0.0010001420538467544,\n", " 0.01716460066392892,\n", " 0.0034396778092497396,\n", " 0.0031609220252970895,\n", " -0.02967989198097956,\n", " -0.028139132433972078,\n", " -0.015218378666438973,\n", " 0.02048939797329141,\n", " 0.005862319257077516,\n", " 0.009339164752540291,\n", " -0.014231751383443533,\n", " -0.004977058518025246,\n", " -0.013170790590667135,\n", " -0.00022828412592801136,\n", " -0.010663677721378634,\n", " -0.014177689971731886,\n", " -0.009487834566069874,\n", " -0.025530654417724237,\n", " 0.0027402541042788114,\n", " -0.027166021435227103,\n", " 0.006835430721483767,\n", " 0.043492666492335276,\n", " 0.01875942162264805,\n", " -0.0048114945133357736,\n", " -0.012724781150078383,\n", " 0.001553430190377402,\n", " -0.01828638240752603,\n", " 0.031436900900123854,\n", " -0.004007326357512252,\n", " -0.02619291043648213,\n", " 0.004159374543612536,\n", " -0.04235736939581025,\n", " 0.01178545853365319,\n", " 0.01977308054282187,\n", " -0.002116854725188664,\n", " 0.021935548187158403,\n", " -0.02753093782692583,\n", " -0.0025831371951692828,\n", " -0.01008251382018821,\n", " -0.026057756907203015,\n", " -0.004517533724508583,\n", " 0.0040478724162959865,\n", " 0.0058690769335414715,\n", " 0.016799684272230192,\n", " 0.032653286388926124,\n", " 0.008737727821957999,\n", " 0.004125586161292757,\n", " 0.00819035323440991,\n", " -0.010487976270670671,\n", " 0.021084077227409747,\n", " 0.006889492598856691,\n", " -0.026368611887190092,\n", " -0.04135722582856435,\n", " 0.006544848770888555,\n", " -0.006078566300907935,\n", " 0.009149948880226971,\n", " 0.00794707501906239,\n", " 0.01171112316122712,\n", " 0.004774326827122738,\n", " 0.018178257721457626,\n", " 0.0056426938406763955,\n", " 0.017218662075640566,\n", " 0.0036930923064625557,\n", " -0.007967348048454257,\n", " 0.0029767744103317375,\n", " 0.001376884845018681,\n", " 0.002973395339269121,\n", " -0.013434340904083969,\n", " -0.003350138130441047,\n", " 0.010609615378344431,\n", " 0.01952980232747435,\n", " 0.005581874286839515,\n", " -0.045168581431266994,\n", " -0.013589768394077507,\n", " -0.0015424488497081544,\n", " -0.004328317852195265,\n", " -0.011021836436613404,\n", " -7.813609795677769e-06,\n", " -0.007507823720598872,\n", " 0.0021354385682951812,\n", " -0.013684376795895445,\n", " 0.010068998467260297,\n", " 0.008197110910873866,\n", " 0.020854314364990138,\n", " 0.0009004658021344685,\n", " -0.00526426163038848,\n", " 0.012373380111307569,\n", " -0.008920186017807362,\n", " 0.015367048479968557,\n", " -0.008095744832591973,\n", " -0.002578068937821316,\n", " 0.049169148249670176,\n", " 0.010427157182495069,\n", " 0.00421343642098546,\n", " 0.014623699412320638,\n", " 0.006115733987120971,\n", " 0.020854314364990138,\n", " 0.011528664965377758,\n", " 0.0025172496168150743,\n", " 0.0053723849194730515,\n", " -0.012555838307156932,\n", " 0.0020932028575648184,\n", " 0.006355632898575236,\n", " -0.025287376202376716,\n", " 0.02350334030266682,\n", " 0.020921891129629694,\n", " 0.02792288678712549,\n", " -0.0026963289744324596,\n", " -0.02205718822615472,\n", " 0.0052743981450844146,\n", " -0.014461514245863142,\n", " -0.0026895712979685036,\n", " 0.005537948924162525,\n", " 0.013704649825287312,\n", " 0.021084077227409747,\n", " -0.01606985148883274,\n", " -0.014515575657574789,\n", " 0.02816616500247301,\n", " 0.021462508972036384,\n", " 0.05149380385443187,\n", " 0.009609473673743634,\n", " 0.008278203028441336,\n", " 0.012163890278279828,\n", " 0.010143332908363813,\n", " 0.03224782580108878,\n", " -0.018962153779211836,\n", " -0.024800821634326786,\n", " -0.015610325763993523,\n", " -0.02335466955781468,\n", " -0.018408020583877235,\n", " -0.016583436762738497,\n", " -0.001876955930149718,\n", " 0.007149664539702824,\n", " -0.013711407501751267,\n", " 0.03235594862451207,\n", " 0.014718307814138576,\n", " 0.028193195708328834,\n", " 0.012224710297777986,\n", " 0.01961089444504182,\n", " 0.027895856081269665,\n", " -0.011035351789541315,\n", " -0.029869108784615437,\n", " 0.05025038393448355,\n", " 0.0008147272581290915,\n", " 0.0026490250063541296,\n", " -0.024179111674352625,\n", " -0.027409299650574624,\n", " -0.0005786294814781415,\n", " -0.02198961146151516,\n", " 0.016191489665183946,\n", " 0.014975100451091452,\n", " 0.016691561448806902,\n", " 0.028490535335388003,\n", " -0.0024851504207806453,\n", " -0.0034515039758923013,\n", " 0.03635651544291525,\n", " 0.014353390491117293,\n", " 0.006389421280895015,\n", " 0.019205431994559357,\n", " -0.001809378699848882,\n", " -0.0023685798032854906,\n", " -0.021651725775672256,\n", " -0.010217668280789882,\n", " -0.008663393380854485,\n", " 0.045898414214664444,\n", " -0.01067043539784259,\n", " 0.0056122838309273166,\n", " -0.014083082501236506,\n", " -0.006487408055283653,\n", " -0.004493881856884738,\n", " 0.005608904992695339,\n", " 0.01763764174169605,\n", " -0.018543175975801466,\n", " 0.0009291861017292599,\n", " -0.009609473673743634,\n", " 0.04343860508062363,\n", " -0.01750248634977182,\n", " -0.002000284107693509,\n", " 0.016286097135679328,\n", " 0.01344785625701188,\n", " -0.02185445606959093,\n", " -0.027111960023515458,\n", " 0.0026017210382758,\n", " -0.0032301886747139147,\n", " 0.028923028491726285,\n", " 0.028003978904692958,\n", " -0.0055784954486075376,\n", " -0.0003112773347660765,\n", " -0.011684092455371296,\n", " -0.007825435911388628,\n", " -0.018380989878021413,\n", " 0.007838951264316541,\n", " -0.005250745811799291,\n", " 0.0028635826310685606,\n", " -0.03781618473500038,\n", " -0.036653856932619536,\n", " 0.023692555243657584,\n", " -0.010967774093579201,\n", " 0.01661046746859432,\n", " 0.0018786453492657068,\n", " 0.004392515778602845,\n", " -0.010623130731272343,\n", " 0.013326218080660675,\n", " -0.0022317359235678297,\n", " -0.005923138810914396,\n", " -0.007325365059088231,\n", " -0.006625941354117302,\n", " 0.007210484093539704,\n", " 0.030031294882395487,\n", " -0.0020847557619848734,\n", " 0.008987763713769477,\n", " 0.01773224921219143,\n", " 0.013961443393562745,\n", " -0.032707351525928,\n", " 0.00794707501906239,\n", " 0.016961870370010245,\n", " -0.010481218594206714,\n", " 0.013069424512385241,\n", " -0.010636646084200254,\n", " 0.036383546148771075,\n", " 0.004017462872208185,\n", " 0.016326643194463062,\n", " 0.019881203366245163,\n", " -0.009244556350722353,\n", " 0.008764758527813823,\n", " 0.017178116016856832,\n", " -0.0015990447393397426,\n", " -0.003845140958224117,\n", " -0.018543175975801466,\n", " -0.011603000337803827,\n", " -0.01356949536468564,\n", " 0.008170080205018042,\n", " -0.0009663534969039962,\n", " -0.01898918448506766,\n", " 0.007284819000304496,\n", " 0.008088987156128017,\n", " -0.030653002979724533,\n", " -0.0145290910105027,\n", " 0.01621852037103977,\n", " 0.021097592580337658,\n", " -0.024706212301186293,\n", " 0.002817967849275581,\n", " -0.0073388804120161424,\n", " -0.006173174237064595,\n", " -0.01811068095681807,\n", " -0.013258640384698562,\n", " -0.007872740577958875,\n", " -0.017934981368755216,\n", " -0.0067610958147189745,\n", " -0.015623841116921434,\n", " -0.014137143912948152,\n", " 0.005673103384764197,\n", " -0.010346064133605042,\n", " 0.005723786423905143,\n", " -0.0008666771869840505,\n", " -0.007386184612925111,\n", " -0.04416843786402108,\n", " 0.00806871412673615,\n", " 0.009102645144979282,\n", " 0.024152080968496803,\n", " 0.01020415292786197,\n", " 0.009954117036050493,\n", " -0.010771800544801926,\n", " -0.015488687587642318,\n", " -0.0032065365742594302,\n", " -0.0101298175554359,\n", " 0.009954117036050493,\n", " -0.005075045292413884,\n", " -0.01031903342774922,\n", " 0.012603142042404623,\n", " -0.018921607720428103,\n", " 0.0068590825891076115,\n", " -0.013001847747745683,\n", " 0.0010744769606115465,\n", " 0.01600227286154807,\n", " 0.008311991410761116,\n", " 0.007676766563520323,\n", " -0.038410863989118714,\n", " 0.016421252527603555,\n", " 0.02581447869185549,\n", " 0.014569638000608991,\n", " 0.009886540271410935,\n", " -0.01515080097047686,\n", " -0.010981290377829668,\n", " 0.02281405171540799,\n", " -0.022408589264925532,\n", " 0.00032204743983816584,\n", " -0.0037403962745408852,\n", " 0.0018144469571968486,\n", " 0.0125761113365488,\n", " -0.00642658896710805,\n", " 0.020178542993304332,\n", " -0.017664672447551873,\n", " 0.0018617510416904979,\n", " 0.0008962421961368364,\n", " 4.919802804552858e-06,\n", " -0.008055198773808237,\n", " -0.00022638351487060885,\n", " 0.01135296444599235,\n", " -0.019448708347261767,\n", " -0.01977308054282187,\n", " 0.033842644897162794,\n", " -0.02731469218007924,\n", " 0.004781084503586695,\n", " -0.02705789861180381,\n", " 0.004419546950119946,\n", " 0.035653713365373624,\n", " 0.011001563407221535,\n", " -0.0034802241008641136,\n", " 0.03005832558825131,\n", " -0.0019158126862327833,\n", " -0.0037708060514593253,\n", " -0.03632948473705943,\n", " 0.014894008333523983,\n", " -0.017705218506335607,\n", " 0.03668088763847536,\n", " 0.0007898081515452752,\n", " 0.007778132176140938,\n", " -0.020313696522583448,\n", " -0.03251813285964701,\n", " -0.006044777918588156,\n", " -0.007061814280010121,\n", " 0.005169653228570543,\n", " 0.0022722822151822033,\n", " -0.005696755252388042,\n", " -0.015515718293498142,\n", " 0.0008523170662904846,\n", " -0.0030798294420683416,\n", " -0.0016801373225684905,\n", " -0.02311139134246716,\n", " -0.035572621247806156,\n", " 0.035788870619942965,\n", " 0.000670703405376137,\n", " 0.021219230756688863,\n", " 0.010575826996024652,\n", " 0.022030157520298896,\n", " -0.029544738451700445,\n", " -0.01877293697557596,\n", " 0.0017147706472769029,\n", " -0.0049905738709531584,\n", " 0.016326643194463062,\n", " 0.03797836897013532,\n", " 0.013468130217726302,\n", " 0.020448851914507675,\n", " 0.055521401378690875,\n", " -0.024152080968496803,\n", " 0.039275850301795284,\n", " -0.0026659194303446584,\n", " -0.0006204428956371669,\n", " 0.007318607382624275,\n", " -0.004095176617204955,\n", " -0.012792357914717941,\n", " -0.00013821643088599762,\n", " 0.0036525460148481817,\n", " 0.001841477895883311,\n", " -0.03295062787863041,\n", " 0.012258498680097764,\n", " 0.003155853767949123,\n", " 0.0031169968954507378,\n", " 0.005615662669159294,\n", " -0.016096882194688564,\n", " -0.008257929999049469,\n", " -0.020381273287223004,\n", " -0.015299470784006444,\n", " -0.014447998892935231,\n", " 0.02086782971791805,\n", " -0.011379995151848173,\n", " 0.01938113158262221,\n", " -0.029463646334132974,\n", " 0.0014596668473634176,\n", " 0.004743917283034937,\n", " 0.0022368044137464353,\n", " 0.017367332820492704,\n", " 0.02730117682715133,\n", " 0.02959879986341209,\n", " -0.028058040316404607,\n", " -0.00565283035537233,\n", " -0.0014148970079590714,\n", " -0.02690922786695167,\n", " -0.01130566071074466,\n", " -0.012359863827057102,\n", " -0.010481218594206714,\n", " -0.02603072620134719,\n", " 0.018637783446296845,\n", " -0.012562595983620887,\n", " 0.009109402821443237,\n", " 0.0015770821744165667,\n", " 0.017461940290988087,\n", " -0.025273860849448805,\n", " 0.018610752740441022,\n", " 0.008122775538447797,\n", " -0.024476451301411795,\n", " -0.00028445766078060255,\n", " -0.02388177204729346,\n", " -0.016096882194688564,\n", " -0.05235879016710844,\n", " -0.017826856682686812,\n", " -0.004598626307737331,\n", " -0.00894045904719923,\n", " -0.0035140127160145315,\n", " -0.024881913751894254,\n", " 0.008406599812579053,\n", " -0.0036694402060080712,\n", " -0.008643120351462618,\n", " -0.033166873525476995,\n", " 0.0036525460148481817,\n", " 0.03970834532077868,\n", " 0.007284819000304496,\n", " 0.0210300158156981,\n", " 0.01463721476524855,\n", " -0.006281297991810444,\n", " -0.02461160483069091,\n", " 0.01923246270041518,\n", " -0.0008012117887858603,\n", " -0.010771800544801926,\n", " 0.0047337807683390035,\n", " 0.029220368118785454,\n", " -0.019354100876766388,\n", " -0.032896566466918756,\n", " 0.011123201583572741,\n", " -0.005946790678538242,\n", " -0.004311423195374097,\n", " -0.023692555243657584,\n", " 0.020151512287448506,\n", " -0.008359296077331362,\n", " -0.004422925788351924,\n", " -0.012488260611194818,\n", " 0.0005790518944647985,\n", " -0.031436900900123854,\n", " 0.004095176617204955,\n", " -0.02278702100955217,\n", " -0.011102928554180873,\n", " 0.001799242185152948,\n", " -0.0029666376628051648,\n", " 0.0062002054085816966,\n", " 0.02722008284693875,\n", " -0.0016801373225684905,\n", " 0.02280053636248008,\n", " -0.005831909712989715,\n", " 0.009582442967887812,\n", " -0.003747153951004841,\n", " 0.0034498145567763124,\n", " -0.010305518074821307,\n", " 0.0155832950581377,\n", " 0.019327070170910562,\n", " 0.03500497269954364,\n", " -0.011697607808299208,\n", " 0.00016155166339282948,\n", " 0.021895002128374665,\n", " -0.008994521390233432,\n", " 0.0069536905252642715,\n", " -0.011447572847810287,\n", " -0.005744059453297011,\n", " 0.029625830569267913,\n", " -0.039275850301795284,\n", " -0.021205715403760952,\n", " -0.0036593036913121373,\n", " 0.024260203791920096,\n", " 0.014623699412320638,\n", " -0.008636362674998663,\n", " -0.016488829292243115,\n", " -0.022922176401476396,\n", " -0.004618899337129199,\n", " 0.0014115181697270936,\n", " 0.03822164532283773,\n", " -0.010521765584313005,\n", " 0.008899912988415495,\n", " -0.003493739686622664,\n", " -0.011535422641841713,\n", " 0.006838809559715745,\n", " -0.011548937994769625,\n", " 0.0025932739426958555,\n", " 0.012285529385953588,\n", " -0.012738296503006296,\n", " -0.017786310623903078,\n", " -0.002476703325200701,\n", " -0.006622562515885324,\n", " 0.04138425653442017,\n", " -0.016015788214475985,\n", " -0.0016936527919117217,\n", " 0.005054772263022016,\n", " 0.016988901075866068,\n", " -0.0013836425214826368,\n", " -0.002929470209422769,\n", " -0.0022384938328624242,\n", " -0.009278345664364689,\n", " -0.016583436762738497,\n", " -0.0193676162296943,\n", " -0.01835395917216559,\n", " 0.000876813759887644,\n", " 0.0016041129966877096,\n", " 0.006629320192349281,\n", " -0.010433914858959024,\n", " -0.01709702389928936,\n", " 0.005193305561855667,\n", " 0.01779982597683099,\n", " 0.01684023033101393,\n", " -0.0016852056963317767,\n", " -0.009744628134345307,\n", " -0.011623273367195694,\n", " 0.007778132176140938,\n", " -0.029977231608038727,\n", " -0.0003412646986978597,\n", " 0.009764901163737174,\n", " -0.006419831290644094,\n", " 0.00020188679216961967,\n", " 0.0183674745250935,\n", " -0.007237514799395528,\n", " -0.016421252527603555,\n", " -0.013866834991744808,\n", " -0.006375905927967104,\n", " -0.0019597378160791353,\n", " -0.031247682233842868,\n", " 0.0003847675028690441,\n", " -0.0106839507507705,\n", " 0.018083650250962247,\n", " -0.0011276940120111569,\n", " -0.01527244007815062,\n", " -0.00676785349118293,\n", " 0.004220194097449416,\n", " -0.01163003104365965,\n", " 0.03292359717277458,\n", " 0.0018059998616169039,\n", " -0.011994947435358377,\n", " 0.004659445861574211,\n", " 0.0042539829454304725,\n", " 0.026949775788380516,\n", " 0.015123770264621037,\n", " -0.026003695495491367,\n", " -0.009312134046684467,\n", " -0.03322093493718864,\n", " 0.003360274645136981,\n", " -0.024152080968496803,\n", " 0.010075756143724253,\n", " 0.01734030211463688,\n", " 0.023597947773162202,\n", " 0.024341295909487567,\n", " -0.026787589690600466,\n", " -0.01961089444504182,\n", " -0.006146143531208772,\n", " -0.008278203028441336,\n", " -0.006710412775578028,\n", " -0.021705787187383904,\n", " -0.0013067734860438614,\n", " 0.0018347201030040356,\n", " 0.0033264862628172016,\n", " -0.01582657327348522,\n", " 0.022449135323709266,\n", " 0.006473892702355741,\n", " -0.00018953284212437575,\n", " -0.0022165311515239287,\n", " -0.002208084055943984,\n", " -0.015921180743980603,\n", " -0.015218378666438973,\n", " -0.025746901927215935,\n", " -0.0028703403075325167,\n", " -0.03678901046189865,\n", " 0.013366764139444409,\n", " 0.027760700689345438,\n", " 0.004321560175731309,\n", " 0.011880066004148572,\n", " 0.051061308835448474,\n", " -0.0005718718050141857,\n", " -0.004757432635962849,\n", " -0.02715250608229919,\n", " 0.004558080248953596,\n", " 0.032410010036223715,\n", " 0.002426020286059754,\n", " 0.020948921835485516,\n", " -0.007940317342598433,\n", " -0.02057049009085888,\n", " 0.012805873267645854,\n", " -0.01654289070395476,\n", " 0.002365200965053513,\n", " -0.03357233783860456,\n", " 0.01071773913309028,\n", " 0.013441098580547924,\n", " 0.010041967761404475,\n", " -0.03668088763847536,\n", " 0.024016925576572576,\n", " -0.011481361230130067,\n", " -0.011156990897215075,\n", " 0.0275985164542105,\n", " -0.013589768394077507,\n", " -0.011724638514155032,\n", " 0.03381561419130697,\n", " 0.010055483114332386,\n", " 0.007325365059088231,\n", " -0.005409552605686086,\n", " 0.0330587507020537,\n", " 0.007142906863238868,\n", " 0.0005000710269233772,\n", " 0.032653286388926124,\n", " -0.021949065402731425,\n", " -0.02792288678712549,\n", " -0.019097307308490952,\n", " -0.0021337491491791923,\n", " -0.03424810921029037,\n", " -0.013231609678842737,\n", " -0.009704081144239016,\n", " -0.0028416199497300655,\n", " 0.0023516853792949623,\n", " -0.0024125049331318424,\n", " -0.0007420817704802885,\n", " -0.028003978904692958,\n", " 0.004456714170671703,\n", " -0.016745622860518547,\n", " 0.022759990303696347,\n", " -0.0014351701537662583,\n", " -0.0120219781412142,\n", " 0.017124054605145184,\n", " -0.008332265371475538,\n", " 0.013880350344672719,\n", " 0.010785315897729839,\n", " -0.011494876583057978,\n", " -0.026990321847164253,\n", " -0.019016215190923485,\n", " 0.035707774777085276,\n", " 0.02182742536373511,\n", " 0.01215713260181587,\n", " 0.2147332088184969,\n", " -0.03968131461492286,\n", " 0.019637925150897642,\n", " 0.0018516144105792446,\n", " -0.0027284281704668886,\n", " -0.02428723449777592,\n", " -0.020056902954308016,\n", " 0.011582726377089403,\n", " 0.002005352597872115,\n", " 0.009987905418370273,\n", " 0.024503482007267617,\n", " -0.0070482989270822085,\n", " -0.006909765628248558,\n", " -0.0023297229307871056,\n", " -0.004625657013593154,\n", " -0.014502060304646878,\n", " -0.035572621247806156,\n", " -0.011961159053038597,\n", " -0.019340585523838473,\n", " -0.008899912988415495,\n", " 0.008102502509055929,\n", " -0.007088844985865943,\n", " -0.008845851576703848,\n", " -0.016326643194463062,\n", " 0.018637783446296845,\n", " -0.01494806974523563,\n", " -0.012103071190104226,\n", " -0.015840088626413132,\n", " 0.014407452834151496,\n", " 0.025679325162576375,\n", " -0.00992708633019467,\n", " 0.02008393552280895,\n", " 0.02255725814713256,\n", " -0.009109402821443237,\n", " -0.012272014033025675,\n", " -0.014461514245863142,\n", " 0.019691986562609287,\n", " 0.026936260435452605,\n", " 0.020137996934520595,\n", " -0.0038620351493840067,\n", " 0.03140986646897781,\n", " -0.035302314189247924,\n", " 0.010893439652475688,\n", " 0.0013642140852334443,\n", " -0.01811068095681807,\n", " 0.020746191541566844,\n", " ...]]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "doc_result = embeddings_hf.embed_documents([text_hf])\n", "doc_result" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "上面给出的例子用于熟悉基本models中的相关操作,详细的API开放接口还有很多,例如针对微软Azure的AzureOpenAI,Cohere和Llama-cpp等,点击[此处](https://python.langchain.com/en/latest/modules/models/text_embedding.html)可以直接跳转到相关位置。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Prompt\n", "Prompt是一种为了更好地使用预训练模型的知识,采用在输入端添加额外文本的技术。Prompt的设计有时候可以极大地激发出大模型的潜力,基于prompt可以完成很多我们想象不到的任务,那么,现在我们就来熟悉一下什么是Prompt以及在LangChain中如何去更好地使用和完善它们,LangChain提供了几个类和函数来轻松构建Prompt模板。\n", "\n", "- [Prompt Templates](#prompt-templates)\n", "- [Chat Prompt Template](#chat-model-prompt-template)\n", "- [Example Selectors](#example-selectors)\n", "- [Output Parser](#output-parser)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Prompt Templates\n", "语言模型的文本输入字符串本身就是一种提示,通常来说prompt由模板、一些例子(有的话)和用户的输入构成,其概念和含义并不复杂。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 什么是prompt template:\n", "Prompt Template,也就是提示模版,是一种可重复使用生成prompt的方式,用template可以模版化提示指令,它由一个字符串和可供用户输入的参数组成。\n", "提示模版包含如下的内容:\n", "- 给语言模型的指令\n", "- 几个例子,帮助语言模型更好地回答\n", "- 一个让语言模型回答的问题\n", "- ..." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "现在我们看一个创建prompt template的例子:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#一般导入的必要库,为了进一步模版化处理\n", "from langchain import PromptTemplate\n", "\n", "#具体的模版内容,其中要进行补全的地方(也就是为了定制我们具体问题以及要求的地方用一个变量进行代替)用中括号\n", "#进行变量的放置,不需要其他的操作,类似于字符串中对于某一个变量对其的format格式化\n", "template = \"\"\"\n", "I want you to act as a naming consultant for new companies.\n", "Here are some examples of good company names:\n", "- search engine, Google\n", "- social media, Facebook\n", "- video sharing, YouTube\n", "The name should be short, catchy and easy to remember.\n", "What is a good name for a company that makes {product}?\n", "\"\"\"\n", "\n", "\"\"\"input_variables就是模版中需要填补的变量,在prompttemplate中格式化模版可以将变量以及模版内容进行很好的组合\"\"\"\n", "prompt = PromptTemplate(\n", " input_variables=[\"product\"],\n", " template=template,\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "让我们看看prompt长什么样子:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PromptTemplate(input_variables=['product'], output_parser=None, partial_variables={}, template='\\nI want you to act as a naming consultant for new companies.\\nHere are some examples of good company names:\\n- search engine, Google\\n- social media, Facebook\\n- video sharing, YouTube\\nThe name should be short, catchy and easy to remember.\\nWhat is a good name for a company that makes {product}?\\n', template_format='f-string', validate_template=True)" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "prompt" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 创建prompt template\n", "我们可以从上面的示例中看到:通过LangChain的PromptTemplate类,可以生成具体的prompt,那么通过继续使用这个类生成几个具体的prompts。prompt template接受多个输入变量,用来格式化生成prompt" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "'Tell me a joke.'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from langchain import PromptTemplate\n", "\n", "# input_variables的值可以为空,说明其中没有任何变量\n", "no_input_prompt = PromptTemplate(input_variables=[], template=\"Tell me a joke.\")\n", "no_input_prompt.format()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Tell me a funny joke.'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 一个input_variable的示例,这样模版化之后的提示将把adjective作为参数传入\n", "one_input_prompt = PromptTemplate(input_variables=[\"adjective\"], template=\"Tell me a {adjective} joke.\")\n", "one_input_prompt.format(adjective=\"funny\")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Tell me a funny joke about chickens.'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 多个input_variables的示例,模版后的提示将adjective和content作为参数传入\n", "multiple_input_prompt = PromptTemplate(\n", " input_variables=[\"adjective\", \"content\"],\n", " template=\"Tell me a {adjective} joke about {content}.\"\n", ")\n", "multiple_input_prompt.format(adjective=\"funny\", content=\"chickens\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 从LangChainHub加载本地prompt template" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "from langchain.prompts import load_prompt\n", "#可以加载用json格式写好的prompt\n", "test_prompt = PromptTemplate(\n", " input_variables=[\"input\"],\n", " template=\"{input}, tell me the answer by using Chinese.\"\n", ")\n", "#将创建好的提示模版格式化,其中的补全的变量就是1+1等于几?\n", "test_prompt.format(input=\"what is 1+1?\")\n", "#然后将创建好的模版保存在指定位置处\n", "test_prompt.save(\"test_prompt.json\")" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, template='{input}, tell me the answer by using Chinese.', template_format='f-string', validate_template=True)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#加载本地的模版使用到的方法是固定的,将具体文件的位置传入即可\n", "prompt = load_prompt(\"./test_prompt.json\")\n", "prompt" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 在prompt template中添加几个例子\n", "如果生成带有几个例子的模版,该怎么做?通过PromptTemplate类固然是可以,将例子固定在具体的模版中是我们想到的方法。那么LangChain有没有提供直接的类可以用来达到我们的目的和要求。下面是给语言模型几个合适的例子从而使大模型能够更准确、更合适地回答问题,LangChain中使用FewShotPromptTemplate类生成带有例子的prompt。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面是创建一个让大语言模型去回答反义词的提示模版:" ] }, { "cell_type": "code", "execution_count": 126, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "\n", "Word: happy\n", "Antonym: sad\n", "\n", "\n", "\n", "\n", "Word: tall\n", "Antonym: short\n", "\n", "\n", "\n", "Word: big\n", "Antonym:\n" ] } ], "source": [ "from langchain import PromptTemplate, FewShotPromptTemplate\n", "#如下是几个提示示例,让大模型知道几个例子回答的时候可以类比着回答\n", "few_examples = [\n", " {\"word\": \"happy\", \"antonym\": \"sad\"},\n", " {\"word\": \"tall\", \"antonym\": \"short\"},\n", "]\n", "\n", "#我们定义如下的提示模版\n", "example_formatter_template = \"\"\"\n", "Word: {word}\n", "Antonym: {antonym}\\n\n", "\"\"\"\n", "#模版格式化提示模版\n", "example_prompt = PromptTemplate(\n", " input_variables=[\"word\", \"antonym\"],\n", " template=example_formatter_template,\n", ")\n", "\n", "#现在构建一个少样本提示模版对象:few_shot_prompt\n", "'''\n", "其中的参数有examples, example_prompt, prefix, suffix, input_variables和example_separator。其中,\n", " examples:示例,样例,这个就是我们写好的几个供大模型了解格式以及例子的具体样例\n", " example_prompt:具体的模版化后的提示模版,这个可以就是通过promptTemplate构建的提示模版,只等待填入具体的变量,\n", "其格式内容中已经将待补全的变量放在其中\n", " prefix:前缀,一般作为大模型接受指令的入口,可以去声明大模型即将承担的角色以及告诉大模型即将要做的事情等\n", " suffix:后缀,一般放置于样例之后,作为提示模版的最后一部分\n", " input_variables:填补的变量\n", " example_separator:分割符,分割前缀、样例和后缀的标志\n", "'''\n", "few_shot_prompt = FewShotPromptTemplate(\n", " examples=few_examples,\n", " example_prompt=example_prompt,\n", " prefix=\"Give the antonym of every input\",\n", " suffix=\"Word: {input}\\nAntonym:\",\n", " input_variables=[\"input\"],\n", " example_separator=\"\\n\\n\",\n", ")\n", "\n", "print(few_shot_prompt.format(input=\"big\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 从prompt template中选取例子\n", "上面那个代码案例中提供的是少量样本示例,如果有非常多可供LLM参考的例子时,使用ExampleSelector类来可控制地选择几个最好的例子供LLM学习。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面是一个使用LengthBasedExampleSelector选择一定长输入的例子,它是一个自动选择例子的方法,我们具体来看:**如果用户担心prompt超过输入窗口大小时,这很有用。当用户输入很长时,它自动选择少量的例子;当用户输入很短时,它选择更多的例子。**" ] }, { "cell_type": "code", "execution_count": 127, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "\n", "Word: happy\n", "Antonym: sad\n", "\n", "\n", "\n", "\n", "Word: tall\n", "Antonym: short\n", "\n", "\n", "\n", "\n", "Word: energetic\n", "Antonym: lethargic\n", "\n", "\n", "\n", "Word: big\n", "Antonym:\n" ] } ], "source": [ "from langchain.prompts.example_selector import LengthBasedExampleSelector\n", "#依然和上面一样,反义词对儿的组合,这里给出下面几种:\n", "few_examples = [\n", " {\"word\": \"beautiful\", \"antonym\": \"ugly\"},\n", " {\"word\": \"outgoing\", \"antonym\": \"incoming\"},\n", " {\"word\": \"happy\", \"antonym\": \"sad\"},\n", " {\"word\": \"tall\", \"antonym\": \"short\"},\n", " {\"word\": \"energetic\", \"antonym\": \"lethargic\"},\n", " {\"word\": \"sunny\", \"antonym\": \"gloomy\"},\n", " {\"word\": \"windy\", \"antonym\": \"calm\"},\n", "]\n", "#我们定义如下的提示模版\n", "example_formatter_template = \"\"\"\n", "Word: {word}\n", "Antonym: {antonym}\\n\n", "\"\"\"\n", "#模版格式化提示模版\n", "example_prompt = PromptTemplate(\n", " input_variables=[\"word\", \"antonym\"],\n", " template=example_formatter_template,\n", ")\n", "\n", "'''\n", "使用LengthBasedExampleSelector选择例子。\n", "其中的examples:同上示例中的作用\n", "example_prompt:同上示例中的作用\n", "max_length:这是格式化后的例子的最大长度。长度由下面的get_text_length函数决定。\n", "'''\n", "example_selector = LengthBasedExampleSelector(\n", " examples=few_examples,\n", " example_prompt=example_prompt,\n", " max_length=25,\n", ")\n", "\n", "#现在使用example_selector来创建fewshotprompttemplate\n", "dynamic_prompt = FewShotPromptTemplate(\n", " example_selector=example_selector,\n", " example_prompt=example_prompt,\n", " prefix=\"Give the antonym of every input\",\n", " suffix=\"Word: {input}\\nAntonym:\",\n", " input_variables=[\"input\"],\n", " example_separator=\"\\n\\n\",\n", ")\n", "\n", "print(dynamic_prompt.format(input=\"big\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "根据上面的例子我们知道:当输入问题很长时,LengthBasedExampleSelector会选择更少的提示" ] }, { "cell_type": "code", "execution_count": 128, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Word: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else\n", "Antonym:\n" ] } ], "source": [ "long_string = \"big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else\"\n", "print(dynamic_prompt.format(input=long_string))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### chat model prompt template\n", "下面的示例是利用prompt template在chat model中使用的情况:chat model可以使用以前的历史信息进行单次生成回复,单次输入包含了过去聊天中的一系列模板、例子、用户问题的组合。LangChain提供了一些类和方法使得构建和使用prompt更加容易。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts import (\n", " ChatPromptTemplate,\n", " PromptTemplate,\n", " SystemMessagePromptTemplate,\n", " AIMessagePromptTemplate,\n", " HumanMessagePromptTemplate,\n", ")\n", "from langchain.schema import (\n", " AIMessage,\n", " HumanMessage,\n", " SystemMessage\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "ChatPromptTemplate可以使用一个或者多个MessagePromptTemplate类构建prompt。可以使用ChatPromptTemplate的format_prompt函数返回prompt值,然后将其转化为string或message对象。" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "system_template=\"You are a helpful assistant that translates {input_language} to {output_language}.\"\n", "system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)\n", "human_template=\"{text}\"\n", "human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)" ] }, { "cell_type": "code", "execution_count": 131, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}),\n", " HumanMessage(content='I love programming.', additional_kwargs={})]" ] }, "execution_count": 131, "metadata": {}, "output_type": "execute_result" } ], "source": [ "chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])\n", "# 从格式化的信息中获取完整的聊天信息\n", "chat_prompt.format_prompt(input_language=\"English\", output_language=\"French\", text=\"I love programming.\").to_messages()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面是一种快速构建MessagePromptTemplate的方法" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "prompt=PromptTemplate(\n", " template=\"You are a helpful assistant that translates {input_language} to {output_language}.\",\n", " input_variables=[\"input_language\", \"output_language\"],\n", ")\n", "system_message_prompt = SystemMessagePromptTemplate(prompt=prompt)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Example Selectors\n", "根据模型功能需要动态选择提示词\n", "LangChain中的BaseExampleSelector类用于选择例子,select_examples函数接收输入变量并返回一系列例子。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 基本接口定义如下" ] }, { "cell_type": "code", "execution_count": 133, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from abc import ABC, abstractmethod\n", "from typing import Dict,List\n", "'''它是一个抽象基类,不能被示例化,而是用于定义其他类的接口和规范'''\n", "class BaseExampleSelector(ABC):\n", " \"\"\"\n", " 这是一个抽象方法,由派生类实现,以满足BaseExampleSelector接口的要求,这个方法是根据输入变量选择要包含在提示中的示例,返回一个字典列表\n", " \"\"\"\n", " @abstractmethod\n", " def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "一个ExampleSelector类必须实现两个方法:\n", "- 1. add_example方法接受一个例子将其添加到example列表中\n", "- 2. select_examples告诉选择器如何选择例子并返回例子\n", "\n", "因此在一个示例选择器中可以随时调用上述两种方法,下面实现一个自定义的example selector" ] }, { "cell_type": "code", "execution_count": 134, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts.example_selector.base import BaseExampleSelector\n", "from typing import Dict, List\n", "import numpy as np\n", "\n", "class CustomExampleSelector(BaseExampleSelector):\n", "\n", " def __init__(self, examples: List[Dict[str, str]]):\n", " self.examples = examples\n", "\n", " def add_example(self, example: Dict[str, str]) -> None:\n", " \"\"\"添加新的例子来存储一个键\"\"\"\n", " self.examples.append(example)\n", "\n", " def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:\n", " \"\"\"根据输入的信息选择要使用的例子\"\"\"\n", " return np.random.choice(self.examples, size=2, replace=False)\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "使用自定义的example selector" ] }, { "cell_type": "code", "execution_count": 135, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "array([{'foo': '1'}, {'foo': '3'}], dtype=object)" ] }, "execution_count": 135, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "examples = [\n", " {\"foo\": \"1\"},\n", " {\"foo\": \"2\"},\n", " {\"foo\": \"3\"}\n", "]\n", "\n", "# 初始化示例选择器\n", "example_selector = CustomExampleSelector(examples)\n", "# 选择示例\n", "example_selector.select_examples({\"foo\": \"foo\"})\n", "# 将新的例子添加到例子集中\n", "example_selector.add_example({\"foo\": \"4\"})\n", "example_selector.examples\n", "# 选择示例\n", "example_selector.select_examples({\"foo\": \"foo\"})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 基于长度的示例选择器\n", "LengthBased ExampleSelector根据用户输入自动选择一定数量的示例;使总长度不超过LLM输入窗口大小。下面的示例我们上面就遇到过,现在我们走到这里再看一下这个代码示例,是否更加了解它的原理?" ] }, { "cell_type": "code", "execution_count": 136, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts import PromptTemplate\n", "from langchain.prompts import FewShotPromptTemplate\n", "from langchain.prompts.example_selector import LengthBasedExampleSelector\n", "# 这些是很多关于创造反义词的例子。\n", "examples = [\n", " {\"input\": \"happy\", \"output\": \"sad\"},\n", " {\"input\": \"tall\", \"output\": \"short\"},\n", " {\"input\": \"energetic\", \"output\": \"lethargic\"},\n", " {\"input\": \"sunny\", \"output\": \"gloomy\"},\n", " {\"input\": \"windy\", \"output\": \"calm\"},\n", "]" ] }, { "cell_type": "code", "execution_count": 137, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "example_prompt = PromptTemplate(\n", " input_variables=[\"input\", \"output\"],\n", " template=\"Input: {input}\\nOutput: {output}\",\n", ")\n", "example_selector = LengthBasedExampleSelector(\n", " examples=examples,\n", " example_prompt=example_prompt,\n", " max_length=25,\n", ")\n", "dynamic_prompt = FewShotPromptTemplate(\n", " example_selector=example_selector,\n", " example_prompt=example_prompt,\n", " prefix=\"Give the antonym of every input\",\n", " suffix=\"Input: {adjective}\\nOutput:\",\n", " input_variables=[\"adjective\"],\n", ")" ] }, { "cell_type": "code", "execution_count": 138, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: tall\n", "Output: short\n", "\n", "Input: energetic\n", "Output: lethargic\n", "\n", "Input: sunny\n", "Output: gloomy\n", "\n", "Input: windy\n", "Output: calm\n", "\n", "Input: big\n", "Output:\n" ] } ], "source": [ "print(dynamic_prompt.format(adjective=\"big\"))" ] }, { "cell_type": "code", "execution_count": 139, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else\n", "Output:\n" ] } ], "source": [ "long_string = \"big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else\"\n", "print(dynamic_prompt.format(adjective=long_string))" ] }, { "cell_type": "code", "execution_count": 140, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: tall\n", "Output: short\n", "\n", "Input: energetic\n", "Output: lethargic\n", "\n", "Input: sunny\n", "Output: gloomy\n", "\n", "Input: windy\n", "Output: calm\n", "\n", "Input: big\n", "Output: small\n", "\n", "Input: enthusiastic\n", "Output:\n" ] } ], "source": [ "# You can add an example to an example selector as well.\n", "new_example = {\"input\": \"big\", \"output\": \"small\"}\n", "dynamic_prompt.example_selector.add_example(new_example)\n", "print(dynamic_prompt.format(adjective=\"enthusiastic\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### 相似性选择器\n", "Similarity Example Selector根据例子和输入的相似程度来选择例子。该选择器根据例子和输入的词嵌入向量的余弦相似性来工作。" ] }, { "cell_type": "code", "execution_count": 141, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts.example_selector import SemanticSimilarityExampleSelector\n", "from langchain.vectorstores import Chroma\n", "from langchain.embeddings import OpenAIEmbeddings\n", "from langchain.prompts import FewShotPromptTemplate, PromptTemplate\n", "\n", "example_prompt = PromptTemplate(\n", " input_variables=[\"input\", \"output\"],\n", " template=\"Input: {input}\\nOutput: {output}\",\n", ")\n", "\n", "# 这些是很多关于创造反义词的例子。\n", "few_examples = [\n", " {\"input\": \"happy\", \"output\": \"sad\"},\n", " {\"input\": \"tall\", \"output\": \"short\"},\n", " {\"input\": \"energetic\", \"output\": \"lethargic\"},\n", " {\"input\": \"sunny\", \"output\": \"gloomy\"},\n", " {\"input\": \"windy\", \"output\": \"calm\"},\n", "]" ] }, { "cell_type": "code", "execution_count": 142, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using embedded DuckDB without persistence: data will be transient\n" ] } ], "source": [ "example_selector = SemanticSimilarityExampleSelector.from_examples(\n", " # 这是可以选择的例子清单。\n", " few_examples,\n", " # 这里使用OpenAI的嵌入方法,用于产生嵌入,而嵌入是用来衡量语义相似性的。\n", " OpenAIEmbeddings(),\n", " # 这是VectorStore类,用于存储嵌入并进行相似度搜索。\n", " Chroma,\n", " # 这是要产生的例子的数量。\n", " k=1\n", ")\n", "similar_prompt = FewShotPromptTemplate(\n", " example_selector=example_selector,\n", " example_prompt=example_prompt,\n", " prefix=\"Give the antonym of every input\",\n", " suffix=\"Input: {adjective}\\nOutput:\",\n", " input_variables=[\"adjective\"],\n", ")" ] }, { "cell_type": "code", "execution_count": 143, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: worried\n", "Output:\n" ] } ], "source": [ "print(similar_prompt.format(adjective=\"worried\"))" ] }, { "cell_type": "code", "execution_count": 144, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: fat\n", "Output:\n" ] } ], "source": [ "print(similar_prompt.format(adjective=\"fat\"))" ] }, { "cell_type": "code", "execution_count": 145, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Give the antonym of every input\n", "\n", "Input: happy\n", "Output: sad\n", "\n", "Input: joyful\n", "Output:\n" ] } ], "source": [ "# 您也可以向SimilarityExampleSelector添加新的示例。\n", "similar_prompt.example_selector.add_example({\"input\": \"enthusiastic\", \"output\": \"apathetic\"})\n", "print(similar_prompt.format(adjective=\"joyful\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Output Parser\n", "输出解析器,顾名思义,就是将输出答案进行解析,它指示模型去格式化输出内容,将输出解析为需要的格式。\n", "Output parsers类结构化模型的响应信息。例如我们提前定义好输出的形式应该包括A属性和B属性,如果正常把提问送给大模型,大模型是不会给你指定出特别严格划分之后的答案的,因此把这种答案进行解析处理进一步给到用户,用户可以用解析处理之后的结果去做更方便的应用或者就已经达到用户的目的。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面是关于PydanticOutputParser的一个示例说明,PydanticOutputParser能够让LLM输出符合JSON格式的回复。该功能效果和LLM生成能力相关。\n", "下面是使用PydanticOutputParser的例子。" ] }, { "cell_type": "code", "execution_count": 146, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate\n", "from langchain.llms import OpenAI\n", "from langchain.chat_models import ChatOpenAI\n", "\n", "from langchain.output_parsers import PydanticOutputParser\n", "from pydantic import BaseModel, Field, validator\n", "from typing import List" ] }, { "cell_type": "code", "execution_count": 147, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#指定使用的大模型\n", "model_name = 'text-davinci-003'\n", "#设置对应的随机性\n", "temperature = 0.0\n", "#model即是调用到的大模型\n", "model = OpenAI(model_name=model_name, temperature=temperature)" ] }, { "cell_type": "code", "execution_count": 148, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "# 定义你想要的数据结构\n", "\"\"\"定义了一个名为Joke的Pydantic模型类,用来表示一个笑话,示例化之后用于提示大模型来填充这个数据结构\"\"\"\n", "class Joke(BaseModel):\n", " \"\"\"\n", " setup:字符串类型,使用Field函数指定一个描述字符串,该属性表示笑话的问题部分,也就是笑话的开头\n", " punchline:字符串类型,同样使用Field函数指定一个描述字符串,表示笑话的答案部分也就是笑话的结尾\n", " \"\"\"\n", " setup: str = Field(description=\"question to set up a joke\")\n", " punchline: str = Field(description=\"answer to resolve the joke\")\n", " # 你可以用Pydantic轻松地添加自定义逻辑结构。\n", " \"\"\"\n", " 装饰器成分,用于标记接下来的方法是一个验证器,验证器是一个函数,接受一个字段值,并返回一个经过验证的值,这里标记的就是\n", " question_ends_with_question_mark方法是一个验证器,将会用于setup属性\n", " \"\"\"\n", " @validator('setup')\n", " def question_ends_with_question_mark(cls, field):\n", " if field[-1] != '?':\n", " raise ValueError(\"Badly formed question!\")\n", " return field" ] }, { "cell_type": "code", "execution_count": 149, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "#参数值是之前定义的joke类,parser对象的作用是把输出结果解析成一个joke对象\n", "parser = PydanticOutputParser(pydantic_object=Joke)" ] }, { "cell_type": "code", "execution_count": 150, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "'''\n", "prompttemplate的两个模版参数占位符是format_instructions和query,但是指定的input_variables是query,\n", "而partial_variables则是指定一个字典,其中包含了键为format_instructions的变量信息,这个值是之前定义的parser对象\n", "调用get_format_instructions方法返回的格式说明字符串\n", "'''\n", "prompt = PromptTemplate(\n", " template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n", " input_variables=[\"query\"],\n", " partial_variables={\"format_instructions\": parser.get_format_instructions()}\n", ")" ] }, { "cell_type": "code", "execution_count": 151, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "# 将用户的query传入提示模版中\n", "joke_query = \"Tell me a joke.\"\n", "_input = prompt.format_prompt(query=joke_query)" ] }, { "cell_type": "code", "execution_count": 152, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "output = model(_input.to_string())" ] }, { "cell_type": "code", "execution_count": 153, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "parser.parse(output)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面是另外一个示例,我们接着看一下" ] }, { "cell_type": "code", "execution_count": 154, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "Actor(name='Tom Hanks', film_names=['Forrest Gump', 'Saving Private Ryan', 'The Green Mile', 'Cast Away', 'Toy Story'])" ] }, "execution_count": 154, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "下面这段代码定一个了一个名为actor的数据结构,它也是基于basemodel类创建的,这个actor有两个属性,分别是name\n", "和file_names,用来表示姓名和演员出演的电影列表,这两个属性上,同样适用field类,为两者分别指定了description属性,用来\n", "描述这两个属性的作用。\n", "其中:\n", " actor_query:用户输入的问题\n", " parser:PydanticOutputParser类实例,作用是将输出的结果解析成一个actor对象\n", " prompt: prompttemplate类实例,包含一个字符串模版和一些变量\n", "\"\"\"\n", "class Actor(BaseModel):\n", " name: str = Field(description=\"name of an actor\")\n", " film_names: List[str] = Field(description=\"list of names of films they starred in\")\n", "\n", "actor_query = \"Generate the filmography for a random actor.\"\n", "\n", "parser = PydanticOutputParser(pydantic_object=Actor)\n", "\n", "prompt = PromptTemplate(\n", " template=\"Answer the user query.\\n{format_instructions}\\n{query}\\n\",\n", " input_variables=[\"query\"],\n", " partial_variables={\"format_instructions\": parser.get_format_instructions()}\n", ")\n", "\n", "_input = prompt.format_prompt(query=actor_query)\n", "\n", "output = model(_input.to_string())\n", "\n", "parser.parse(output)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Index\n", "该模块用于接受用户查询,返回最相关概念。\n", "这里LangChain主要在针对用户提供的文档构建索引,将索引组合成检索器;然后可以建立一个问答链用于模型提问回答。\n", "LangChain使用chromadb构建向量池vectorstore,向量池用于检索和查找词嵌入。\n", "\n", "详细文档说明点击👉[此处](https://python.langchain.com/en/latest/modules/indexes.html)👈直接访问。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "了解索引基本概念也很重要,下面是索引器Retriever的接口,用户可以自己实现如何返回相关文档。LangChain关注于使用Vectorstore retriever进行检索相关文档。" ] }, { "cell_type": "code", "execution_count": 155, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from abc import ABC, abstractmethod\n", "from typing import List\n", "from langchain.schema import Document\n", "\n", "\"\"\"\n", "定义了一个名为BaseRetriever的抽象基类,继承自ABC。该类包含了一个名为get_relevant_documents的方法,该方法接受一个字符串类型的\n", "参数query,并返回一个文档列表(List[Document])。注释中提到了abstractmethod装饰器,这表示get_relevant_documents方法是一个抽象方\n", "法,子类必须实现该方法。\n", "\"\"\"\n", "class BaseRetriever(ABC):\n", " #这个函数的作用是根据输入的查询语句(query)获取相关的文本内容。返回值为一个文档列表,每个文档都是一个Document对象。\n", " @abstractmethod\n", " def get_relevant_documents(self, query: str) -> List[Document]:\n", " \"\"\"Get texts relevant for a query.\n", "\n", " Args:\n", " query: string to find relevant texts for\n", "\n", " Returns:\n", " List of relevant documents\n", " \"\"\"" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "这里先加载需要的文档" ] }, { "cell_type": "code", "execution_count": 156, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.chains import RetrievalQA\n", "from langchain.llms import OpenAI\n", "from langchain.document_loaders import TextLoader\n", "#用于从文件中加载文本数据。其中,参数'state_of_the_union.txt'表示要加载的文件名,\n", "#encoding='utf-8'表示文件的编码格式为UTF-8。具体来说,\n", "#作用是将文件state_of_the_union.txt中的内容读取到内存中,并以字符串的形式存储在变量loader中。\n", "loader = TextLoader('state_of_the_union.txt',encoding='utf-8')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "创建索引" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面的语句使用VectorstoreIndexCreator直接创建索引" ] }, { "cell_type": "code", "execution_count": 157, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using embedded DuckDB without persistence: data will be transient\n" ] } ], "source": [ "\"\"\"\n", "VectorstoreIndexCreator类用于创建向量空间索引(Vector Space Index)。通过调用from_loaders方法来创建一个名为index的对象,\n", "该方法接受一个参数列表,列表中只包含一个元素,即之前提到的TextLoader对象loader。from_loaders方法的作用是将多个文本数据加载器(TextLoader)\n", "封装成一个向量空间索引对象。因此,index的作用是将state_of_the_union.txt文件中的内容读取到内存中,并以字符串的形式存储在变量loader中,然后\n", "使用VectorstoreIndexCreator类将其封装成一个向量空间索引对象index。\n", "\"\"\"\n", "from langchain.indexes import VectorstoreIndexCreator\n", "index = VectorstoreIndexCreator().from_loaders([loader])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "现在索引建立了,就可以开始根据文档问问题了" ] }, { "cell_type": "code", "execution_count": 158, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "\" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice, a former federal public defender, and from a family of public school educators and police officers. He also said that she is a consensus builder and has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans.\"" ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"What did the president say about Ketanji Brown Jackson\"\n", "index.query(query)" ] }, { "cell_type": "code", "execution_count": 159, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "{'question': 'What did the president say about Ketanji Brown Jackson',\n", " 'answer': \" The president said that he nominated Circuit Court of Appeals Judge Ketanji Brown Jackson, one of the nation's top legal minds, to continue Justice Breyer's legacy of excellence, and that she has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans.\\n\",\n", " 'sources': 'state_of_the_union.txt'}" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "query = \"What did the president say about Ketanji Brown Jackson\"\n", "index.query_with_sources(query)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "如果只是想访问vectorstore,可以这样做" ] }, { "cell_type": "code", "execution_count": 160, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 160, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index.vectorstore" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "或者想访问VectorstoreRetriever" ] }, { "cell_type": "code", "execution_count": 161, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "VectorStoreRetriever(vectorstore=, search_type='similarity', search_kwargs={})" ] }, "execution_count": 161, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index.vectorstore.as_retriever()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "上面是用索引查询的例子,那么索引是怎么创建的呢,有3步:\n", "1.将文档划分成块\n", "2.对每块创建词嵌入\n", "3.将文档和词嵌入存在向量池中\n", "下面会一步步展示" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "加载文档" ] }, { "cell_type": "code", "execution_count": 162, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "documents = loader.load()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "文档切块" ] }, { "cell_type": "code", "execution_count": 163, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.text_splitter import CharacterTextSplitter\n", "\"\"\"\n", "CharacterTextSplitter类用于将文本数据按照指定的大小进行划分(chunking)。接下来,代码通过调用split_documents方法来创建一个名为\n", "text_splitter的对象,该方法接受两个参数:chunk_size表示每个文档被划分成的大小,chunk_overlap表示文档之间的重叠大小。chunk_size被\n", "设置为1000,chunk_overlap被设置为0。然后,代码调用split_documents方法来将documents列表中的文档按照指定的大小进行划分,并返回一个包\n", "含所有划分后文档的列表texts。具体来说,split_documents方法的作用是将一个文本列表按照指定的大小进行划分,并返回一个包含所有划分后文档的\n", "列表。\n", "\"\"\"\n", "text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n", "texts = text_splitter.split_documents(documents)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "根据需要从合适的词嵌入方法中选一个进行词嵌入" ] }, { "cell_type": "code", "execution_count": 164, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.embeddings import OpenAIEmbeddings\n", "embeddings = OpenAIEmbeddings()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面用词嵌入和块创建向量池" ] }, { "cell_type": "code", "execution_count": 165, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using embedded DuckDB without persistence: data will be transient\n" ] } ], "source": [ "from langchain.vectorstores import Chroma\n", "\"\"\"\n", "Chroma类用于将向量空间索引(Vector Space Index)与文本数据结合起来,以实现对文本数据的向量化表示。接下来,代码通过调用\n", "from_documents方法来创建一个名为db的对象,该方法接受两个参数:texts和embeddings。其中,texts是一个包含所有文本数据的列表,\n", "embeddings是一个包含所有向量数据的二维数组。from_documents方法的作用是将指定的文本数据和向量数据结合起来,并返回一个包含所有\n", "文档向量的二维数组。具体来说,from_documents方法的作用是将指定的文本数据和向量数据结合起来,以实现对文本数据的向量化表示。texts\n", "是一个包含所有文本数据的列表,embeddings是一个包含所有向量数据的二维数组。\n", "\"\"\"\n", "db = Chroma.from_documents(texts, embeddings)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "然后创建索引" ] }, { "cell_type": "code", "execution_count": 166, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "\"\"\"\n", "调用db对象的as_retriever方法来创建一个名为retriever的对象。\n", "该方法的作用是将db对象转换为一个检索器(retriever),以便在后续的计算中使用。\n", "retriever将被用于从数据库中检索与给定查询相关的文档向量。\n", "\"\"\"\n", "retriever = db.as_retriever()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "接下来创建一个链并问问题" ] }, { "cell_type": "code", "execution_count": 167, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "\" The President said that Ketanji Brown Jackson is one of the nation's top legal minds and that she will continue Justice Breyer's legacy of excellence.\"" ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "RetrievalQA类用于实现基于检索器的问答(Question Answering)任务。接下来,代码通过调用from_chain_type方法来创建一个名为qa的对象,\n", "该方法接受三个参数:llm、chain_type和retriever。其中,llm表示语言模型(Language Model),chain_type表示查询类型(query type),\n", "retriever表示检索器(retriever)。from_chain_type方法的作用是根据指定的查询类型和检索器创建一个名为qa的对象,以便在后续的计算中使用。\n", "llm被设置为OpenAI(),chain_type被设置为\"stuff\",retriever被设置为之前创建的retriever对象。\n", "\"\"\"\n", "qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=\"stuff\", retriever=retriever)\n", "query = \"What did the president say about Ketanji Brown Jackson\"\n", "\"\"\"\n", "run方法将执行以下操作:首先从数据库中检索与给定查询相关的文档向量;然后将用户输入的问题与每个文档向量进行匹配,找到最佳的文档向量作为答案;\n", "最后将答案封装成一个三元组返回给用户。\n", "\"\"\"\n", "qa.run(query)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "总结以上过程,VectorstoreIndexCreator就是做了切块,词嵌入,创建索引的过程。" ] }, { "cell_type": "code", "execution_count": 168, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "index_creator = VectorstoreIndexCreator(\n", " vectorstore_cls=Chroma,\n", " embedding=OpenAIEmbeddings(),\n", " text_splitter=CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Memory\n", "\n", "Memory涉及在用户与语言模型的整个交互过程中保持状态概念。用户与语言模型的交互在 ChatMessages 的概念中被捕获,因此这归结为从一系列聊天消\n", "息中摄取、捕获、转换和提取知识。有许多不同的方法可以做到这一点,每一\n", "种都有自己的内存类型。通常,对于每种类型的内存,有两种理解使用内存的方法。这些是从一系列消息中提取信息的独立函数,然后您可以在链中使用这种类型的内存。内存可以返回多条信息(例如,最近的 N 条消息和之前所有消息的摘要)。返回的信息可以是字符串或消息列表。我们将介绍最简单的内存形式:“Buffer”内存,它只涉及保留所有先前消息的缓冲区。我们将在这里展示如何使用模块化实用函数,然后展示如何在链中使用它(既返回字符串又返回消息列表)。\n", "\n", "LLMs和chat models都是无状态的,每次输入请求都是独立的;Chains和Agents基于底层模块开发,也是无状态的。在一些应用中,比如聊天机器人,让语言模型知道之前的聊天内容很重要。这就是Memory模块存在的意义。\n", "\n", "LangChain提供两种memory组件;第一,LangChain提供helper utilities负责管理和操作之前的聊天信息;第二,LangChain提供将这些程序合并到Chains模块中的方法。\n", "\n", "查看完整文档以及示例说明,点击👉[LangChain官网直达](https://python.langchain.com/en/latest/index.html)。\n", "\n", "下面是添加Memory的两个案例,方便快速了解:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [Add Memory to an LLMChain](#add-memory-to-an-llmchain)\n", "- [Add Memory to an Agent](#add-memory-to-an-agent)\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们用这个ConversationBufferMemory进行举例,因此先看一下这个类是什么样的:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### ConversationBufferMemory\n", "ConversationBufferMemory可以帮助用户轻松创建对话历史,用法如下" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.memory import ConversationBufferMemory\n", "\n", "\"\"\"\n", "ConversationBufferMemory类用于实现基于记忆缓存(Memories)的对话系统(Conversational System)。接下来,代码通过调用\n", "from_memory方法来创建一个名为memory的对象,该方法不接受任何参数。该方法的作用是根据默认配置创建一个名为memory的对象,以便\n", "在后续的计算中使用。\n", "memory将被用于存储用户和AI之间的对话历史记录。\n", "然后,调用memory对象的chat_memory属性来创建一个名为chat_memory的对话缓存(Conversation Buffer),并向其添加两条消息:一条\n", "是用户发送的消息\"hi!\",另一条是AI发送的消息\"whats up?\"。具体来说,chat_memory.add_user_message()方法的作用是将一条用户消\n", "息添加到对话缓存中;而chat_memory.add_ai_message()方法的作用是将一条AI消息添加到对话缓存中。这样,聊天历史记录就被成功地添加\n", "到了对话缓存中。\n", "\"\"\"\n", "memory = ConversationBufferMemory()\n", "memory.chat_memory.add_user_message(\"hi!\")\n", "memory.chat_memory.add_ai_message(\"whats up?\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "{'history': 'Human: hi!\\nAI: whats up?'}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#加载对话缓存中存储的变量。该方法接受一个空字典作为参数,表示不需要加载任何变量\n", "memory.load_memory_variables({})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "也可以用列表返回历史消息" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "memory = ConversationBufferMemory(return_messages=True)\n", "memory.chat_memory.add_user_message(\"hi!\")\n", "memory.chat_memory.add_ai_message(\"whats up?\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "{'history': [HumanMessage(content='hi!', additional_kwargs={}),\n", " AIMessage(content='whats up?', additional_kwargs={})]}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "memory.load_memory_variables({})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "上面就是对历史对话进行记录以及获取的方式,简单直接,接下来我们通过几个示例看一下具体怎么讲其添加到Chain中:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Add Memory to an LLMChain\n", "\n", "下面展示了ConversationBufferMemory的添加用法,对于其他类型的Memory,您可以点击[此处查看和使用](https://python.langchain.com/en/latest/modules/memory/how_to_guides.html)。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.llms import OpenAI\n", "from langchain.chains import ConversationChain\n", "from langchain import LLMChain, PromptTemplate\n", "\n", "\"\"\"\n", "最重要的一步是正确设置提示。在下面的提示中,我们有两个输入键:一个用于实际输入,\n", "另一个用于来自 Memory 类的输入。重要的是,我们确保 PromptTemplate 和 ConversationBufferMemory 中的键匹配 ( chat_history)。\n", "\"\"\"\n", "\n", "template = \"\"\"You are a chatbot having a conversation with a human.\n", "{chat_history}\n", "Human: {human_input}\n", "Chatbot:\"\"\"\n", "\n", "prompt = PromptTemplate(\n", " input_variables=[\"chat_history\", \"human_input\"], \n", " template=template\n", ")\n", "\"\"\"\n", "调用ConversationBufferMemory类的构造函数来创建一个名为memory的对话缓存对象,该对象将用于存储对话历史记录。\n", "memory对象将使用\"chat_history\"作为key来存储对话历史记录。最后,代码调用LLMChain类的构造函数来创建一个名为\n", "llm_chain的对象,该对象将用于执行长文本链模型。llm_chain对象将使用OpenAI()作为llm参数来执行长文本链模型;\n", "将prompt作为prompt参数;将verbose设置为True以打印调试信息;将memory作为memory参数来加载对话缓存中存储的\n", "历史记录。\n", "\"\"\"\n", "memory = ConversationBufferMemory(memory_key=\"chat_history\")\n", "\n", "llm_chain = LLMChain(\n", " llm=OpenAI(), \n", " prompt=prompt, \n", " verbose=True, \n", " memory=memory,\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "\n", "Human: Hi there!\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "\" Hi there! It's nice to meet you. My name is AI. What's your name?\"" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_chain.predict(human_input=\"Hi there!\")" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: Hi there!\n", "AI: Hi there! It's nice to meet you. My name is AI. What's your name?\n", "Human: I'm doing well! Just having a conversation with an AI.\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "\" That's great! It's always nice to have a conversation with someone new. What would you like to talk about?\"" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_chain.predict(human_input=\"I'm doing well! Just having a conversation with an AI.\")" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n", "\n", "Current conversation:\n", "Human: Hi there!\n", "AI: Hi there! It's nice to meet you. My name is AI. What's your name?\n", "Human: I'm doing well! Just having a conversation with an AI.\n", "AI: That's great! It's always nice to have a conversation with someone new. What would you like to talk about?\n", "Human: Tell me about yourself.\n", "AI:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "\" Sure! I'm an AI created to help people with their everyday tasks. I'm programmed to understand natural language and provide helpful information. I'm also able to learn from my conversations and experiences, so I'm constantly growing and evolving. What else would you like to know?\"" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "llm_chain.predict(input=\"Tell me about yourself.\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "另外一种情景是用户需要进行历史信息的保存,因为用户有保存历史信息,然后在需要的时候加载重用的需求。LangChain的schema类能方便的把历史信息转为为python数据结构,比如字典;也可以转化为json格式;然后从字典、json中加载历史信息。如下所示:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import json\n", "\n", "from langchain.memory import ChatMessageHistory\n", "from langchain.schema import messages_from_dict, messages_to_dict\n", "\n", "#代码创建了一个名为history的ChatMessageHistory对象\n", "history = ChatMessageHistory()\n", "#向对话历史记录中添加一条用户输入的消息:\"hi!\"\n", "history.add_user_message(\"hi!\")\n", "#向对话历史记录中添加一条AI发出的消息:\"whats up?\"。\n", "history.add_ai_message(\"whats up?\")" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "dicts = messages_to_dict(history.messages)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[{'type': 'human', 'data': {'content': 'hi!', 'additional_kwargs': {}}},\n", " {'type': 'ai', 'data': {'content': 'whats up?', 'additional_kwargs': {}}}]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dicts" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "new_messages = messages_from_dict(dicts)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "[HumanMessage(content='hi!', additional_kwargs={}),\n", " AIMessage(content='whats up?', additional_kwargs={})]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "new_messages" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面是关于在Agent中添加Memory的案例说明:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Add Memory to an Agent\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "为了向Agent中添加Memory,我们将执行以下步骤:\n", "\n", "- 1.我们将创建一个带内存的 LLMChain。\n", "\n", "- 2.我们将使用该 LLMChain 创建自定义代理。\n", "\n", "我们将创建一个简单的自定义代理,它可以访问搜索工具并使用该类ConversationBufferMemory。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import ZeroShotAgent, Tool, AgentExecutor\n", "from langchain.memory import ConversationBufferMemory\n", "from langchain import OpenAI, LLMChain\n", "from langchain.utilities import GoogleSearchAPIWrapper\n", "\n", "search = GoogleSearchAPIWrapper()\n", "tools = [\n", " Tool(\n", " name = \"Search\",\n", " func=search.run,\n", " description=\"useful for when you need to answer questions about current events\"\n", " )\n", "]\n", "\n", "#chat_history请注意PromptTemplate 中变量的用法,它与 ConversationBufferMemory 中的动态键名相匹配。\n", "\n", "prefix = \"\"\"Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:\"\"\"\n", "suffix = \"\"\"Begin!\"\n", "\n", "{chat_history}\n", "Question: {input}\n", "{agent_scratchpad}\"\"\"\n", "\n", "prompt = ZeroShotAgent.create_prompt(\n", " tools, \n", " prefix=prefix, \n", " suffix=suffix, \n", " input_variables=[\"input\", \"chat_history\", \"agent_scratchpad\"]\n", ")\n", "memory = ConversationBufferMemory(memory_key=\"chat_history\")\n", "\n", "#我们现在可以使用 Memory 对象构造 LLMChain,然后创建代理。\n", "llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)\n", "agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)\n", "agent_chain = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True, memory=memory)\n", "\n", "agent_chain.run(input=\"How many people live in canada?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "为了测试此代理的记忆力,我们可以提出一个后续问题,该问题依赖于先前交流中的信息才能正确回答。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_chain.run(input=\"what is their national anthem called?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们将其与没有memory的agent进行比较" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prefix = \"\"\"Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:\"\"\"\n", "suffix = \"\"\"Begin!\"\n", "\n", "Question: {input}\n", "{agent_scratchpad}\"\"\"\n", "\n", "prompt = ZeroShotAgent.create_prompt(\n", " tools, \n", " prefix=prefix, \n", " suffix=suffix, \n", " input_variables=[\"input\", \"agent_scratchpad\"]\n", ")\n", "llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt)\n", "agent = ZeroShotAgent(llm_chain=llm_chain, tools=tools, verbose=True)\n", "agent_without_memory = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)\n", "agent_without_memory.run(\"How many people live in canada?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_without_memory.run(\"what is their national anthem called?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "当然上述操作示例是方便读者快速了解和上手,为了在开发中更加熟练地应用,还是需要全面完善的浏览和查阅官方教程做进一步的融会贯通,点击此处可以直达[Memory教程位置](https://python.langchain.com/en/latest/modules/memory.html)。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Chains\n", "当实现一些简单的应用时,只用一个大语言模型是非常可行的。但是,一些复杂情况下,需要我们去组合不同的大语言模型或者组合大语言模型和其他模块,去完成一些庞大而又复杂的工作内容。LangChain为Chains提供了一个标准接口,以及一些常用的实现方法。\n", "例如,简单的方式我们已经了解到——我们可以创建一个chain,接收用户输入,然后使用Prompt模块格式化,然后将格式化内容传给LLM;复杂的方式诸如组合多个chain,我们可以将多个chain组合在一起,也可以在chain中加入其他模块协同工作。\n", "这部分教程有如下内容:\n", "- 1.使用简单的LLM链\n", "- 2.创建序列化的链接\n", "- 3.创建自定义的链\n", "\n", "如果你想了解更多,可以点击[这里](https://python.langchain.com/en/latest/modules/chains.html)直达Chains官方教程。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [使用LLMChain完成基本调用](#llmchain-usage)\n", "- [SequentialChain组合多个Chain](#using-sequentialchain-to-combine-with-multiple-chains)\n", "- [自定义Chain](#customize-the-chain-class)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### LLMChain usage\n", "\n", "LLMChain,它是一个最简单、使用最多的chain,它会接收一个prompt模板,我们使用这个模板格式化输入信息,然后返回用户的查询得到的响应,也就是我们想要的答案。下面是使用例子:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.prompts import PromptTemplate\n", "from langchain.llms import OpenAI\n", "#使用OpenAI的大模型,默认是text-davinci-003,设置随机性为0.9\n", "llm = OpenAI(temperature=0.9)\n", "#提示模版格式化变量内容\n", "prompt = PromptTemplate(\n", " input_variables=[\"product\"],\n", " template=\"What is a good name for a company that makes {product}?\",\n", ")" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "Brightly Socks!\n" ] } ], "source": [ "from langchain.chains import LLMChain\n", "#实例化chain对象\n", "chain = LLMChain(llm=llm, prompt=prompt)\n", "\n", "#用chain的run方法来运行指定输入变量的链 \n", "print(chain.run(\"colorful socks\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "在LLMChain中使用chat model去完成聊天机器人的交互过程,以下是一个示例:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RainbowSocks\n" ] } ], "source": [ "from langchain.chat_models import ChatOpenAI\n", "from langchain.prompts.chat import (\n", " ChatPromptTemplate,\n", " HumanMessagePromptTemplate,\n", ")\n", "human_message_prompt = HumanMessagePromptTemplate(\n", " prompt=PromptTemplate(\n", " template=\"What is a good name for a company that makes {product}?\",\n", " input_variables=[\"product\"],\n", " )\n", " )\n", "chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])\n", "chat = ChatOpenAI(temperature=0.9)\n", "chain = LLMChain(llm=chat, prompt=chat_prompt_template)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Rainbow Socks Co.\n" ] } ], "source": [ "print(chain.run(\"colorful socks\"))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Using SequentialChain to combine with multiple chains\n", "\n", "顺序链可以组合多个chain,SequentialChain参数输入chain列表,它会顺序执行每一个chain,将第一个chain的返回值输入到第二chain,依次类推。下面是使用范例" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.chat_models import ChatOpenAI\n", "from langchain.prompts.chat import (\n", " ChatPromptTemplate,\n", " HumanMessagePromptTemplate,\n", ")\n", "human_message_prompt = HumanMessagePromptTemplate(\n", " prompt=PromptTemplate(\n", " template=\"What is a good name for a company that makes {product}?\",\n", " input_variables=[\"product\"],\n", " )\n", " )\n", "#定义第二个prompt,然后使用llmchain实例化这个对象\n", "second_prompt = PromptTemplate(\n", " input_variables=[\"company_name\"],\n", " template=\"Write a catchphrase for the following company: {company_name}\",\n", ")\n", "chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])\n", "chat = ChatOpenAI(temperature=0.9)\n", "chain_one = LLMChain(llm=chat, prompt=chat_prompt_template)\n", "chain_two = LLMChain(llm=llm, prompt=second_prompt)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "下面将两个简单的LLMChains组合到一起的方式,使用SimpleSequentialChain来完成,最终实现先给公司命名,然后给这个已经命名的公司起一个宣传语的这么一个过程。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new SimpleSequentialChain chain...\u001b[0m\n", "\u001b[36;1m\u001b[1;3mRainbow Sock Co.\u001b[0m\n", "\u001b[33;1m\u001b[1;3m\n", "\n", "\"Walk on the wild side with Rainbow Socks!\"\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "\n", "\n", "\"Walk on the wild side with Rainbow Socks!\"\n" ] } ], "source": [ "from langchain.chains import SimpleSequentialChain\n", "overall_chain = SimpleSequentialChain(chains=[chain, chain_two], verbose=True)\n", "#运行chain的run方法,只需要指定第一个链的输入变量。\n", "catchphrase = overall_chain.run(\"colorful socks\")\n", "print(catchphrase)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Customize the Chain class\n", "使用已经封装好的LangChain固然没有任何问题,因为其提供了很多开箱即用的chains,但是往往有时候用户可能想自己创建个自定义的类用于特殊用途。\n", "创建自定义类过程如下:\n", "- 1.继承Chain类\n", "- 2.填写input_keys 和 output_keys 属性\n", "- 3.实现私有方法_call方法,用于展示如何执行chain\n", "\n", "下面是自定义创建chain类的方法" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "首先自定义一个ConcatenateChain类,该类将两个LLMChain同时处理一个查询并返回连接结果。" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.chains import LLMChain\n", "from langchain.chains.base import Chain\n", "from typing import Dict, List\n", "\"\"\"\n", "这段代码定义了一个名为ConcatenateChain的类,继承自Chain。该类表示一个将两个链连接在一起的链。\n", "首先从langchain.chains模块中导入LLMChain和Chain类,以及从typing模块中导入Dict和List类型注解。\n", "在ConcatenateChain类中,有两个属性:chain_1和chain_2,分别表示要连接的两个链。这两个属性都是LLMChain类型的实例。\n", "该类还定义了两个方法:input_keys()和output_keys()。其中,input_keys()方法返回连接后输入变量的集合,即两个原始链\n", "的输入变量的并集;而output_keys()方法返回一个字符串列表,表示连接后的输出变量只有一个,名称为concat_output。\n", "最后,该类实现了一个私有方法_call(),用于实际执行连接操作。该方法接受一个字典类型的参数inputs,表示输入变量及其取值。\n", "该方法先调用两个链的run()方法,分别获取它们的输出结果,然后将它们相加得到新的输出结果,并将其存储在一个字典中返回。\n", "\"\"\"\n", "\n", "class ConcatenateChain(Chain):\n", " chain_1: LLMChain\n", " chain_2: LLMChain\n", "\n", " @property\n", " def input_keys(self) -> List[str]:\n", " # 两个链的输入键的并集\n", " all_input_vars = set(self.chain_1.input_keys).union(set(self.chain_2.input_keys))\n", " return list(all_input_vars)\n", "\n", " @property\n", " def output_keys(self) -> List[str]:\n", " return ['concat_output']\n", "\n", " def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:\n", " output_1 = self.chain_1.run(inputs)\n", " output_2 = self.chain_2.run(inputs)\n", " return {'concat_output': output_1 + output_2}" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Concatenated output:\n", "\n", "\n", "Vivid Sockery.\n", "\n", "\"Step Into Colorful Comfort!\"\n" ] } ], "source": [ "\"\"\"\n", " prompt_1: PromptTemplate类型,表示一个提示模板,其中包含输入变量\"product\",\n", "模板为\"What is a good name for a company that makes {product}?\"。\n", " chain_1: LLMChain类型,表示一个LLMChain实例,其中llm参数设置为之前定义的llm对象,prompt参数设置为prompt_1。\n", " chain_2: LLMChain类型,表示一个LLMChain实例,其中llm参数设置为之前定义的llm对象,prompt参数设置为prompt_2。\n", " concat_chain: ConcatenateChain类型,表示一个连接两个链的对象。其中,chain_1和chain_2属性分别对应上面定义的两个链实例。\n", " concat_output: 字符串类型,表示调用concat_chain.run()方法后得到的结果。该结果是将chain_1和chain_2输出的结果进行连接\n", "得到的。最后通过打印输出的方式展示连接结果。\n", "\"\"\"\n", "prompt_1 = PromptTemplate(\n", " input_variables=[\"product\"],\n", " template=\"What is a good name for a company that makes {product}?\",\n", ")\n", "chain_1 = LLMChain(llm=llm, prompt=prompt_1)\n", "\n", "prompt_2 = PromptTemplate(\n", " input_variables=[\"product\"],\n", " template=\"What is a good slogan for a company that makes {product}?\",\n", ")\n", "chain_2 = LLMChain(llm=llm, prompt=prompt_2)\n", "\n", "concat_chain = ConcatenateChain(chain_1=chain_1, chain_2=chain_2)\n", "concat_output = concat_chain.run(\"colorful socks\")\n", "print(f\"Concatenated output:\\n{concat_output}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "## Agents\n", "实际应用可能不仅需要预定义好的chain,也需要根据用户的输入请求,生成一个隐含的chain。agent作为代理,会根据用户输入,确定下来要采取的操作、使用的工具、LLM的输出、observation观察得出的结果或是将LLM结果返回给用户。\n", "在使用agents前,下面几个概念需要理解:\n", "\n", "- Tools:一个实现具体功能的函数;可以是谷歌搜索、数据库查找、python交互界面。tool的接口是一个接受string,返回string的函数\n", "- LLM:驱动Agent运行的大语言模型\n", "- Agent:使用的Agent\n", "\n", "下面是三者之间的联系:\n", "\n", "\n", "\n", "LangChain 将基于用户提出的要求驱动agent进行处理,期间调用大模型来完成响应请求,该请求可进一步驱动tools去根据特定任务进行特定操作,尔后会把tools具体的操作完成返回给用户,在这一过程中如果用户无需调用tools完成处理将会直接得到大模型的反馈。\n", "\n", "更加详细的内容点击👉[这里](https://python.langchain.com/en/latest/modules/agents.html)👈跳转到Agents官方教程" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [使用Agent的简单示例](#a-simple-example-with-using-agent)\n", "- [Tools](#tools)\n", "- [Agent](#agent)\n", "- [Toolkits](#toolkits)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### A simple example with using Agent" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.agents import load_tools\n", "from langchain.agents import initialize_agent\n", "from langchain.agents import AgentType\n", "from langchain.llms import OpenAI\n", "\"\"\"\n", "llm是创建一个OpenAI的LLM模型,温度参数设置为0。\n", "tools 是从指定路径加载工具库,包括\"serpapi\"和\"llm-math\"两个工具,并将加载的工具与LLM模型绑定。\n", "agent 是初始化代理,选择指定类型,并使用加载的工具和LLM模型对其进行训练。同时,在训练过程中打印详细输出信息。\n", "\"\"\"\n", "llm = OpenAI(temperature=0)\n", "tools = load_tools([\"serpapi\", \"llm-math\"], llm=llm)\n", "agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m I need to find out who Leo DiCaprio's girlfriend is and then calculate her age raised to the 0.43 power.\n", "Action: Search\n", "Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mNina Agdal: 2016 to 2017 ... Leo and Nina were together for almost exactly a year until a source confirmed their breakup with a very familiar ...\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I need to find out Nina Agdal's age\n", "Action: Search\n", "Action Input: \"Nina Agdal age\"\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m31 years\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I need to calculate 31 raised to the 0.43 power\n", "Action: Calculator\n", "Action Input: 31^0.43\u001b[0m\n", "Observation: \u001b[33;1m\u001b[1;3mAnswer: 4.378098500976803\n", "\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: Nina Agdal is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 4.378098500976803.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "\"Nina Agdal is Leo DiCaprio's girlfriend and her current age raised to the 0.43 power is 4.378098500976803.\"" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.run(\"Who is Leo DiCaprio's girlfriend? What is her current age raised to the 0.43 power?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Tools\n", "工具是智能体和外部环境交互的方式。工具可以是实用程序、chain、其他agent等。\n", "\n", "LangChain大部分工具和搜索相关,下面仅举几个有特点的工具例子。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [Bing Search](#bing-search)\n", "- [Google Search](#google-search)\n", "- [Google Serper API](#google-serper-api)\n", "- [Python REPL](#python-repl)\n", "- [Bash](#bash)\n", "- [Wikipedia API](#wikipedia-api)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "一般通过下面的方式加载工具,对于当做工具使用的chain、agent,需要进行初始化" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import load_tools\n", "tool_names = [...]\n", "tools = load_tools(tool_names)\n", "llm = ...\n", "tools = load_tools(tool_names, llm=llm)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Bing Search" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面示例展示了如何使用必应搜索组件:\n", "\n", "首先,您需要设置适当的 API 密钥和环境变量。点击[此处](https://levelup.gitconnected.com/api-tutorial-how-to-use-bing-web-search-api-in-python-4165d5592a7e)查阅说明并完成配置。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.environ[\"BING_SUBSCRIPTION_KEY\"] = \"\"\n", "os.environ[\"BING_SEARCH_URL\"] = \"\"\n", "\n", "#导入BingSearchAPIWrapper类,该类用于与Bing搜索引擎进行交互。\n", "from langchain.utilities import BingSearchAPIWrapper\n", "#创建一个BingSearchAPIWrapper对象,并将其赋值给变量search。\n", "search = BingSearchAPIWrapper()\n", "#调用search对象的run()方法,传入参数\"python\",表示在Bing搜索引擎上搜索关于Python的信息。\n", "search.run(\"python\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#设置k控制输出结果数目\n", "search = BingSearchAPIWrapper(k=1)\n", "search.run(\"python\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "运行下面的代码将会返回三项内容:片段,标题和链接\n", "\n", "片段: 结果的描述.\n", "\n", "标题: 结果的标题.\n", "\n", "链接: 结果的链接." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "search = BingSearchAPIWrapper()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "search.results(\"apples\", 5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Google Search" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "以下示例介绍了如何使用谷歌搜索组件,您需要设置适当的 API 密钥和环境变量。要进行设置,请在[此处](https://console.cloud.google.com/apis/credentials)创建 GOOGLE_API_KEY,[这里](https://programmablesearchengine.google.com/)创建 GOOGLE_CSE_ID" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.environ[\"GOOGLE_CSE_ID\"] = \"\"\n", "os.environ[\"GOOGLE_API_KEY\"] = \"\"\n", "#导入GoogleSearchAPIWrapper类,该类用于与Google搜索引擎进行交互。\n", "from langchain.utilities import GoogleSearchAPIWrapper\n", "#创建一个GoogleSearchAPIWrapper对象,并将其赋值给变量search。\n", "search = GoogleSearchAPIWrapper()\n", "#调用search对象的run()方法,传入参数\"Obama's first name?\",表示在Google搜索引擎上搜索关于\"Obama的名\"的信息。\n", "search.run(\"Obama's first name?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "首先创建一个GoogleSearchAPIWrapper对象search,并传入参数k=1,以便在搜索结果中只返回前一条结果。\n", "然后调用search对象的run()方法,传入参数\"python\",以在Google搜索引擎上搜索关于Python的信息。\n", "接着再次创建一个GoogleSearchAPIWrapper对象search,并传入空值,以便清空之前搜索的结果。\n", "最后调用search对象的results()方法,传入参数\"apples\"和5,以在Google搜索引擎上搜索关于苹果的信息,并返回前5个结果。\n", "\"\"\"\n", "search = GoogleSearchAPIWrapper(k=1)\n", "search.run(\"python\")\n", "search = GoogleSearchAPIWrapper()\n", "search.results(\"apples\", 5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Google Serper API" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "为了更好地使用谷歌网络搜索API,需要注册一个免费账户用于获取API_KEY,注册位置点击[此处](https://serper.dev/)。下面是示例代码" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.environ[\"SERPER_API_KEY\"] = \"\"\n", "\n", "from langchain.utilities import GoogleSerperAPIWrapper\n", "search = GoogleSerperAPIWrapper()\n", "search.run(\"Obama's first name?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "os.environ['OPENAI_API_KEY'] = \"YOUR_OPENAI_KEY\"\n", "from langchain.utilities import GoogleSerperAPIWrapper\n", "from langchain.llms.openai import OpenAI\n", "from langchain.agents import initialize_agent, Tool\n", "from langchain.agents import AgentType\n", "\n", "\"\"\"\n", "首先创建一个OpenAI的LLM模型,温度参数设置为0。\n", "然后创建一个GoogleSerperAPIWrapper对象search,用于在Google搜索引擎上进行搜索。\n", "接着定义一个包含一个工具的列表tools,其中工具名称为\"Intermediate Answer\",其功能\n", "为调用search对象的run()方法进行搜索,并将搜索结果作为答案返回。\n", "接下来初始化一个agent,也就是self_ask_with_search,该agent使用tools列表中的工具与LLM模型\n", "交互,并支持使用\"self ask with search\"方式进行提问。\n", "最后调用self_ask_with_search对象的run()方法,传入问题,以获取相应的答案。\n", "\"\"\"\n", "llm = OpenAI(temperature=0)\n", "search = GoogleSerperAPIWrapper()\n", "tools = [\n", " Tool(\n", " name=\"Intermediate Answer\",\n", " func=search.run,\n", " description=\"useful for when you need to ask with search\"\n", " )\n", "]\n", "\n", "self_ask_with_search = initialize_agent(tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True)\n", "self_ask_with_search.run(\"What is the hometown of the reigning men's U.S. Open champion?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "#### Python REPL" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "'27\\n'" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\"\"\"\n", "首先导入PythonREPL类,该类用于在Python解释器中执行交互式代码。\n", "接着创建一个PythonREPL对象python_repl,以便在Python解释器中执行代码。\n", "最后调用python_repl对象的run()方法,传入一条简单的Python语句\"print(3**3)\",以打印出数字27的值。\n", "\"\"\"\n", "from langchain.utilities import PythonREPL\n", "python_repl = PythonREPL()\n", "python_repl.run(\"print(3**3)\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "#### Bash" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\"My name is name\" \r\n", "\n" ] } ], "source": [ "\"\"\"\n", "首先导入BashProcess类,该类用于在Linux系统中执行命令行操作。\n", "接着创建一个BashProcess对象bash,以便在Linux系统中执行命令行操作。\n", "最后调用bash对象的run()方法,传入一条简单的命令\"echo 'My name is \n", "name'\",以在终端上打印出字符串\"My name is name\"。\n", "\"\"\"\n", "from langchain.utilities import BashProcess\n", "bash = BashProcess()\n", "print(bash.run(' echo \"My name is name\" '))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Wikipedia API" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面是如何使用维基百科的示例:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: wikipedia in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (1.4.0)\n", "Requirement already satisfied: requests<3.0.0,>=2.0.0 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from wikipedia) (2.28.1)\n", "Requirement already satisfied: beautifulsoup4 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from wikipedia) (4.12.0)\n", "Requirement already satisfied: idna<4,>=2.5 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from requests<3.0.0,>=2.0.0->wikipedia) (3.4)\n", "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from requests<3.0.0,>=2.0.0->wikipedia) (1.26.13)\n", "Requirement already satisfied: certifi>=2017.4.17 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from requests<3.0.0,>=2.0.0->wikipedia) (2022.12.7)\n", "Requirement already satisfied: charset-normalizer<3,>=2 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from requests<3.0.0,>=2.0.0->wikipedia) (2.1.1)\n", "Requirement already satisfied: soupsieve>1.2 in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (from beautifulsoup4->wikipedia) (2.4)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "%pip install wikipedia" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from langchain.utilities import WikipediaAPIWrapper" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "wikipedia = WikipediaAPIWrapper()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Page: Hunter × Hunter\\nSummary: Hunter × Hunter (stylized as HUNTER×HUNTER and pronounced \"hunter hunter\") is a Japanese manga series written and illustrated by Yoshihiro Togashi. It has been serialized in Shueisha\\'s shōnen manga magazine Weekly Shōnen Jump since March 1998, although the manga has frequently gone on extended hiatuses since 2006. Its chapters have been collected in 37 tankōbon volumes as of November 2022. The story focuses on a young boy named Gon Freecss who discovers that his father, who left him at a young age, is actually a world-renowned Hunter, a licensed professional who specializes in fantastical pursuits such as locating rare or unidentified animal species, treasure hunting, surveying unexplored enclaves, or hunting down lawless individuals. Gon departs on a journey to become a Hunter and eventually find his father. Along the way, Gon meets various other Hunters and encounters the paranormal.\\nHunter × Hunter was adapted into a 62-episode anime television series produced by Nippon Animation and directed by Kazuhiro Furuhashi, which ran on Fuji Television from October 1999 to March 2001. Three separate original video animations (OVAs) totaling 30 episodes were subsequently produced by Nippon Animation and released in Japan from 2002 to 2004. A second anime television series by Madhouse aired on Nippon Television from October 2011 to September 2014, totaling 148 episodes, with two animated theatrical films released in 2013. There are also numerous audio albums, video games, musicals, and other media based on Hunter × Hunter.\\nThe manga has been translated into English and released in North America by Viz Media since April 2005. Both television series have been also licensed by Viz Media, with the first series having aired on the Funimation Channel in 2009 and the second series broadcast on Adult Swim\\'s Toonami programming block from April 2016 to June 2019.\\nHunter × Hunter has been a huge critical and financial success and has become one of the best-selling manga series of all time, having over 84 million copies in circulation by July 2022.\\n\\nPage: Hunter × Hunter (2011 TV series)\\nSummary: Hunter × Hunter is an anime television series that aired from 2011 to 2014 based on Yoshihiro Togashi\\'s manga series Hunter × Hunter. The story begins with a young boy named Gon Freecss, who one day discovers that the father who he thought was dead, is in fact alive and well. He learns that his father, Ging, is a legendary \"Hunter\", an individual who has proven themselves an elite member of humanity. Despite the fact that Ging left his son with his relatives in order to pursue his own dreams, Gon becomes determined to follow in his father\\'s footsteps, pass the rigorous \"Hunter Examination\", and eventually find his father to become a Hunter in his own right.\\nThis new Hunter × Hunter anime was announced on July 24, 2011. It is a complete reboot of the anime adaptation starting from the beginning of the manga, with no connections to the first anime from 1999. Produced by Nippon TV, VAP, Shueisha and Madhouse, the series is directed by Hiroshi Kōjina, with Atsushi Maekawa and Tsutomu Kamishiro handling series composition, Takahiro Yoshimatsu designing the characters and Yoshihisa Hirano composing the music. Instead of having the old cast reprise their roles for the new adaptation, the series features an entirely new cast to voice the characters. The new series premiered airing weekly on Nippon TV and the nationwide Nippon News Network from October 2, 2011. The series started to be collected in both DVD and Blu-ray format on January 25, 2012. Viz Media has licensed the anime for a DVD/Blu-ray release in North America with an English dub. On television, the series began airing on Adult Swim\\'s Toonami programming block on April 17, 2016, and ended on June 23, 2019.The anime series\\' opening theme is alternated between the song \"Departure!\" and an alternate version titled \"Departure! -Second Version-\" both sung by Galneryus\\' vocalist Masatoshi Ono. Five pieces of music were used as the ending theme; \"Just Awake\" by the Japanese band Fear, and Loathing in Las Vegas in episodes 1 to 26, \"Hunting for Your Dream\" by Galneryus in episodes 27 to 58, \"Reason\" sung by Japanese duo Yuzu in episodes 59 to 75, \"Nagareboshi Kirari\" also sung by Yuzu from episode 76 to 98, which was originally from the anime film adaptation, Hunter × Hunter: Phantom Rouge, and \"Hyōri Ittai\" by Yuzu featuring Hyadain from episode 99 to 146, which was also used in the film Hunter × Hunter: The Last Mission. The background music and soundtrack for the series was composed by Yoshihisa Hirano.\\n\\n\\n\\nPage: List of Hunter × Hunter characters\\nSummary: The Hunter × Hunter manga series, created by Yoshihiro Togashi, features an extensive cast of characters. It takes place in a fictional universe where licensed specialists known as Hunters travel the world taking on special jobs ranging from treasure hunting to assassination. The story initially focuses on Gon Freecss and his quest to become a Hunter in order to find his father, Ging, who is himself a famous Hunter. On the way, Gon meets and becomes close friends with Killua Zoldyck, Kurapika and Leorio Paradinight.\\nAlthough most characters are human, most possess superhuman strength and/or supernatural abilities due to Nen, the ability to control one\\'s own life energy or aura. The world of the series also includes fantastical beasts such as the Chimera Ants or the Five great calamities.'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "wikipedia.run('HUNTER X HUNTER')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Agent" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "我们接着看与agent相关的内容,Agent使用 LLM 来确定采取哪些行动以及采取何种顺序。action可以是使用tools并观察其输出,也可以是向用户返回响应。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [类型](#type)\n", "- [自定义Agent](#custom-agent)\n", "- [自定义大模型Agent](#custom-llm-agent)\n", "- [Self Ask With Search](#self-ask-with-search)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Type" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "以下是LangChain中可用的Agent类型:\n", "\n", "使用到的是ReAct框架\n", "\n", "**zero-shot-react-description**: 仅根据工具的描述来确定要使用的工具。可以提供任意数量的工具。此Agent要求为每个工具提供描述。\n", "\n", "**react-docstore**: 这个Agent使用 ReAct 框架与文档库进行交互。必须提供两个工具:一个搜索工具和一个查找工具(它们的名称必须完全一样)。搜索工具应搜索文档,而查找工具应在最近找到的文档中查找术语。这个代理等同于原始的 ReAct 论文,特别是维基百科的例子。\n", "\n", "**self-ask-with-search**: 该Agent使用一个工具,该工具应命名为 Intermediate Answer。该工具应该能够查找问题的事实答案。这个代理相当于原来的 self ask with search paper,其中提供了一个 Google 搜索 API 作为工具。\n", "\n", "**conversational-react-description**: 该Agent旨在用于会话设置。这部分提示的设计旨在使agent可以提供到帮助以及便于开展对话。它使用 ReAct 框架来决定使用哪个工具,并使用内存来记住之前的对话交互。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Custom Agent\n", "\n", "如何创建自定义的Agent" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import Tool,AgentExecutor\n", "from langchain.agents import BaseSingleActionAgent\n", "from langchain import OpenAI, SerpAPIWrapper\n", "from typing import List, Tuple, Any, Union\n", "from langchain.schema import AgentAction, AgentFinish\n", "\"\"\"\n", "创建了一个名为 search 的 SerpAPIWrapper 对象。然后,定义了一个名为 tools 的列表,\n", "其中包含了一个名为 \"Search\" 的 Tool 对象。这个 Tool 对象可以被调用,其功能是搜索相关信息。\n", "接着,定义了一个名为 FakeAgent 的类,继承自 BaseSingleActionAgent。这个类的作用是模拟一\n", "个假的智能体,它有一个输入键(input_keys)属性,用于接收用户输入。在 plan() 方法中,根据当前\n", "状态和用户输入决定要采取什么行动,返回一个 AgentAction 或 AgentFinish 对象。最后,创建了\n", "一个名为 agent 的 FakeAgent 对象,并通过 AgentExecutor.from_agent_and_tools() 方法\n", "创建了一个 AgentExecutor 对象。然后调用了 run() 方法,传入了一个查询语句 \"How many people\n", " live in canada as of 2023?\",该查询将由智能体执行。\n", "\"\"\"\n", "search = SerpAPIWrapper()\n", "tools = [\n", " Tool(\n", " name = \"Search\",\n", " func=search.run,\n", " description=\"useful for when you need to answer questions about current events\",\n", " return_direct=True\n", " )\n", "]\n", "class FakeAgent(BaseSingleActionAgent):\n", " @property\n", " def input_keys(self):\n", " return [\"input\"]\n", " \n", " def plan(\n", " self, intermediate_steps: List[Tuple[AgentAction, str]], **kwargs: Any\n", " ) -> Union[AgentAction, AgentFinish]:\n", " return AgentAction(tool=\"Search\", tool_input=kwargs[\"input\"], log=\"\")\n", "\n", " async def aplan(\n", " self, intermediate_steps: List[Tuple[AgentAction, str]], **kwargs: Any\n", " ) -> Union[AgentAction, AgentFinish]:\n", " return AgentAction(tool=\"Search\", tool_input=kwargs[\"input\"], log=\"\")\n", "\n", "agent = FakeAgent()\n", "agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)\n", "agent_executor.run(\"How many people live in canada as of 2023?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Custom LLM Agent" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "LLM代理由几部分组成:\n", "\n", "1. PromptTemplate:这是提示模板,可用于指示语言模型做什么\n", "\n", "2. LLM:这是为代理提供支持的语言模型\n", "\n", "3. StopSequence:指示LLM一旦找到这个字符串就停止生成\n", "\n", "4. OutputParser:这决定了如何将 LLMOutput 解析为 AgentAction 或 AgentFinish 对象\n", "\n", "LLMAgent 在 AgentExecutor 中使用。这个 AgentExecutor 在很大程度上可以被认为是一个循环:\n", "1. 将用户输入和任何先前的步骤传递给代理(在本例中为 LLMAgent)\n", "\n", "2. 如果代理返回一个AgentFinish,则直接将其返回给用户\n", "\n", "3. 如果 Agent 返回一个AgentAction,则使用它来调用一个工具并获得一个Observation\n", "\n", "4. 重复,将AgentAction和传递Observation回代理,直到AgentFinish发出 。\n", "\n", "AgentActionaction是由和组成的响应action_input。action指的是使用哪个工具,并action_input指的是该工具的输入。log也可以作为更多上下文提供(可用于日志记录、跟踪等)。\n", "\n", "AgentFinish是包含要发送回用户的最终消息的响应。这应该用于结束代理运行。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n", "from langchain.prompts import StringPromptTemplate\n", "from langchain import OpenAI, SerpAPIWrapper, LLMChain\n", "from typing import List, Union\n", "from langchain.schema import AgentAction, AgentFinish\n", "import re\n", "\"\"\"定义了一个名为 search 的搜索引擎对象,并将其封装成一个 Tool 对象添加到\n", "tools 列表中,以便在后续的任务执行过程中使用。\n", "\"\"\"\n", "search = SerpAPIWrapper()\n", "tools = [\n", " Tool(\n", " name = \"Search\",\n", " func=search.run,\n", " description=\"useful for when you need to answer questions about current events\"\n", " )\n", "]" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "这部分指示代理做什么。一般来说,模板应包括:\n", "\n", "- tools:agent可以选择访问哪些工具以及调用它们的方式和时间。\n", "\n", "- intermediate_steps:这些是先前 ( AgentAction, Observation) 对应的元组对儿。这些一般不会直接传递给模型,而是提示模板以特定的方式对它们进行格式化处理之后再发送给llm。\n", "\n", "- input: 一般用户的输入内容" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Answer the following questions as best you can, but speaking as a pirate might speak. You have access to the following tools:\\n\\n{tools}\\n\\nUse the following format:\\n\\nQuestion: the input question you must answer\\nThought: you should always think about what to do\\nAction: the action to take, should be one of [{tool_names}]\\nAction Input: the input to the action\\nObservation: the result of the action\\n... (this Thought/Action/Action Input/Observation can repeat N times)\\nThought: I now know the final answer\\nFinal Answer: the final answer to the original input question\\n\\nBegin! Remember to speak as a pirate when giving your final answer. Use lots of \"Arg\"s\\n\\nQuestion: {input}\\n{agent_scratchpad}'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "template = \"\"\"Answer the following questions as best you can, but speaking as a pirate might speak. You have access to the following tools:\n", "\n", "{tools}\n", "\n", "Use the following format:\n", "\n", "Question: the input question you must answer\n", "Thought: you should always think about what to do\n", "Action: the action to take, should be one of [{tool_names}]\n", "Action Input: the input to the action\n", "Observation: the result of the action\n", "... (this Thought/Action/Action Input/Observation can repeat N times)\n", "Thought: I now know the final answer\n", "Final Answer: the final answer to the original input question\n", "\n", "Begin! Remember to speak as a pirate when giving your final answer. Use lots of \"Arg\"s\n", "\n", "Question: {input}\n", "{agent_scratchpad}\"\"\"\n", "template" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为 CustomPromptTemplate 的类,继承自 StringPromptTemplate。\n", " template 是一个字符串类型的属性,表示提示信息的模板;\n", " tools 是一个列表类型的属性,表示可用的工具列表;\n", " format 是一个方法,用于将传入的参数格式化成提示信息。在 format 方法中,首先从传入的参数中弹出一个名为 intermediate_steps 的关键字\n", "参数。然后,遍历这个中间步骤列表,将每个步骤的操作日志和观察结果拼接到一个字符串 thoughts 中。接着,将 thoughts 存入 agent_scratchpad \n", "中,并将可用的工具信息添加到tools 和 tool_names 中。最后,调用父类的 format 方法,将格式化后的提示信息返回。\n", "\"\"\"\n", "class CustomPromptTemplate(StringPromptTemplate):\n", " template: str\n", " tools: List[Tool]\n", " def format(self, **kwargs) -> str:\n", " intermediate_steps = kwargs.pop(\"intermediate_steps\")\n", " thoughts = \"\"\n", " for action, observation in intermediate_steps:\n", " thoughts += action.log\n", " thoughts += f\"\\nObservation: {observation}\\nThought: \"\n", " kwargs[\"agent_scratchpad\"] = thoughts\n", " kwargs[\"tools\"] = \"\\n\".join([f\"{tool.name}: {tool.description}\" for tool in self.tools])\n", " kwargs[\"tool_names\"] = \", \".join([tool.name for tool in self.tools])\n", " return self.template.format(**kwargs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为 prompt 的变量,类型为 CustomPromptTemplate。该变量通过调用父类 StringPromptTemplate 的构造函数\n", "进行初始化,传入了三个参数:template、tools 和 input_variables。其中,template 是一个字符串类型的参数,表示提示信息的模板;\n", "tools 是一个列表类型的参数,表示可用的工具列表;input_variables 是一个列表类型的参数,表示输入变量的名称列表。在本例中,输入变\n", "量的名称为 input 和 intermediate_steps。\n", "\"\"\"\n", "prompt = CustomPromptTemplate(\n", " template=template,\n", " tools=tools,\n", " input_variables=[\"input\", \"intermediate_steps\"]\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "OutputParser负责将 LLM 的输出解析为AgentAction和AgentFinish。这通常在很大程度上取决于所使用的提示。\n", "\n", "这时候您可以更改解析以进行重试、处理空白等的地方" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "定义了一个名为 output_parser 的变量,类型为 CustomOutputParser。该变量通过调用父类 \n", "AgentOutputParser 的构造函数进行初始化。\n", "在 CustomOutputParser 类中,定义了一个名为 parse 的方法,用于解析 LLM 输出。该方法接受一个字符串\n", "类型的参数 llm_output,返回值为 AgentAction 或 AgentFinish 类型的对象。\n", "在 parse 方法中,首先判断输入的 LLM 输出是否包含 \"Final Answer:\" 字符串。如果是,则说明已经完成了任务,返回 \n", "AgentFinish 对象;否则,使用正则表达式从 LLM 输出中提取出动作和输入信息。如果无法提取出动作和输入信息,则抛出异常。\n", "最后,根据提取出的信息创建 AgentAction 对象并返回。\n", "\"\"\"\n", "class CustomOutputParser(AgentOutputParser):\n", " def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:\n", " if \"Final Answer:\" in llm_output:\n", " return AgentFinish(\n", " return_values={\"output\": llm_output.split(\"Final Answer:\")[-1].strip()},\n", " log=llm_output,\n", " )\n", " regex = r\"Action: (.*?)[\\n]*Action Input:[\\s]*(.*)\"\n", " match = re.search(regex, llm_output, re.DOTALL)\n", " if not match:\n", " raise ValueError(f\"Could not parse LLM output: `{llm_output}`\")\n", " action = match.group(1).strip()\n", " action_input = match.group(2)\n", " return AgentAction(tool=action, tool_input=action_input.strip(\" \").strip('\"'), log=llm_output)\n", "\n", "output_parser = CustomOutputParser()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "llm = OpenAI(temperature=0)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "定义StopSequence(停止序列),这很重要,因为它告诉 LLM 何时停止生成。\n", "\n", "这在很大程度上取决于您使用的提示和模型。通常,您希望这是您在提示中使用的任何标记来表示一个开始Observation(否则,LLM 可能会为您产生虚拟的Observation)。\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "llm_chain = LLMChain(llm=llm, prompt=prompt)\n", "#使用列表推导式从 tools 列表中提取出每个工具的名称,并将这些名称存储到 tool_names 列表中。\n", "tool_names = [tool.name for tool in tools]\n", "\n", "\"\"\"\n", "传入了如下几个个参数:llm_chain、output_parser、stop和 allowed_tools。\n", "其中,llm_chain 是一个 LLMChain 对象,表示 LLM 链;\n", "output_parser 是一个 CustomOutputParser 对象,表示解析 LLM 输出的类;\n", "allowed_tools 是一个列表,表示可用的工具列表。\n", "\"\"\"\n", "agent = LLMSingleActionAgent(\n", " llm_chain=llm_chain, \n", " output_parser=output_parser,\n", " stop=[\"\\nObservation:\"], \n", " allowed_tools=tool_names\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "定义了一个名为 agent_executor 的变量,类型为 AgentExecutor。\n", "该变量通过调用 AgentExecutor 类的构造函数进行初始化。\n", "在构造函数中,传入了三个参数:agent、tools 和 verbose。\n", "其中,agent 是一个 LLMSingleActionAgent 对象,表示 LLM 代理;\n", "tools 是一个列表,表示可用的工具列表;\n", "verbose 是一个布尔值,表示是否输出详细信息。\n", "接下来,调用 AgentExecutor 类的 from_agent_and_tools 静态方法,将 agent、tools 和 verbose \n", "作为参数传递给它。该方法会返回一个新的 AgentExecutor 对象,用于执行 LLM 任务。\n", "\"\"\"\n", "agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"How many people live in canada as of 2023?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Self Ask With Search" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain import OpenAI, SerpAPIWrapper\n", "from langchain.agents import initialize_agent, Tool\n", "from langchain.agents import AgentType\n", "\"\"\"\n", "这段代码导入了 OpenAI 和 SerpAPIWrapper 模块,以及 initialize_agent、Tool 和 AgentType 类。\n", "然后,定义了一个名为 llm 的 OpenAI 对象,用于执行 LLM 任务。接着,定义了一个名为 search 的 SerpAPIWrapper 对象,用于搜索答案。\n", "接下来,定义了一个名为 tools 的列表,其中包含一个名为 Intermediate Answer 的工具对象。该工具对象具有 func 属性,指定了使用\n", " search.run() 方法来搜索答案。\n", " \"\"\"\n", "llm = OpenAI(temperature=0)\n", "search = SerpAPIWrapper()\n", "tools = [\n", " Tool(\n", " name=\"Intermediate Answer\",\n", " func=search.run,\n", " description=\"useful for when you need to ask with search\"\n", " )\n", "]\n", "#调用 initialize_agent 函数初始化一个代理对象,并将其赋值给 self_ask_with_search 变量。\n", "self_ask_with_search = initialize_agent(tools, llm, agent=AgentType.SELF_ASK_WITH_SEARCH, verbose=True)\n", "self_ask_with_search.run(\"What is the hometown of the reigning men's U.S. Open champion?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "### Toolkits\n", "这部分主要包含一些成了工具的agent" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "- [CSV Agent](#csv-agent)\n", "- [Python Agent](#python-agent)\n", "- [Vectorstore Agent](#vectorstore-agent)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "#### CSV Agent\n", "根据给定的csv文件内容,回复用户问题。" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.agents import create_csv_agent\n", "from langchain.llms import OpenAI\n", "#我们找了一个titanic生还者名单,里面是一些幸存者的信息,你可以上传一个csv文件,并对csv文件进行基本的询问\n", "agent = create_csv_agent(OpenAI(temperature=0), 'titanic.csv', verbose=True)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to count the number of rows\n", "Action: python_repl_ast\n", "Action Input: len(df)\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m891\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: There are 891 rows in the dataframe.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'There are 891 rows in the dataframe.'" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.run(\"how many rows are there?\")" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to count the number of people with more than 3 siblings\n", "Action: python_repl_ast\n", "Action Input: df[df['SibSp'] > 3].shape[0]\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m30\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: 30 people have more than 3 siblings.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'30 people have more than 3 siblings.'" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.run(\"how many people have more than 3 sibligngs\")" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to calculate the average age first\n", "Action: python_repl_ast\n", "Action Input: df['Age'].mean()\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m29.69911764705882\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now need to calculate the square root of this\n", "Action: python_repl_ast\n", "Action Input: math.sqrt(df['Age'].mean())\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mname 'math' is not defined\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I need to import the math library\n", "Action: python_repl_ast\n", "Action Input: import math\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now need to calculate the square root of the average age\n", "Action: python_repl_ast\n", "Action Input: math.sqrt(df['Age'].mean())\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m5.449689683556195\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: 5.449689683556195\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'5.449689683556195'" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent.run(\"whats the square root of the average age?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "#### Python Agent\n", "该代理用于根据用户要求生成或执行一段python代码" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "from langchain.agents.agent_toolkits import create_python_agent\n", "from langchain.tools.python.tool import PythonREPLTool\n", "from langchain.python import PythonREPL\n", "from langchain.llms.openai import OpenAI\n", "\"\"\"\n", "这段代码定义了一个名为 agent_executor 的变量,类型为 AgentExecutor。该变量通过调用 create_python_agent 函数进行初始化。\n", "在构造函数中,传入了三个参数:llm、tool 和 verbose。\n", "其中,llm 是一个 OpenAI 对象,用于执行 LLM 任务;\n", "tool 是一个PythonREPLTool 对象,表示用于交互式解释的工具;\n", "verbose 是一个布尔值,表示是否输出详细信息。\n", "接下来,调用 create_python_agent 函数,将 llm、tool 和 verbose 作为参数传递给它。该函数会返回一个新的 AgentExecutor 对象,\n", "用于执行 LLM 任务并提供交互式解释功能。\n", "\"\"\"\n", "agent_executor = create_python_agent(\n", " llm=OpenAI(temperature=0, max_tokens=1000),\n", " tool=PythonREPLTool(),\n", " verbose=True\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "生成Fibonacci数列" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m I need to calculate the 10th fibonacci number\n", "Action: Python REPL\n", "Action Input: def fibonacci(n):\n", " if n == 0:\n", " return 0\n", " elif n == 1:\n", " return 1\n", " else:\n", " return fibonacci(n-1) + fibonacci(n-2)\n", "\n", "print(fibonacci(10))\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3m55\n", "\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: 55\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'55'" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent_executor.run(\"What is the 10th fibonacci number?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, "source": [ "训练神经网络" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3m I need to write a neural network in PyTorch and train it on the given data.\n", "Action: Python REPL\n", "Action Input: \n", "import torch\n", "\n", "# Define the model\n", "model = torch.nn.Sequential(\n", " torch.nn.Linear(1, 1)\n", ")\n", "\n", "# Define the loss\n", "loss_fn = torch.nn.MSELoss()\n", "\n", "# Define the optimizer\n", "optimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n", "\n", "# Define the data\n", "x_data = torch.tensor([[1.0], [2.0], [3.0], [4.0]])\n", "y_data = torch.tensor([[2.0], [4.0], [6.0], [8.0]])\n", "\n", "# Train the model\n", "for epoch in range(1000):\n", " # Forward pass\n", " y_pred = model(x_data)\n", "\n", " # Compute and print loss\n", " loss = loss_fn(y_pred, y_data)\n", " if (epoch+1) % 100 == 0:\n", " print(f'Epoch {epoch+1}: loss = {loss.item():.4f}')\n", "\n", " # Zero the gradients\n", " optimizer.zero_grad()\n", "\n", " # Backward pass\n", " loss.backward()\n", "\n", " # Update the weights\n", " optimizer.step()\n", "\n", "# Make a prediction\n", "x_pred = torch.tensor([[5.0]])\n", "y_pred = model(x_pred)\n", "\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mEpoch 100: loss = 0.2032\n", "Epoch 200: loss = 0.1116\n", "Epoch 300: loss = 0.0613\n", "Epoch 400: loss = 0.0336\n", "Epoch 500: loss = 0.0185\n", "Epoch 600: loss = 0.0101\n", "Epoch 700: loss = 0.0056\n", "Epoch 800: loss = 0.0031\n", "Epoch 900: loss = 0.0017\n", "Epoch 1000: loss = 0.0009\n", "\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: The prediction for x = 5 is y = 10.00.\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n" ] }, { "data": { "text/plain": [ "'The prediction for x = 5 is y = 10.00.'" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "agent_executor.run(\"\"\"Understand, write a single neuron neural network in PyTorch.\n", "Take synthetic data for y=2x. Train for 1000 epochs and print every 100 epochs.\n", "Return prediction for x = 5\"\"\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "#### Vectorstore Agent" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.embeddings.openai import OpenAIEmbeddings\n", "from langchain.vectorstores import Chroma\n", "from langchain.text_splitter import CharacterTextSplitter\n", "from langchain import OpenAI, VectorDBQA\n", "llm = OpenAI(temperature=0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.document_loaders import TextLoader\n", "\"\"\"\n", "然后,最后,使用 Chroma.from_documents() \n", "方法将文档转换为语谱图,并将其存储在名为 state_of_union_store 的对象中。\n", "\"\"\"\n", "#加载指定的文本文件\n", "loader = TextLoader('../../../state_of_the_union.txt')\n", "#从文本文件中加载文档\n", "documents = loader.load()\n", "#定义了一个名为 text_splitter 的 CharacterTextSplitter 对象,用于将文档分成\n", "#多个块。其中,chunk_size 参数指定每个块的大小,chunk_overlap 参数指定块之间的重叠大小。\n", "text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n", "texts = text_splitter.split_documents(documents)\n", "#定义了一个名为embeddings 的 OpenAIEmbeddings 对象,用于生成文档的嵌入表示。\n", "embeddings = OpenAIEmbeddings()\n", "\"\"\"\n", "下面代码是使用 Chroma 库从文档中提取语谱图,并将其存储在一个名为 state_of_union_store 的对象中。具体来说,它做了以下几件事情:\n", "从一个名为 texts 的列表中加载多个文本文件。\n", "将每个文本文件转换为一个包含单词和它们对应的嵌入向量的列表。这些嵌入向量是通过调用 OpenAIEmbeddings 类的 generate() 方法生成的。\n", "使用 Chroma.from_documents() 方法将所有文本文件的嵌入向量列表合并成一个完整的语谱图。该方法接受三个参数:texts、embeddings 和 \n", "collection_name,分别表示要加载的文本文件列表、每个文本文件中的嵌入向量列表以及语谱图的集合名称。\n", "最终,这段代码会将生成的语谱图存储在名为 state_of_union_store 的对象中,以便后续使用。\n", "\"\"\"\n", "state_of_union_store = Chroma.from_documents(texts, embeddings, collection_name=\"state-of-union\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.document_loaders import WebBaseLoader\n", "#创建一个 WebBaseLoader 对象并指定要加载的 URL\n", "loader = WebBaseLoader(\"https://beta.ruff.rs/docs/faq/\")\n", "#调用 load() 方法从指定的 URL 加载文档。该方法返回一个包含所有文档的列表。\n", "docs = loader.load()\n", "#使用 text_splitter.split_documents() 方法将所有文档分割成多个文本段落。该方法接受一个包含所有文档的列表作为参数,\n", "#并返回一个包含所有文本段落的列表。\n", "ruff_texts = text_splitter.split_documents(docs)\n", "\"\"\"\n", "使用 Chroma.from_documents() 方法将所有文本段落转换为语谱图,并将其存储在\n", "一个名为 ruff_store 的对象中。该方法接受三个参数:ruff_texts、embeddings 和 collection_name,分别表示所有文本\n", "段落的列表、每个文本段落对应的嵌入向量列表以及语谱图的集合名称。在本例中,语谱图的集合名称为 \"ruff\"\n", "\"\"\"\n", "ruff_store = Chroma.from_documents(ruff_texts, embeddings, collection_name=\"ruff\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents.agent_toolkits import (\n", " create_vectorstore_agent,\n", " VectorStoreToolkit,\n", " VectorStoreInfo,\n", ")\n", "#首先,创建一个 VectorStoreInfo 对象,并指定其名称、描述和指向语谱图存储对象的vectorstore\n", "vectorstore_info = VectorStoreInfo(\n", " name=\"state_of_union_address\",\n", " description=\"the most recent state of the Union adress\",\n", " vectorstore=state_of_union_store\n", ")\n", "#创建一个 VectorStoreToolkit 对象,将 vectorstore_info 对象作为参数传递给它。该对象用于管理与向量存储相关的元数据和工具。\n", "toolkit = VectorStoreToolkit(vectorstore_info=vectorstore_info)\n", "\"\"\"\n", "使用 create_vectorstore_agent() 方法创建一个\n", "代理。该方法接受三个参数:llm,表示语言模型;toolkit,表示 VectorStoreToolkit 对象;verbose,表示是否启用详\n", "细输出模式。在本例中,代理将使用 llm 作为其语言模型,并将 toolkit 作为其工具包。最终,代理的执行器将被返回,\n", "可以将其用于执行特定的任务或操作。\n", "\"\"\"\n", "agent_executor = create_vectorstore_agent(\n", " llm=llm,\n", " toolkit=toolkit,\n", " verbose=True\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"What did biden say about ketanji brown jackson is the state of the union address?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"What did biden say about ketanji brown jackson is the state of the union address? List the source.\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Multiple Vectorstores\n", "\n", "多个矢量存储库,我们也可以很容易地使用这个初始化一个具有多个向量存储的代理,并使用代理在它们之间连接。要做到这一点。这个代理是为连接彼此而优化的,所以它是一个不同的工具包和初始化器。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from langchain.agents.agent_toolkits import (\n", " create_vectorstore_router_agent,\n", " VectorStoreRouterToolkit,\n", " VectorStoreInfo,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "VectorStoreInfo这个类实例用于表示向量存储的信息。\n", "它有三个属性:name、description和vectorstore,分别表示名称、描述和指向向量存储对象的存储库。\n", "\"\"\"\n", "ruff_vectorstore_info = VectorStoreInfo(\n", " name=\"ruff\",\n", " description=\"Information about the Ruff python linting library\",\n", " vectorstore=ruff_store\n", ")\n", "\"\"\"\n", "VectorStoreRouterToolkit这个类用于表示向量存储路由器工具包。\n", "它有一个属性vectorstores,表示包含多个向量存储信息的列表,参数llm,表示语言模型。\n", "\"\"\"\n", "router_toolkit = VectorStoreRouterToolkit(\n", " vectorstores=[vectorstore_info, ruff_vectorstore_info],\n", " llm=llm\n", ")\n", "\"\"\"\n", "create_vectorstore_router_agent这个方法用于创建一个代理,该代理将使用向量存储路由器工具包来处理消息。\n", "它有三个参数:llm、toolkit和verbose,分别表示语言模型、工具包和详细输出模式。\n", "\"\"\"\n", "agent_executor = create_vectorstore_router_agent(\n", " llm=llm,\n", " toolkit=router_toolkit,\n", " verbose=True\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"What did biden say about ketanji brown jackson is the state of the union address?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"What tool does ruff use to run over Jupyter Notebooks?\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent_executor.run(\"What tool does ruff use to run over Jupyter Notebooks? Did the president mention that tool in the state of the union?\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Coding Exampls\n", "\n", "- [Question answering in documents](#question-answering-in-documents)\n", "- [BabyAGI with Tools](#babyagi-with-tools)\n", "- [Auto-GPT Assistant](#auto-gpt-assistant)\n", "\n", "### Question answering in documents" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "问答可以使用不同的chains:stuff,map_reduce,refine和map_rerank\n", "\n", "其中的stuff是最常使用的方式;map_reduce可以把输入的数据分割成若干个小的数据块,并在这些小的数据块上独立地执行计算,然后将计算结果进行汇总,从而得到最终的输出结果;refine是根据上下文的信息和一个问题给出一个初步的答案,如果答案不够准确就会迭代根据上下文信息以及之前的回答来提供更好的答案,直到找到最终的最佳答案。\n", "\n", "详细的文档说明点击👉[此处](https://python.langchain.com/en/latest/use_cases/question_answering.html)👈直接跳转。\n", "\n", "下面我们针对这个示例进行逐行的代码解释。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "# 设置HTTP代理\n", "os.environ['HTTP_PROXY'] = 'http://127.0.0.1:your port'\n", "# 设置HTTPS代理\n", "os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:your port'\n", "# openai的key\n", "os.environ[\"OPENAI_API_KEY\"] = \"Your OpenAI Key\"\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "#导入生成文本嵌入向量的所需要的库\n", "from langchain.embeddings.openai import OpenAIEmbeddings\n", "from langchain.embeddings.cohere import CohereEmbeddings\n", "#导入将文本分割成固定长度的小块,方便进行嵌入向量的计算和存储\n", "from langchain.text_splitter import CharacterTextSplitter\n", "#导入将文本嵌入向量存储到向量库种,以便进行文本检索和相似度的计算\n", "from langchain.vectorstores.elastic_vector_search import ElasticVectorSearch\n", "from langchain.vectorstores import Chroma\n", "#导入文档对象,包含了文档的名称和作者摘要内容等信息\n", "from langchain.docstore.document import Document\n", "#导入模板创建库,表示问答模板,包含问题答案提示等信息方便进行问答\n", "from langchain.prompts import PromptTemplate" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "#加载文本数据,当然这一步完全可以调用对应的loader完成,示例如下的注释部分:\n", "# from langchain.document_loaders import TextLoader\n", "# loader = TextLoader(\"./state_of_the_union.txt\")\n", "with open(\"./state_of_the_union.txt\") as f:\n", " state_of_the_union = f.read()\n", "#创建一个charactertextspliter对象,这个对象用于将文档切分成固定大小的文本块,这里是用一个文本块大小为1000字符串的切分器,并且不允许文本块之间有重叠的部分\n", "text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n", "#文本切分器对象的split_documents方法将文档数据分割成若干个文本,返回一个文本块列表,并将结果保存存储到texts变量中\n", "texts = text_splitter.split_text(state_of_the_union)\n", "\n", "#创建embedding对象,计算文本数据的词向量,这个对象使用Openai的gpt-3进行计算,可以将一个文本字符串映射为一个768维度的词向量\n", "embeddings = OpenAIEmbeddings()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Using embedded DuckDB without persistence: data will be transient\n" ] } ], "source": [ "#使用chroma类的from_documents方法,将文本块列表和词向量对象作为参数传入,生成一个chroma对象,chroma对象可以用于搜索文本块中的相似文本信息,可以用于文本相似度的计算和文本匹配的任务。\n", "docsearch = Chroma.from_texts(texts, embeddings, metadatas=[{\"source\": str(i)} for i in range(len(texts))])\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "#定义我们的问题\n", "query = \"What did the president say about Justice Breyer\"\n", "#调用docsearch的相似度计算搜索方式对问题进行检索\n", "docs = docsearch.similarity_search(query)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "#导入问答模型的langchain\n", "from langchain.chains.qa_with_sources import load_qa_with_sources_chain\n", "#使用openai模型来生成文本的嵌入向量\n", "from langchain.llms import OpenAI" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'output_text': \" The president thanked Justice Breyer for his service and mentioned that he nominated Circuit Court of Appeals Judge Ketanji Brown Jackson to continue Justice Breyer's legacy of excellence.\\nSOURCES: 31-pl\"}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#构建一个问答模型chain,把模型参数传入里面\n", "chain = load_qa_with_sources_chain(OpenAI(temperature=0), chain_type=\"stuff\")\n", "query = \"What did the president say about Justice Breyer\"\n", "#运行chain模型,使用docs作为输入文档的列表,query作为问题,从而返回最终的问题答案\n", "chain({\"input_documents\": docs, \"question\": query}, return_only_outputs=True)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'output_text': '\\n總統沒有對司法大法官布雷耶發表評論。\\nSOURCES: 31, 32, 34'}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "template = \"\"\"Given the following extracted parts of a long document and a question, create a final answer with references (\"SOURCES\"). \n", "If you don't know the answer, just say that you don't know. Don't try to make up an answer.\n", "ALWAYS return a \"SOURCES\" part in your answer.\n", "Respond in Chinese.\n", "\n", "QUESTION: {question}\n", "=========\n", "{summaries}\n", "=========\n", "FINAL ANSWER IN ITALIAN:\"\"\"\n", "#定义了一个PromptTemplate类,该类用于将模板(template)与输入变量(input_variables)绑定起来。\n", "#模板包括了两个输入变量:\"summaries\"和\"question\"。\n", "PROMPT = PromptTemplate(template=template, input_variables=[\"summaries\", \"question\"])\n", "#加载一个QA with Sources链,该链使用OpenAI作为其语言模型,并使用PromptTemplate类来生成回答问题的提示\n", "chain = load_qa_with_sources_chain(OpenAI(temperature=0), chain_type=\"stuff\", prompt=PROMPT)\n", "query = \"What did the president say about Justice Breyer\"\n", "#使用chain()方法对给定的文档(docs)和问题(query)进行查询,并返回只包含输出结果的字典。\n", "chain({\"input_documents\": docs, \"question\": query}, return_only_outputs=True)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### BabyAGI with Tools\n", "\n", "\n", "\n", "BabyAGI 是一种自主人工智能代理,可以根据给定目标生成并假装执行任务。(这个功能有没有熟悉?其实最近大火的AutoGPT就是基于此进行的设计)\n", "\n", "我们通过这个案例将帮助您了解创建自己的递归代理的组件。\n", "\n", "尽管 BabyAGI 使用特定的向量存储/模型提供程序(Pinecone、OpenAI),但使用 LangChain 实现它的好处之一是您可以轻松地将它们换成不同的选项。在此实现中,我们使用 FAISS vectorstore(因为它在本地运行且免费)。\n", "\n", "关于BabyAGI的详细说明可以[点击此处访问](https://github.com/yoheinakajima/babyagi)。\n", "\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "那么我们在这个案例开始之前首先得知道什么是BabyAGI对吧?下面是一个BabyAGI的用户操作指南,我们熟悉这个之后再进一步看上面相关的代码案例" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "# 设置HTTP代理\n", "os.environ['HTTP_PROXY'] = 'http://127.0.0.1:port'\n", "# 设置HTTPS代理\n", "os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:port'\n", "# openai的key\n", "os.environ[\"OPENAI_API_KEY\"] = \"your openai key like :sk-xxxxxxxxxxxxxxxx\"\n", "#谷歌搜索api的key,仅在agent中使用\n", "os.environ['SERPAPI_API_KEY']='your search API KEY'\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os\n", "#deque可以从队列两端执行快速的添加和弹出操作\n", "from collections import deque\n", "#类型提示功能,可以进行类型注释和类型检查\n", "from typing import Dict, List, Optional, Any\n", "from langchain import LLMChain, OpenAI, PromptTemplate\n", "from langchain.embeddings import OpenAIEmbeddings\n", "from langchain.llms import BaseLLM\n", "from langchain.vectorstores.base import VectorStore\n", "from pydantic import BaseModel, Field\n", "from langchain.chains.base import Chain" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "连接到矢量存储库" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "#这个类可以用于基于向量存储库窒息感近似搜索的类,由meta开发的异种骨高效的近似最近搜索库,可以处理高维向量数据\n", "from langchain.vectorstores import FAISS\n", "#这个类是一个用于在内存中存储文本文档的类,提供了添加、检索和删除文档的方法,是一个简单有用的文档存储解决方案\n", "from langchain.docstore import InMemoryDocstore" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "如果没有安装faiss库,请允许下面的代码,否则跳过下面pip这一步即可" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: faiss-cpu in /Users/yfcao/Anaconda/anaconda3/envs/egovlp/lib/python3.8/site-packages (1.7.3)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "%pip install faiss-cpu" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# Define your embedding model:text-embedding-ada-002\n", "embeddings_model = OpenAIEmbeddings()\n", "# Initialize the vectorstore as empty,选择的vectorstore是faiss\n", "import faiss\n", "#文本emmbedding的维数,每个文本嵌入向量中包含的数字数量\n", "embedding_size = 1536\n", "#向量空间中执行近似最近搜索,使用的是L2距离衡量向量之间的相似度\n", "index = faiss.IndexFlatL2(embedding_size)\n", "#embeddings_model.embed_query用于将文本查询转换为嵌入向量,InMemoryDocstore用于在内存中存储文档,最终将其存在vectorstore中\n", "vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "定义链\n", "\n", "BabyAGI 依赖于三个 LLM 链:\n", "\n", "任务创建链选择新任务添加到列表\n", "\n", "任务优先级链,用于重新确定任务的优先级\n", "\n", "执行任务的执行链" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为TaskCreationChain的类,它是LLMChain类的子类。该类的目的是生成任务,并返回llmchain对象。\n", "在类定义中,有一个静态方法from_llm(),它接受一个BaseLLM对象和一个布尔类型的verbose参数作为输入,并返回一个LLMChain对象。\n", "该方法使用了一个task_creation_template字符串来生成一个提示(prompt),该提示用于指导AI完成任务的创建。接下来,该代码还定\n", "义了一个PromptTemplate类,该类用于将模板(template)与输入变量(input_variables)绑定起来。在这个例子中,模板包括了五个\n", "输入变量:\"result\"、\"task_description\"、\"incomplete_tasks\"、\"objective\" 和 \"previous_task_result\"。最后,\n", "它使用cls()方法创建一个LLMChain对象,并将其保存在task_creation_chain变量中。\n", "\"\"\"\n", "class TaskCreationChain(LLMChain):\n", " @classmethod\n", " def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:\n", " \"\"\"Get the response parser.\n", " 仔细看关于模版的设计部分,怎么设计也比较重要:每一次设定目标,也要给出完成这个目标的结果,还有\n", " 这个结果对应的任务描述信息也会给到,此时还没有完整的任务就基于上面给到的结果继续罗列任务清单。\n", " 即:四项参数——\n", " 1. objective 目标\n", " 2. result 前一个任务结果\n", " 3. task_description 任务描述\n", " 4. incomplete_tasks 当前任务列表\n", " \"\"\"\n", " task_creation_template = (\n", " \"You are an task creation AI that uses the result of an execution agent\"\n", " \" to create new tasks with the following objective: {objective},\"\n", " \" The last completed task has the result: {result}.\"\n", " \" This result was based on this task description: {task_description}.\"\n", " \" These are incomplete tasks: {incomplete_tasks}.\"\n", " \" Based on the result, create new tasks to be completed\"\n", " \" by the AI system that do not overlap with incomplete tasks.\"\n", " \" Return the tasks as an array.\"\n", " )\n", " prompt = PromptTemplate(\n", " template=task_creation_template,\n", " input_variables=[\n", " \"result\",\n", " \"task_description\",\n", " \"incomplete_tasks\",\n", " \"objective\",\n", " ],\n", " )\n", " return cls(prompt=prompt, llm=llm, verbose=verbose)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为TaskPrioritizationChain的类,它是LLMChain类的子类。该类的目的是确定任务的优先级,并返回llmchain对象。\n", "在类定义中,有一个静态方法from_llm(),它接受一个BaseLLM对象和一个布尔类型的verbose参数作为输入,并返回一个LLMChain对象。该方法\n", "使用了一个task_prioritization_template字符串来生成一个提示(prompt),该提示用于指导AI完成任务的优先级排序。接下来,又定义了一个\n", "PromptTemplate类,该类用于将模板(template)与输入变量(input_variables)绑定起来。我们可以看到模板包括了三个输入变量:\n", "\"task_names\"、\"next_task_id\"和\"objective\"。最后,它使用cls()方法创建一个LLMChain对象,并将其保存在task_prioritization_chain\n", "这个变量中。\n", "\"\"\"\n", "class TaskPrioritizationChain(LLMChain):\n", " @classmethod\n", " def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:\n", " task_prioritization_template = (\n", " \"You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing\"\n", " \" the following tasks: {task_names}.\"\n", " \" Consider the ultimate objective of your team: {objective}.\"\n", " \" Do not remove any tasks. Return the result as a numbered list, like:\"\n", " \" #. First task\"\n", " \" #. Second task\"\n", " \" Start the task list with number {next_task_id}.\"\n", " )\n", " prompt = PromptTemplate(\n", " template=task_prioritization_template,\n", " input_variables=[\"task_names\", \"next_task_id\", \"objective\"],\n", " )\n", " return cls(prompt=prompt, llm=llm, verbose=verbose)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为ExecutionChain的类,它是LLMChain类的子类。该类的目的是执行任务,并返回llmchain对象。在类定义\n", "中,有一个静态方法from_llm(),它接受一个BaseLLM对象和一个布尔类型的verbose参数作为输入,并返回一个LLMChain对象。该方法\n", "使用了一个execution_template字符串来生成一个提示(prompt),该提示用于指导AI完成任务的执行。接下来,该代码还定义了一个\n", "PromptTemplate类,该类用于将模板(template)与输入变量(input_variables)绑定起来。在这个例子中,模板包括了三个输入变量:\n", "\"objective\"、\"context\" 和 \"task\"。最后,它使用cls()方法创建一个LLMChain对象,并将其保存在execution_chain变量中。\n", "\"\"\"\n", "class ExecutionChain(LLMChain):\n", " @classmethod\n", " def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:\n", " \"\"\"Get the response parser.\"\"\"\n", " execution_template = (\n", " \"You are an AI who performs one task based on the following objective: {objective}.\"\n", " \" Take into account these previously completed tasks: {context}.\"\n", " \" Your task: {task}.\"\n", " \" Response:\"\n", " )\n", " prompt = PromptTemplate(\n", " template=execution_template,\n", " input_variables=[\"objective\", \"context\", \"task\"],\n", " )\n", " return cls(prompt=prompt, llm=llm, verbose=verbose)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "定义 BabyAGI 控制器\n", "\n", "BabyAGI 将上面定义的链组合成一个(可能)无限循环的闭环运行过程。\n", "\n", "这个过程如下:\n", "1. 从任务列表中提取第一个任务.\n", "2. 将任务发送给执行代理, 该代理使用 OpenAI API 根据上下文完成任务.\n", "3. 润色结果并将其存储.\n", "4. 基于目标和前一个任务的结果创建新任务, 并根据优先级对任务列表进行排序." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "该方法返回一个字典列表,传入的参数包括LLMchain,result,任务列表的task_list,表示目标的objective字符串类型,\n", "这里用到的三链中的第一链task_creation_chian去构建任务列表,然后在chain.run的方法中将变量均以input_variables\n", "的形式传入模版中完成补全,而响应的结果以'\\n'分割开来并储存到new_tasks变量中,最终get_next_task方法返回一个将字典包\n", "装起来的列表\n", "\"\"\"\n", "def get_next_task(\n", " task_creation_chain: LLMChain,\n", " result: Dict,\n", " task_description: str,\n", " task_list: List[str],\n", " objective: str,\n", ") -> List[Dict]:\n", " \"\"\"Get the next task.\"\"\"\n", " incomplete_tasks = \", \".join(task_list)\n", "\n", " response = task_creation_chain.run(\n", " result=result,\n", " task_description=task_description,\n", " incomplete_tasks=incomplete_tasks,\n", " objective=objective,\n", " )\n", " #最终的响应结果是array组成的task,用换行符进行分割\n", " new_tasks = response.split(\"\\n\")\n", " #返回一个包含所有新任务信息的列表,其中每个任务信息都由一个\"task_name\"键组成。\n", " return [{\"task_name\": task_name} for task_name in new_tasks if task_name.strip()]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "\n", "\"\"\"\n", "这段代码定义了一个名为prioritize_tasks的函数,它接受四个参数:task_prioritization_chain、this_task_id、task_list和objective。\n", "该函数的目的是根据当前任务和目标设定,对任务列表进行优先级排序,并返回一个按照优先级排序的任务列表(List[Dict])。在函数中,首先将task_list\n", "中的每个任务字典(t)的任务名称(task_name)提取出来,生成一个任务名称列表(task_names)。然后将当前的任务ID(this_task_id)转换成整数,并加1,\n", "生成下一个任务的ID(next_task_id)。\n", "接着,使用一个三链中的任务优先级排序链去将task_names、next_task_id和objective传入其中补全input_variables。\n", "接着使用换行符分割响应内容将其存储到new_tasks字符串列表中。接下来,该代码创建一个空的列表用于保存按照优先级排序之后的任务列表(prioritized_task_list)。\n", "然后,使用for循环遍历new_tasks列表中的每个任务字符串(task_string),如果这个字符串是空的字符串或只包含空格就跳过这次循环。\n", "接着,使用strip()方法去除首位空格,强制将任务字符串分成两部分,分割符号是“.”。如果分割后得到的列表长度等于2,即成功拆分出task_id和task_name,\n", "则将它们添加到prioritized_task_list列表中。最后,该函数返回prioritized_task_list列表。\n", "\"\"\"\n", "def prioritize_tasks(\n", " task_prioritization_chain: LLMChain,\n", " this_task_id: int,\n", " task_list: List[Dict],\n", " objective: str,\n", ") -> List[Dict]:\n", " \"\"\"Prioritize tasks.\"\"\"\n", " #将任务列表中的每个任务字典(t)的任务名称task_name提取出来,生成一个任务名称列表task_names\n", " task_names = [t[\"task_name\"] for t in task_list]\n", " #将当前的任务ID(this_task_id)转换成整数,并加1,生成下一个任务的id(next_task_id)\n", " next_task_id = int(this_task_id) + 1\n", " #使用一个三链中的任务优先级排序链去将task_names,next_task_id,objective传入其中补全input_variables\n", " response = task_prioritization_chain.run(\n", " task_names=task_names, next_task_id=next_task_id, objective=objective\n", " )\n", " #使用换行符分割内容将其存储到new_tasks字符串列表中\n", " new_tasks = response.split(\"\\n\")\n", " #创建一个空的列表用于保存按照优先级排序之后的任务列表\n", " prioritized_task_list = []\n", " #\n", " for task_string in new_tasks:\n", " #如果这个字符串是空的字符串或只包含空格就跳过这次循环\n", " if not task_string.strip():\n", " continue\n", " #首先去除首位空格之后将其强制分成两部分,分割符号就是“.”,得到的是一个包含两个元素的列表task_parts\n", " task_parts = task_string.strip().split(\".\", 1)\n", " #如果task_parts 列表长度等于2,即成功拆分出task_id和task_names\n", " if len(task_parts) == 2:\n", " task_id = task_parts[0].strip()\n", " task_name = task_parts[1].strip()\n", " prioritized_task_list.append({\"task_id\": task_id, \"task_name\": task_name})\n", " return prioritized_task_list" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这段代码定义了一个名为_get_top_tasks的函数,该函数接受三个参数:vectorstore(一个向量存储库),query(查询语句)和k(要返回的结果数量)。\n", "该函数的目的是根据查询语句返回与查询最相关的前k个向量及其对应的任务名称。函数首先调用vectorstore对象的similarity_search_with_score方法\n", "进行相似度搜索,并将结果存储在results中。如果没有找到任何匹配项,则函数返回空列表。否则,函数使用Python内置的sorted函数对results中的元素\n", "按照相似性分数从大到小进行排序。该函数使用lambda表达式指定按第二个元素(即分数)进行排序,并使用reverse=True参数以倒序方式排序。然后,函数\n", "将排序后的结果拆分为两个元组,并将每个元组中的task_names转换为字符串,最后将这些字符串作为列表返回。\n", "\"\"\"\n", "def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:\n", " \"\"\"Get the top k tasks based on the query.\"\"\"\n", " #由vectorstore的相似度计算函数进行计算,返回的是最相似的K个向量以及其相似分数,存储在results中,这个里面并没有排序之后的结果\n", " results = vectorstore.similarity_search_with_score(query, k=k)\n", " if not results:\n", " return []\n", " #sorted函数是对results中结果元素按照相似性分数从大到小进行排序,并将排序好的向量以及分数拆分为两个元组,分别存储到sorted_results和_两个变量中,其中的\n", " #key=lambda x:x[1]表示按照元素中的第二个值(即分数)进行排序,reverse表示倒序排序\n", " sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))\n", " #将sorted_results列表中的每一个向量对应的task_names(存储在metadata[\"task\"]中)转换为字符串,并以列表的形式返回\n", " return [str(item.metadata[\"task\"]) for item in sorted_results]\n", "\n", "\"\"\"\n", "这段代码定义了一个名为execute_task的函数,该函数接受四个参数:vectorstore(一个向量存储库)、execution_chain(执行链对象)、\n", "objective(目标字符串)和task(要执行的任务字符串)。该函数的目的是根据给定的目标和任务执行指定的向量计算。函数首先调用_get_top_tasks函数\n", "获取与目标最相关的前k个向量及其对应的任务名称,并将结果存储在context变量中。然后,函数调用execution_chain.run()方法,将目标、上下文和\n", "任务作为参数传递给它。最后,函数返回执行结果。\n", "\"\"\"\n", "def execute_task(\n", " vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5\n", ") -> str:\n", " \"\"\"Execute a task.\"\"\"\n", " context = _get_top_tasks(vectorstore, query=objective, k=k)\n", " return execution_chain.run(objective=objective, context=context, task=task)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "定义了一个名为BabyAGI的类,继承了Chain和BaseModel类。\n", "BabyAGI类用于控制模型的执行流程,其中定义了如下内容:\n", "task_list是一个deque类型,用于存储任务列表;\n", "task_creation_chain、task_prioritization_chain、execution_chain是三链类型的实例,用于创建任务、排序任务以及执行任务;\n", "task_id_counter是一个整型变量,用于记录任务ID;\n", "vectorstore是一个VectorStore类型的实例,用于存储向量数据;\n", "max_iterations是一个整型变量,表示最大迭代次数;\n", "add_task方法用于添加任务到任务列表中;\n", "print_task_list方法用于打印当前的任务列表;\n", "print_next_task方法用于打印下一个任务;\n", "print_task_result方法用于打印任务执行结果;\n", "get_next_task方法用于获取下一个任务;\n", "prioritize_tasks方法用于重新排序任务列表。\n", "在类定义中还定义了一个Config类,用于配置pydantic对象,其中arbitrary_types_allowed属性设置为True表示允许任意类型。\n", "\"\"\"\n", "class BabyAGI(Chain, BaseModel):\n", " \"\"\"Controller model for the BabyAGI agent.\"\"\"\n", " #定义了task_list,类型为deque,使用field作为字段验证器,设置了默认工厂函数为deque,也就是创建一个空的双端队列作为默认值\n", " task_list: deque = Field(default_factory=deque)\n", " #定义了task_creation_chain,类型为TaskCreationChain,使用field作为字段验证器,设置了必须的字段标志\"...\",初始化的时候提供\n", " task_creation_chain: TaskCreationChain = Field(...)\n", " #同上\n", " task_prioritization_chain: TaskPrioritizationChain = Field(...)\n", " execution_chain: ExecutionChain = Field(...)\n", " #类型为int,初始值为1\n", " task_id_counter: int = Field(1)\n", " #创建时候不需要初始化\n", " vectorstore: VectorStore = Field(init=False)\n", " #默认值为None,表示没有最大迭代次数限制\n", " max_iterations: Optional[int] = None\n", "\n", " class Config:\n", " arbitrary_types_allowed = True\n", "\n", " def add_task(self, task: Dict):\n", " self.task_list.append(task)\n", "\n", " def print_task_list(self):\n", " #利用ANSI码设置终端的文本颜色和样式,下同\n", " print(\"\\033[95m\\033[1m\" + \"\\n*****TASK LIST*****\\n\" + \"\\033[0m\\033[0m\")\n", " for t in self.task_list:\n", " print(str(t[\"task_id\"]) + \": \" + t[\"task_name\"])\n", "\n", " def print_next_task(self, task: Dict):\n", " print(\"\\033[92m\\033[1m\" + \"\\n*****NEXT TASK*****\\n\" + \"\\033[0m\\033[0m\")\n", " print(str(task[\"task_id\"]) + \": \" + task[\"task_name\"])\n", "\n", " def print_task_result(self, result: str):\n", " print(\"\\033[93m\\033[1m\" + \"\\n*****TASK RESULT*****\\n\" + \"\\033[0m\\033[0m\")\n", " print(result)\n", "\n", " @property\n", " def input_keys(self) -> List[str]:\n", " return [\"objective\"]\n", "\n", " @property\n", " def output_keys(self) -> List[str]:\n", " return []\n", " \"\"\"\n", " 这个方法用于执行任务。该方法接收一个字典参数inputs作为输入,并返回执行结果。在方法内部,\n", " 首先从inputs中获取任务ID和第一个任务,然后根据第一个任务的名称创建一个新的任务,将其添加到\n", " 任务列表中,并执行该任务。接着,根据执行结果更新向量存储中的文本内容和元数据,并生成新任务的ID,\n", " 将新任务添加到任务列表中,最后重新排序任务列表。如果达到了最大迭代次数,则打印结束信息并退出循环。\n", " 在类中还定义了一些辅助方法和属性,如input_keys()属性用于获取输入键列表;output_keys()属性用\n", " 于获取输出键列表;TaskCreationChain.from_list()方法用于从任务列表中创建任务创建链等。\n", " \"\"\"\n", " def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:\n", " \"\"\"Run the agent.返回一个字典对象\"\"\"\n", " #从输入参数inputs中获取键为objective的值,并将其赋给变量objective\n", " objective = inputs[\"objective\"]\n", " #从输入参数inputs中获取键为first_task的值,并将其赋值给变量first_task,\n", " #如果inputs中没有键为first_task的项,没有这个键就使用默认的make a todo list\n", " #赋值给first_task,get方法可以避免字典中不存在某个键时候报错\n", " first_task = inputs.get(\"first_task\", \"Make a todo list\")\n", " self.add_task({\"task_id\": 1, \"task_name\": first_task})\n", " num_iters = 0\n", " while True:\n", " if self.task_list:\n", " self.print_task_list()\n", "\n", " # Step 1: Pull the first task\n", " #popleft是移除队首的任务,从队首移除一个元素并返回其值\n", " task = self.task_list.popleft()\n", " self.print_next_task(task)\n", "\n", " # Step 2: Execute the task\n", " result = execute_task(\n", " self.vectorstore, self.execution_chain, objective, task[\"task_name\"]\n", " )\n", " this_task_id = int(task[\"task_id\"])\n", " self.print_task_result(result)\n", "\n", " # Step 3: Store the result in Pinecone\n", " result_id = f\"result_{task['task_id']}\"\n", " self.vectorstore.add_texts(\n", " texts=[result],\n", " metadatas=[{\"task\": task[\"task_name\"]}],\n", " ids=[result_id],\n", " )\n", "\n", " # Step 4: Create new tasks and reprioritize task list\n", " new_tasks = get_next_task(\n", " self.task_creation_chain,\n", " result,\n", " task[\"task_name\"],\n", " [t[\"task_name\"] for t in self.task_list],\n", " objective,\n", " )\n", " for new_task in new_tasks:\n", " self.task_id_counter += 1\n", " new_task.update({\"task_id\": self.task_id_counter})\n", " self.add_task(new_task)\n", " self.task_list = deque(\n", " prioritize_tasks(\n", " self.task_prioritization_chain,\n", " this_task_id,\n", " list(self.task_list),\n", " objective,\n", " )\n", " )\n", " num_iters += 1\n", " if self.max_iterations is not None and num_iters == self.max_iterations:\n", " print(\n", " \"\\033[91m\\033[1m\" + \"\\n*****TASK ENDING*****\\n\" + \"\\033[0m\\033[0m\"\n", " )\n", " break\n", " return {}\n", "\n", " \"\"\"\n", " 这是一个类方法,用于从LLM(Language Model)实例中初始化BabyAGI控制器。\n", " 该类方法接受四个参数:llm、vectorstore、verbose和kwargs。其中,llm表示LLM实例,vectorstore表示向量存储实例,\n", " verbose表示是否启用详细输出模式,kwargs表示其他可选参数。在类方法中,首先调用TaskCreationChain.from_llm()\n", " 和TaskPrioritizationChain.from_llm()方法分别创建任务创建链和任务排序链。然后调用ExecutionChain.from_llm()方法\n", " 创建执行链。最后使用这些链和vectorstore以及传入的其他参数来创建一个BabyAGI类实例并返回。\n", " \"\"\"\n", " @classmethod\n", " def from_llm(\n", " cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs\n", " ) -> \"BabyAGI\":\n", " \"\"\"Initialize the BabyAGI Controller.\"\"\"\n", " task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)\n", " task_prioritization_chain = TaskPrioritizationChain.from_llm(\n", " llm, verbose=verbose\n", " )\n", " execution_chain = ExecutionChain.from_llm(llm, verbose=verbose)\n", " return cls(\n", " task_creation_chain=task_creation_chain,\n", " task_prioritization_chain=task_prioritization_chain,\n", " execution_chain=execution_chain,\n", " vectorstore=vectorstore,\n", " **kwargs,\n", " )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "运行 BabyAGI \n", "\n", "现在是创建 BabyAGI 控制器并观察它尝试实现您的目标的时候了。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "OBJECTIVE = \"Make a plan to travel around the world for a month\"" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "llm = OpenAI(temperature=0)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "定义了三个变量:verbose、max_iterations和baby_agi。\n", "verbose:这是一个布尔类型的变量,初始值为False。它表示是否启用详细输出模式。如果设置为True,则在执行任务时会输出更多的信息。\n", "max_iterations:这是一个可选整数类型的变量,初始值为3。它表示BabyAGI控制器的最大迭代次数。如果没有指定,则默认为3。\n", "baby_agi:这是从LLM实例中初始化BabyAGI控制器的结果。它是一个BabyAGI类的对象,包含了从LLM实例中生成的任务列表、执行任务的\n", "链以及向量存储等信息。\n", "\"\"\"\n", "verbose = False\n", "max_iterations: Optional[int] = 3\n", "baby_agi = BabyAGI.from_llm(\n", " llm=llm, vectorstore=vectorstore, verbose=verbose, max_iterations=max_iterations\n", ")" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "1: Make a todo list\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "1: Make a todo list\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "\n", "\n", "1. Research potential destinations\n", "2. Create a budget\n", "3. Book flights\n", "4. Book accommodations\n", "5. Research local attractions\n", "6. Pack necessary items\n", "7. Make copies of important documents\n", "8. Notify bank and credit card companies of travel plans\n", "9. Purchase travel insurance\n", "10. Make a list of emergency contacts\n", "11. Research visa requirements\n", "12. Apply for necessary visas\n", "13. Make a list of must-see attractions\n", "14. Make a list of must-do activities\n", "15. Make a list of must-try foods\n", "16. Make a list of must-visit restaurants\n", "17. Make a list of must-visit shops\n", "18. Make a list of must-visit markets\n", "19. Make a list of must-visit museums\n", "20. Make a list of must-visit galleries\n", "21. Make a list of must-visit parks\n", "22. Make a list of must-visit historical sites\n", "23. Make a list of must-visit religious sites\n", "24. Make a list of must-visit natural sites\n", "25. Make a list of must-visit cultural sites\n", "26. Make a list of must-visit nightlife spots\n", "\n", "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "2: Research local currency exchange rates\n", "3: Research local safety and security information\n", "4: Research local customs and etiquette\n", "5: Research local language basics\n", "6: Research local weather conditions\n", "7: Research local medical facilities\n", "8: Research local emergency services\n", "9: Research local shopping options\n", "10: Research local entertainment options\n", "11: Research local cultural events\n", "12: Research local outdoor activities\n", "13: Research local festivals\n", "14: Research local sports teams\n", "15: Research local volunteer opportunities\n", "16: Research local job opportunities\n", "17: Research local educational opportunities\n", "18: Research local religious services\n", "19: Research local political activities\n", "20: Research local environmental initiatives\n", "21: Research local community organizations\n", "22: Research local charities\n", "23: Research local art galleries\n", "24: Research local music venues\n", "25: Research local theater venues\n", "26: Research local libraries\n", "1: Research local transportation options\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "2: Research local currency exchange rates\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "\n", "\n", "I will research local currency exchange rates for the countries I plan to visit during my month-long trip around the world. I will use online resources such as currency conversion websites and travel blogs to find the most up-to-date exchange rates. I will also research the best ways to exchange money in each country, such as using ATMs or exchanging cash at banks.\n", "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "3: Research local transportation costs\n", "4: Research local accommodation options\n", "5: Research local food options\n", "6: Research local tourist attractions\n", "7: Research local tourist discounts\n", "8: Research local tourist visas\n", "9: Research local tourist activities\n", "10: Research local tourist guides\n", "11: Research local tourist maps\n", "12: Research local tourist safety tips\n", "13: Research local safety and security information\n", "14: Research local customs and etiquette\n", "15: Research local language basics\n", "16: Research local weather conditions\n", "17: Research local medical facilities\n", "18: Research local emergency services\n", "19: Research local shopping options\n", "20: Research local entertainment options\n", "21: Research local cultural events\n", "22: Research local outdoor activities\n", "23: Research local festivals\n", "24: Research local sports teams\n", "25: Research local volunteer opportunities\n", "26: Research local job opportunities\n", "27: Research local educational opportunities\n", "28: Research local religious services\n", "29: Research local political activities\n", "30: Research local environmental initiatives\n", "31: Research local community organizations\n", "32: Research local charities\n", "33: Research local art galleries\n", "34: Research local\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "3: Research local transportation costs\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "\n", "\n", "I will research local transportation costs by looking up the cost of flights, trains, buses, and other forms of transportation in each of the countries I plan to visit. I will also look into the cost of renting a car or taking a taxi in each country. Additionally, I will research any discounts or promotions that may be available for transportation costs.\n", "\u001b[91m\u001b[1m\n", "*****TASK ENDING*****\n", "\u001b[0m\u001b[0m\n" ] }, { "data": { "text/plain": [ "{'objective': 'Make a plan to travel around the world for a month'}" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "baby_agi({\"objective\": OBJECTIVE})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "现在,我们熟悉了BabyAGI的基本操作,现在看一下有关它的代码案例吧,下面的案例将会用到谷歌的搜索API,可以使agent进行联网搜索并完成任务规划\n", "\n", "首先是导入相关库" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "import os\n", "from collections import deque\n", "from typing import Dict, List, Optional, Any\n", "\n", "from langchain import LLMChain, OpenAI, PromptTemplate\n", "from langchain.embeddings import OpenAIEmbeddings\n", "from langchain.llms import BaseLLM\n", "from langchain.vectorstores.base import VectorStore\n", "from pydantic import BaseModel, Field\n", "from langchain.chains.base import Chain" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "连接到 Vector Store \n", "\n", "根据您使用的矢量存储,此步骤可能看起来有所不同。" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Note: you may need to restart the kernel to use updated packages.\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "%pip install faiss-cpu > /dev/null\n", "%pip install google-search-results > /dev/null\n", "from langchain.vectorstores import FAISS\n", "from langchain.docstore import InMemoryDocstore" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": [ "\n", "#embeddings_model:这是一个OpenAIEmbeddings类的对象,用于将查询嵌入到模型中以生成相似度向量。\n", "#它包含了一个embed_query()方法,用于将查询嵌入到指定的维度中。\n", "embeddings_model = OpenAIEmbeddings()\n", "import faiss\n", "#embedding_size:这是一个整数类型的变量,初始值为1536。它表示嵌入向量的维度。\n", "embedding_size = 1536\n", "#index:这是一个faiss.IndexFlatL2类型的对象,用于存储嵌入向量。它是一个扁平索引,\n", "#可以快速查找相似向量。在创建索引时,需要传入embedding_model.embed_query()方法的结果作为输入。\n", "index = faiss.IndexFlatL2(embedding_size)\n", "#vectorstore:这是一个FAISS类型的对象,用于存储嵌入向量。它与index一起使用,可以将查询嵌入到指定的\n", "#维度中并存储到内存中以供快速查找。在创建vectorstore时,需要传入embeddings_model.embed_query()方法的结果作为输入。\"\"\"\n", "vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "下面的定义链的过程,同上,大同小异,这里就不再赘述:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "class TaskCreationChain(LLMChain):\n", " @classmethod\n", " def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:\n", " \"\"\"Get the response parser.\"\"\"\n", " task_creation_template = (\n", " \"You are an task creation AI that uses the result of an execution agent\"\n", " \" to create new tasks with the following objective: {objective},\"\n", " \" The last completed task has the result: {result}.\"\n", " \" This result was based on this task description: {task_description}.\"\n", " \" These are incomplete tasks: {incomplete_tasks}.\"\n", " \" Based on the result, create new tasks to be completed\"\n", " \" by the AI system that do not overlap with incomplete tasks.\"\n", " \" Return the tasks as an array.\"\n", " )\n", " prompt = PromptTemplate(\n", " template=task_creation_template,\n", " input_variables=[\n", " \"result\",\n", " \"task_description\",\n", " \"incomplete_tasks\",\n", " \"objective\",\n", " ],\n", " )\n", " return cls(prompt=prompt, llm=llm, verbose=verbose)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "class TaskPrioritizationChain(LLMChain):\n", " @classmethod\n", " def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:\n", " \"\"\"Get the response parser.\"\"\"\n", " task_prioritization_template = (\n", " \"You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing\"\n", " \" the following tasks: {task_names}.\"\n", " \" Consider the ultimate objective of your team: {objective}.\"\n", " \" Do not remove any tasks. Return the result as a numbered list, like:\"\n", " \" #. First task\"\n", " \" #. Second task\"\n", " \" Start the task list with number {next_task_id}.\"\n", " )\n", " prompt = PromptTemplate(\n", " template=task_prioritization_template,\n", " input_variables=[\"task_names\", \"next_task_id\", \"objective\"],\n", " )\n", " return cls(prompt=prompt, llm=llm, verbose=verbose)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "谷歌搜索api我们会用到,因此在这里需要加入:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "from langchain.agents import ZeroShotAgent, Tool, AgentExecutor\n", "from langchain import OpenAI, SerpAPIWrapper, LLMChain\n", "\n", "#定义了一个todo_prompt模板,该模板将被用于生成任务的提示信息\n", "todo_prompt = PromptTemplate.from_template(\n", " \"You are a planner who is an expert at coming up with a todo list for a given objective. Come up with a todo list for this objective: {objective}\"\n", ")\n", "#定义了两个工具链:一个是LLMChain(使用OpenAI库),另一个是SerpAPIWrapper(用于搜索)。\n", "todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt)\n", "search = SerpAPIWrapper()\n", "\n", "\"\"\"\n", "定义了一个包含两个工具的工具列表,其中第一个工具是“Search”,用于回答当前事件相关的问题;\n", "第二个工具是“TODO”,用于为给定的目标生成任务列表。\n", "\"\"\"\n", "tools = [\n", " Tool(\n", " name=\"Search\",\n", " func=search.run,\n", " description=\"useful for when you need to answer questions about current events\",\n", " ),\n", " Tool(\n", " name=\"TODO\",\n", " func=todo_chain.run,\n", " description=\"useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!\",\n", " ),\n", "]\n", "\n", "#定义了前缀、后缀和模板,这些变量将被传递给ZeroShotAgent以生成任务提示信息。\n", "prefix = \"\"\"You are an AI who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\"\"\"\n", "suffix = \"\"\"Question: {task}\n", "{agent_scratchpad}\"\"\"\n", "prompt = ZeroShotAgent.create_prompt(\n", " tools,\n", " prefix=prefix,\n", " suffix=suffix,\n", " input_variables=[\"objective\", \"task\", \"context\", \"agent_scratchpad\"],\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "定义AGI controller, 为了把三个定义链组成成一个循环的链进入下面的步骤:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "这个函数的作用是获取下一个任务。\n", "它首先将之前执行过的任务列表转换为字符串,并将其作为参数传递给任务创建链的run方法。\n", "然后,它从任务创建链的响应中提取出新任务,并将它们存储在一个列表中。最后,它返回一\n", "个包含新任务名称的字典列表,每个字典都包含一个名为“task_name”的键和对应的值。\n", "\n", "task_creation_chain: LLMChain类型,表示任务创建链。\n", "result: Dict类型,表示之前执行任务的结果。\n", "task_description: str类型,表示要为新任务生成的任务描述。\n", "task_list: List[str]类型,表示之前执行过的任务列表。\n", "objective: str类型,表示任务的目标。\n", "\"\"\"\n", "def get_next_task(\n", " task_creation_chain: LLMChain,\n", " result: Dict,\n", " task_description: str,\n", " task_list: List[str],\n", " objective: str,\n", ") -> List[Dict]:\n", " \"\"\"Get the next task.\"\"\"\n", " incomplete_tasks = \", \".join(task_list)\n", " response = task_creation_chain.run(\n", " result=result,\n", " task_description=task_description,\n", " incomplete_tasks=incomplete_tasks,\n", " objective=objective,\n", " )\n", " new_tasks = response.split(\"\\n\")\n", " return [{\"task_name\": task_name} for task_name in new_tasks if task_name.strip()]" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "该函数的作用是确定每个任务的优先级。它首先将任务列表中的所有任务名称提取出来,并将其存储在一个列表中。\n", "然后,它计算下一个任务的ID,并将其作为参数传递给任务优先级创建链的run方法。接下来,它从任务优先级创建链的\n", "响应中提取出新任务,并将它们存储在一个列表中。最后,它遍历新任务列表中的每个任务字符串,并使用空格分隔符将\n", "其拆分为两个部分。如果第二个部分不为空,则表示这是一个具有ID和名称的任务。它将该任务添加到一个优先级任务列\n", "表中,并返回该列表。\n", "task_prioritization_chain: LLMChain类型,表示任务优先级创建链。\n", "this_task_id: int类型,表示当前任务的ID。\n", "task_list: List[Dict]类型,表示所有任务的列表。\n", "objective: str类型,表示任务的目标。\n", "\"\"\"\n", "def prioritize_tasks(\n", " task_prioritization_chain: LLMChain,\n", " this_task_id: int,\n", " task_list: List[Dict],\n", " objective: str,\n", ") -> List[Dict]:\n", " \"\"\"Prioritize tasks.\"\"\"\n", " task_names = [t[\"task_name\"] for t in task_list]\n", " next_task_id = int(this_task_id) + 1\n", " response = task_prioritization_chain.run(\n", " task_names=task_names, next_task_id=next_task_id, objective=objective\n", " )\n", " new_tasks = response.split(\"\\n\")\n", " prioritized_task_list = []\n", " for task_string in new_tasks:\n", " if not task_string.strip():\n", " continue\n", " task_parts = task_string.strip().split(\".\", 1)\n", " if len(task_parts) == 2:\n", " task_id = task_parts[0].strip()\n", " task_name = task_parts[1].strip()\n", " prioritized_task_list.append({\"task_id\": task_id, \"task_name\": task_name})\n", " return prioritized_task_list" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "该函数的作用是根据查询语句返回与查询最相关的k个任务名称。它首先调用相似向量存储对象的similarity_search_with_score方法\n", "来执行查询,并将结果存储在results变量中。如果没有结果,则函数返回空列表。否则,它使用zip和sorted函数来按相关性对结果进行\n", "排序,并将结果存储在sorted_results变量中。最后,它遍历sorted_results中的每个项目,并从其元数据中提取任务名称,并将其存\n", "储在一个列表中,最终返回该列表。\n", "\"\"\"\n", "def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:\n", " \"\"\"Get the top k tasks based on the query.\"\"\"\n", " results = vectorstore.similarity_search_with_score(query, k=k)\n", " if not results:\n", " return []\n", " sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))\n", " return [str(item.metadata[\"task\"]) for item in sorted_results]\n", "\n", "\"\"\"\n", "该函数的作用是执行给定的任务。它首先调用名为“_get_top_tasks”的辅助函数来获取与任务目标相关的前k个任务列表,并将结果存储\n", "在context变量中。然后,它将上下文作为参数传递给执行链的run方法,以执行任务。最后,该函数返回执行结果。\n", "\"\"\"\n", "def execute_task(\n", " vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5\n", ") -> str:\n", " \"\"\"Execute a task.\"\"\"\n", " context = _get_top_tasks(vectorstore, query=objective, k=k)\n", " return execution_chain.run(objective=objective, context=context, task=task)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "义了一个控制模拟AI代理行为的类,可以添加任务、执行任务并输出结果。它还提供了一些配置选项,以便在运行时自定义类的行为。\n", "task_list: 一个双向队列,存储了任务列表;\n", "task_creation_chain: 创建任务的链条;\n", "task_prioritization_chain: 对任务进行优先级排序的链条;\n", "execution_chain: 执行任务的代理;\n", "task_id_counter: 任务ID计数器;\n", "vectorstore: 一个向量储存库;\n", "max_iterations: 最大迭代次数。\n", "类定义中还有一些方法和属性:\n", "add_task(task): 添加任务到任务列表中;\n", "print_task_list(): 打印任务列表;\n", "print_next_task(task): 打印下一个任务;\n", "print_task_result(result): 打印任务结果;\n", "input_keys: 输入关键字列表;\n", "output_keys: 输出关键字列表。\n", "\"\"\"\n", "class BabyAGI(Chain, BaseModel):\n", " \"\"\"Controller model for the BabyAGI agent.\"\"\"\n", "\n", " task_list: deque = Field(default_factory=deque)\n", " task_creation_chain: TaskCreationChain = Field(...)\n", " task_prioritization_chain: TaskPrioritizationChain = Field(...)\n", " execution_chain: AgentExecutor = Field(...)\n", " task_id_counter: int = Field(1)\n", " vectorstore: VectorStore = Field(init=False)\n", " max_iterations: Optional[int] = None\n", "\n", " class Config:\n", " \"\"\"Configuration for this pydantic object.\"\"\"\n", "\n", " arbitrary_types_allowed = True\n", "\n", " def add_task(self, task: Dict):\n", " self.task_list.append(task)\n", "\n", " def print_task_list(self):\n", " print(\"\\033[95m\\033[1m\" + \"\\n*****TASK LIST*****\\n\" + \"\\033[0m\\033[0m\")\n", " for t in self.task_list:\n", " print(str(t[\"task_id\"]) + \": \" + t[\"task_name\"])\n", "\n", " def print_next_task(self, task: Dict):\n", " print(\"\\033[92m\\033[1m\" + \"\\n*****NEXT TASK*****\\n\" + \"\\033[0m\\033[0m\")\n", " print(str(task[\"task_id\"]) + \": \" + task[\"task_name\"])\n", "\n", " def print_task_result(self, result: str):\n", " print(\"\\033[93m\\033[1m\" + \"\\n*****TASK RESULT*****\\n\" + \"\\033[0m\\033[0m\")\n", " print(result)\n", "\n", " @property\n", " def input_keys(self) -> List[str]:\n", " return [\"objective\"]\n", "\n", " @property\n", " def output_keys(self) -> List[str]:\n", " return []\n", "\n", " def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:\n", " \"\"\"Run the agent.\"\"\"\n", " objective = inputs[\"objective\"]\n", " #要执行的第一个任务的名称\n", " first_task = inputs.get(\"first_task\", \"Make a todo list\")\n", " #加一个新任务到任务列表中。\n", " self.add_task({\"task_id\": 1, \"task_name\": first_task})\n", " num_iters = 0\n", " #一个无限循环,直到遇到某个退出条件为止。\n", " while True:\n", " if self.task_list:\n", " self.print_task_list()\n", "\n", " # Step 1: Pull the first task\n", " task = self.task_list.popleft()\n", " self.print_next_task(task)\n", "\n", " # Step 2: Execute the task\n", " result = execute_task(\n", " self.vectorstore, self.execution_chain, objective, task[\"task_name\"]\n", " )\n", " this_task_id = int(task[\"task_id\"])\n", " self.print_task_result(result)\n", "\n", " # Step 3: Store the result in Pinecone\n", " result_id = f\"result_{task['task_id']}\"\n", " self.vectorstore.add_texts(\n", " texts=[result],\n", " metadatas=[{\"task\": task[\"task_name\"]}],\n", " ids=[result_id],\n", " )\n", "\n", " # Step 4: Create new tasks and reprioritize task list\n", " new_tasks = get_next_task(\n", " self.task_creation_chain,\n", " result,\n", " task[\"task_name\"],\n", " [t[\"task_name\"] for t in self.task_list],\n", " objective,\n", " )\n", " for new_task in new_tasks:\n", " self.task_id_counter += 1\n", " new_task.update({\"task_id\": self.task_id_counter})\n", " self.add_task(new_task)\n", " self.task_list = deque(\n", " prioritize_tasks(\n", " self.task_prioritization_chain,\n", " this_task_id,\n", " list(self.task_list),\n", " objective,\n", " )\n", " )\n", " num_iters += 1\n", " if self.max_iterations is not None and num_iters == self.max_iterations:\n", " print(\n", " \"\\033[91m\\033[1m\" + \"\\n*****TASK ENDING*****\\n\" + \"\\033[0m\\033[0m\"\n", " )\n", " break\n", " return {}\n", " \"\"\"首先使用TaskCreationChain.from_llm()和TaskPrioritizationChain.from_llm()方法\n", " 分别创建任务创建链和任务优先级链。然后使用LLMChain()方法创建一个LLM链,并使用ZeroShotAgent()方法\n", " 创建一个ZeroShotAgent。最后使用AgentExecutor.from_agent_and_tools()方法创建一个代理执行器。\n", " 最后,该方法返回一个由这些对象组成的BabyAGI控制器对象。\"\"\"\n", " @classmethod\n", " def from_llm(\n", " cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs\n", " ) -> \"BabyAGI\":\n", " \"\"\"Initialize the BabyAGI Controller.\"\"\"\n", " task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)\n", " task_prioritization_chain = TaskPrioritizationChain.from_llm(\n", " llm, verbose=verbose\n", " )\n", " llm_chain = LLMChain(llm=llm, prompt=prompt)\n", " tool_names = [tool.name for tool in tools]\n", " agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)\n", " agent_executor = AgentExecutor.from_agent_and_tools(\n", " agent=agent, tools=tools, verbose=True\n", " )\n", " return cls(\n", " task_creation_chain=task_creation_chain,\n", " task_prioritization_chain=task_prioritization_chain,\n", " execution_chain=agent_executor,\n", " vectorstore=vectorstore,\n", " **kwargs,\n", " )" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "运行 BabyAGI \n", "\n", "现在是创建 BabyAGI 控制器并观察它尝试实现您的目标的时候了。" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [], "source": [ "OBJECTIVE = \"Write a weather report for Beijing today\"" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [], "source": [ "llm = OpenAI(temperature=0)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [], "source": [ "# Logging of LLMChains\n", "verbose = False\n", "# If None, will keep on going forever\n", "max_iterations: Optional[int] = 3\n", "baby_agi = BabyAGI.from_llm(\n", " llm=llm, vectorstore=vectorstore, verbose=verbose, max_iterations=max_iterations\n", ")" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "1: Make a todo list\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "1: Make a todo list\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to come up with a todo list\n", "Action: TODO\n", "Action Input: Write a weather report for Beijing today\u001b[0m\n", "Observation: \u001b[33;1m\u001b[1;3m\n", "\n", "1. Research current weather conditions in Beijing\n", "2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions\n", "3. Research historical weather patterns in Beijing\n", "4. Analyze current and historical data to determine any trends\n", "5. Write a brief introduction to the weather report\n", "6. Describe current weather conditions in Beijing\n", "7. Discuss any trends in the weather\n", "8. Make predictions about the weather in Beijing for the next 24 hours\n", "9. Conclude the report with a summary of the weather conditions\n", "10. Proofread and edit the report for accuracy and clarity\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: A todo list for writing a weather report for Beijing today: \n", "1. Research current weather conditions in Beijing\n", "2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions\n", "3. Research historical weather patterns in Beijing\n", "4. Analyze current and historical data to determine any trends\n", "5. Write a brief introduction to the weather report\n", "6. Describe current weather conditions in Beijing\n", "7. Discuss any trends in the weather\n", "8. Make predictions about the weather in Beijing for the next 24 hours\n", "9. Conclude the report with a summary of the weather conditions\n", "10. Proofread and edit the report for accuracy and clarity\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "A todo list for writing a weather report for Beijing today: \n", "1. Research current weather conditions in Beijing\n", "2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions\n", "3. Research historical weather patterns in Beijing\n", "4. Analyze current and historical data to determine any trends\n", "5. Write a brief introduction to the weather report\n", "6. Describe current weather conditions in Beijing\n", "7. Discuss any trends in the weather\n", "8. Make predictions about the weather in Beijing for the next 24 hours\n", "9. Conclude the report with a summary of the weather conditions\n", "10. Proofread and edit the report for accuracy and clarity\n", "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "2: Gather data on air quality, air pollution, and other relevant environmental conditions\n", "3: Research historical air quality patterns in Beijing\n", "4: Analyze current and historical data to determine any trends\n", "5: Compare current air quality to air quality standards\n", "6: Make predictions about the air quality in Beijing for the next 24 hours\n", "7: Discuss any trends in the air quality\n", "8: Write a brief summary of the air quality in Beijing\n", "9: Create a chart or graph to illustrate the air quality data\n", "10: Proofread and edit the report for accuracy and clarity\n", "1: Research current air quality in Beijing\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "2: Gather data on air quality, air pollution, and other relevant environmental conditions\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to search for data on air quality, air pollution, and other relevant environmental conditions\n", "Action: Search\n", "Action Input: air quality, air pollution, and other relevant environmental conditions\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mDespite the dramatic progress to date, air pollution continues to threaten Americans' health and welfare. The main obstacles are climate change, ...\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: Despite the dramatic progress to date, air pollution continues to threaten Americans' health and welfare. The main obstacles are climate change, ...\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "Despite the dramatic progress to date, air pollution continues to threaten Americans' health and welfare. The main obstacles are climate change, ...\n", "\u001b[95m\u001b[1m\n", "*****TASK LIST*****\n", "\u001b[0m\u001b[0m\n", "3: Compare current air quality to air quality standards\n", "4: Make predictions about the air quality in Beijing for the next 24 hours\n", "5: Research current air quality in Beijing\n", "6: Identify any sources of air pollution in Beijing and their potential impacts on air quality\n", "7: Investigate the effectiveness of current air quality regulations in Beijing\n", "8: Analyze the impact of climate change on air quality in Beijing\n", "9: Compare air quality in Beijing to other cities in China\n", "10: Examine the health effects of air pollution in Beijing\n", "11: Investigate the economic costs of air pollution in Beijing\n", "12: Research the potential solutions to improve air quality in Beijing\n", "13: Create a timeline of air quality in Beijing over the past decade\n", "14: Discuss any trends in the air quality\n", "15: Research historical air quality patterns in Beijing\n", "16: Analyze current and historical data to determine any trends\n", "17: Write a brief summary of the air quality in Beijing\n", "18: Create a chart or graph to illustrate the air quality data\n", "19: Proofread and edit the report for accuracy and clarity\n", "20: Summarize the findings of the report in a concise\n", "\u001b[92m\u001b[1m\n", "*****NEXT TASK*****\n", "\u001b[0m\u001b[0m\n", "3: Compare current air quality to air quality standards\n", "\n", "\n", "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", "\u001b[32;1m\u001b[1;3mThought: I need to search for air quality standards\n", "Action: Search\n", "Action Input: air quality standards\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mAQI values at or below 100 are generally thought of as satisfactory. When AQI values are above 100, air quality is unhealthy: at first for certain sensitive groups of people, then for everyone as AQI values get higher.\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I need to search for current air quality\n", "Action: Search\n", "Action Input: current air quality\u001b[0m\n", "Observation: \u001b[36;1m\u001b[1;3mGet air quality data where you live. ; Air Quality Index Scale ; 0 - 50. Good ; 51 - 100. Moderate ; 101 - 150. Unhealthy for Sensitive Groups (USG) ; 151 - 200.\u001b[0m\n", "Thought:\u001b[32;1m\u001b[1;3m I now know the final answer\n", "Final Answer: The current air quality in Beijing is Unhealthy for Sensitive Groups (USG).\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "\u001b[93m\u001b[1m\n", "*****TASK RESULT*****\n", "\u001b[0m\u001b[0m\n", "The current air quality in Beijing is Unhealthy for Sensitive Groups (USG).\n", "\u001b[91m\u001b[1m\n", "*****TASK ENDING*****\n", "\u001b[0m\u001b[0m\n" ] }, { "data": { "text/plain": [ "{'objective': 'Write a weather report for Beijing today'}" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "baby_agi({\"objective\": OBJECTIVE})" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Auto-GPT Assistant " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "首先我们对AutoGPT基于langchain进行相应地实现,以便了解其原理与步骤" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "首先建立tools,定义search tool, write-file tool, read-file tool\n", "安装一些我们这个栏目中即将要使用到的库函数" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pip install duckduckgo_search\n", "%pip install playwright\n", "%pip install bs4\n", "%pip install nest_asyncio\n", "%pip install tiktoken" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "配置程序运行代理以及相关API Key" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import os\n", "# 设置HTTP代理\n", "os.environ['HTTP_PROXY'] = 'http://127.0.0.1:xxxx'\n", "# 设置HTTPS代理\n", "os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:xxxx'\n", "\n", "# openai的key\n", "os.environ[\"OPENAI_API_KEY\"] = \"sk-xxxxxxxxxxxx\"\n", "#谷歌搜索api的key,仅在agent中使用\n", "os.environ['SERPAPI_API_KEY']='--------------Your API KEY----------------------'" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "以下的代码注释由于在Coding Examples中已经出现过,将对于重复的部分不再特别添加注释说明,如依然有疑问请参阅完整的[Coding Examples](#coding-exampls)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from langchain.utilities import SerpAPIWrapper\n", "from langchain.agents import Tool\n", "from langchain.tools.file_management.write import WriteFileTool\n", "from langchain.tools.file_management.read import ReadFileTool\n", "\n", "\"\"\"\n", "它创建了一个SerpAPIWrapper对象,并将其赋值给变量search。然后,它定义了一个名为“tools”的列表,其中包含了\n", "三个元素:一个Tool对象,该对象代表名称为“search”的工具;一个WriteFileTool对象;和一个ReadFileTool对象。\n", "\"\"\"\n", "search = SerpAPIWrapper()\n", "tools = [\n", " Tool(\n", " name = \"search\",\n", " func=search.run,\n", " description=\"useful for when you need to answer questions about current events. You should ask targeted questions\"\n", " ),\n", " WriteFileTool(),\n", " ReadFileTool(),\n", "]" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from langchain.vectorstores import FAISS\n", "from langchain.docstore import InMemoryDocstore\n", "from langchain.embeddings import OpenAIEmbeddings" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "embeddings_model = OpenAIEmbeddings()\n", "import faiss\n", "embedding_size = 1536\n", "index = faiss.IndexFlatL2(embedding_size)\n", "vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from langchain.experimental.autonomous_agents.autogpt.agent import AutoGPT\n", "from langchain.chat_models import ChatOpenAI" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "下面是使用AutoGPT创建一个名为\"agent\"的智能代理。具体来说,该智能代理将扮演一个助理的角色,\n", "并使用指定的工具和语言模型(在这里是ChatOpenAI)来与用户进行交互。其中,参数ai_name指定了智能\n", "代理的名称为\"Tom\",ai_role指定了其角色为助理;参数tools指定了智能代理可以使用的工具列表;参数\n", "llm指定了智能代理的语言模型为ChatOpenAI,并将其温度设置为0,这意味着它将尽可能地提供准确的回答;\n", "参数memory指定了智能代理使用的检索器为vectorstore.as_retriever()。\n", "通过这部分代码,我们可以创建一个具有自定义角色、工具和语言模型的智能代理,并使用指定的检索器来获\n", "取信息。\n", "\"\"\"\n", "agent = AutoGPT.from_llm_and_tools(\n", " ai_name=\"Tom\",\n", " ai_role=\"Assistant\",\n", " tools=tools,\n", " llm=ChatOpenAI(temperature=0),\n", " memory=vectorstore.as_retriever()\n", ")\n", "agent.chain.verbose = True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent.run([\"make a plan to travel around the China for a month, and give me five advices\"])\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "运行代码最终将会在当前目录下新建出很多的txt文件,包括不限于china_trip_plan.txt, china_info.txt, budge.txt, flight_info.txt等文件,您可以通过运行该noteboook代码进行体验。" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "由于运行过程中需要finish的中断命令,因此我们上面运行的程序将部分运行结果放置在这里:\n", "OUT:\n", "\n", "\n", "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n", "Your decisions must always be made independently without seeking user assistance.\n", "Play to your strengths as an LLM and pursue simple strategies with no legal complications.\n", "If you have completed all your tasks, make sure to use the \"finish\" command.\n", "\n", "GOALS:\n", "\n", "1. make a plan to travel around the China for a month, and give me five advices\n", "\n", "\n", "Constraints:\n", "1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n", "2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n", "3. No user assistance\n", "4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n", "\n", "Commands:\n", "1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {\"query\": {\"title\": \"Query\", \"type\": \"string\"}}\n", "2. write_file: Write file to disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}, \"text\": {\"title\": \"Text\", \"description\": \"text to write to file\", \"type\": \"string\"}}\n", "3. read_file: Read file from disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}}\n", "4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n", "\n", "Resources:\n", "1. Internet access for searches and information gathering.\n", "2. Long Term memory management.\n", "3. GPT-3.5 powered Agents for delegation of simple tasks.\n", "4. File output.\n", "\n", "Performance Evaluation:\n", "1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n", "2. Constructively self-criticize your big-picture behavior constantly.\n", "3. Reflect on past decisions and strategies to refine your approach.\n", "4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n", "\n", "You should only respond in JSON format as described below \n", "Response Format: \n", "{\n", " \"thoughts\": {\n", " \"text\": \"thought\",\n", " \"reasoning\": \"reasoning\",\n", " \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n", " \"criticism\": \"constructive self-criticism\",\n", " \"speak\": \"thoughts summary to say to user\"\n", " },\n", " \"command\": {\n", " \"name\": \"command name\",\n", " \"args\": {\n", " \"arg name\": \"value\"\n", " }\n", " }\n", "} \n", "Ensure the response can be parsed by Python json.loads\n", "System: The current time and date is Wed Apr 26 16:17:15 2023\n", "System: This reminds you of these events from your past:\n", "['Assistant Reply: {\"thoughts\": {\"text\": \"I will use the information I retrieved from the affordable accommodations and transportation file to create a budget for my trip. I will use the write_file command to save the budget to a file. Then, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\", \"reasoning\": \"I have retrieved the information I need to create a budget for my trip. I also need to find popular tourist attractions in China and create a packing list. I will use the write_file command to save both the budget and packing list to files.\", \"plan\": \"- Use the information from the affordable accommodations and transportation file to create a budget for my trip.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n- Use the write_file command to save the budget to a file.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n- Use the search command to find popular tourist attractions in China and save the information to a file.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n- Use the write_file command to save a packing list to a file.\", \"criticism\": \"I need to make sure I am not spending too much time on planning and that I am making progress towards actually traveling to China.\", \"speak\": \"I am going to use the information I retrieved from the affordable accommodations and transportation file to create a budget for my trip. I will use the write_file command to save the budget to a file. Then, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\"}, \"command\": {\"name\": \"write_file\", \"args\": {\"file_path\": \"budget.txt\", \"text\": \"Budget for China Trip:\\\\\\\\nAccommodation: $80 per day\\\\\\\\nTransportation: $3 per day\\\\\\\\nFood: $30 per day\\\\\\\\nTotal: $113 per day\\\\\\\\nTotal for 30 days: $3,390\"}}} \\nResult: Command write_file returned: File written successfully to budget.txt. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"Now that I have all the necessary information saved to files, I can start planning my trip. I will use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China. Then, I will use this information to create a budget for my trip. After that, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\",\\n \"reasoning\": \"I have all the necessary information saved to files. I can use the information I saved earlier about affordable accommodations and transportation in China to create a budget for my trip. I also need to find popular tourist attractions in China and create a packing list. I will use the write_file command to save both the budget and packing list to files.\",\\n \"plan\": \"- Use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China.\\\\\\\\\\\\\\\\n- Use this information to create a budget for my trip.\\\\\\\\\\\\\\\\n- Use the search command to find popular tourist attractions in China and save the information to a file.\\\\\\\\\\\\\\\\n- Use the write_file command to save a packing list to a file.\",\\n \"criticism\": \"I need to make sure I am not spending too much time on planning and that I am making progress towards actually traveling to China.\",\\n \"speak\": \"Now that I have all the necessary information saved to files, I am going to use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China. Then, I will use this information to create a budget for my trip. After that, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\"\\n },\\n \"command\": {\\n \"name\": \"read_file\",\\n \"args\": {\\n \"file_path\": \"china_accommodations_transportation.txt\"\\n }\\n }\\n} \\nResult: Command read_file returned: Accommodation: $80 per day; Transportation: $3 per day; Food: $30 per day ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I am going to use the write_file command to save the information I found earlier about affordable accommodations and transportation in China to a file. This will make it easier for me to access the information later when I need it.\", \\n \"reasoning\": \"I have found affordable accommodations and transportation options for my trip to China. I want to make sure I have easy access to this information later when I need it.\", \\n \"plan\": \"- Use the write_file command to save the information about affordable accommodations and transportation in China to a file\", \\n \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually traveling to China.\", \\n \"speak\": \"I am going to use the write_file command to save the information I found earlier about affordable accommodations and transportation in China to a file.\"\\n }, \\n \"command\": {\\n \"name\": \"write_file\", \\n \"args\": {\\n \"file_path\": \"china_info.txt\", \\n \"text\": \"Accommodation: $80 per day; Transportation: $3 per day; Food: $30 per ...\"\\n }\\n }\\n} \\nResult: Command write_file returned: File written successfully to china_info.txt. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I will use the write_file command to save the information about affordable accommodations and transportation in China to a file. Then, I will use the search command to find affordable flights to China and use the write_file command to save the flight information to a file.\",\\n \"reasoning\": \"I have found information about affordable accommodations and transportation in China using the search command. I need to save this information to a file so that I can refer to it later. I also need to find affordable flights to China and save this information to a file.\",\\n \"plan\": \"- Use the write_file command to save the information about affordable accommodations and transportation in China to a file.\\\\\\\\\\\\\\\\n- Use the search command to find affordable flights to China and use the write_file command to save the flight information to a file.\",\\n \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually traveling to China.\",\\n \"speak\": \"I am going to use the write_file command to save the information about affordable accommodations and transportation in China to a file. Then, I will use the search command to find affordable flights to China and use the write_file command to save the flight information to a file.\"\\n },\\n \"command\": {\\n \"name\": \"write_file\",\\n \"args\": {\\n \"file_path\": \"china_accommodations_transportation.txt\",\\n \"text\": \"Accommodation: $80 per day; Transportation: $3 per day; Food: $30 per day\"\\n }\\n }\\n} \\nResult: Command write_file returned: File written successfully to china_accommodations_transportation.txt. ']\n", "\n", "\n", "Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n", "\n", "\u001b[1m> Finished chain.\u001b[0m\n", "{\n", " \"thoughts\": {\n", " \"text\": \"Now that I have all the necessary information saved to files, I can start planning my trip. I will use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China. Then, I will use this information to create a budget for my trip. After that, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\",\n", " \"reasoning\": \"I have all the necessary information saved to files. I can use the information I saved earlier about affordable accommodations and transportation in China to create a budget for my trip. I also need to find popular tourist attractions in China and create a packing list. I will use the write_file command to save both the budget and packing list to files.\",\n", " \"plan\": \"- Use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China.\\\\n- Use this information to create a budget for my trip.\\\\n- Use the search command to find popular tourist attractions in China and save the information to a file.\\\\n- Use the write_file command to save a packing list to a file.\",\n", " \"criticism\": \"I need to make sure I am not spending too much time on planning and that I am making progress towards actually traveling to China.\",\n", " \"speak\": \"Now that I have all the necessary information saved to files, I am going to use the read_file command to access the information I saved earlier about affordable accommodations and transportation in China. Then, I will use this information to create a budget for my trip. After that, I will use the search command to find popular tourist attractions in China and save the information to a file. Finally, I will use the write_file command to save a packing list to a file.\"\n", " },\n", " \"command\": {\n", " \"name\": \"read_file\",\n", " \"args\": {\n", " \"file_path\": \"china_accommodations_transportation.txt\"\n", " }\n", " }\n", "}\n", "\n", "\n", "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n", "Prompt after formatting:\n", "\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n", "Your decisions must always be made independently without seeking user assistance.\n", "Play to your strengths as an LLM and pursue simple strategies with no legal complications.\n", "If you have completed all your tasks, make sure to use the \"finish\" command.\n", "\n", "GOALS:\n", "\n", "1. make a plan to travel around the China for a month, and give me five advices\n", "\n", "\n", "Constraints:\n", "1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n", "2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n", "3. No user assistance\n", "4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n", "\n", "Commands:\n", "1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {\"query\": {\"title\": \"Query\", \"type\": \"string\"}}\n", "2. write_file: Write file to disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}, \"text\": {\"title\": \"Text\", \"description\": \"text to write to file\", \"type\": \"string\"}}\n", "3. read_file: Read file from disk, args json schema: {\"file_path\": {\"title\": \"File Path\", \"description\": \"name of file\", \"type\": \"string\"}}\n", "4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n", "\n", "Resources:\n", "1. Internet access for searches and information gathering.\n", "2. Long Term memory management.\n", "3. GPT-3.5 powered Agents for delegation of simple tasks.\n", "4. File output.\n", "\n", "Performance Evaluation:\n", "1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n", "2. Constructively self-criticize your big-picture behavior constantly.\n", "3. Reflect on past decisions and strategies to refine your approach.\n", "4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n", "\n", "You should only respond in JSON format as described below \n", "Response Format: \n", "{\n", " \"thoughts\": {\n", " \"text\": \"thought\",\n", " \"reasoning\": \"reasoning\",\n", " \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n", " \"criticism\": \"constructive self-criticism\",\n", " \"speak\": \"thoughts summary to say to user\"\n", " },\n", " \"command\": {\n", " \"name\": \"command name\",\n", " \"args\": {\n", " \"arg name\": \"value\"\n", " }\n", " }\n", "} \n", "Ensure the response can be parsed by Python json.loads\n", "System: The current time and date is Wed Apr 26 16:18:07 2023\n", "System: This reminds you of these events from your past:\n", "['Assistant Reply: {\"thoughts\": {\"text\": \"I will use the search command to find popular tourist attractions in China and save the information to a file. I should make sure to include the location, hours of operation, and admission fees for each attraction. Then, I will use the write_file command to save the information to a file.\", \"reasoning\": \"I need to find popular tourist attractions in China and save the information to a file. I will use the search command to find this information and the write_file command to save it to a file.\", \"plan\": \"- Use the search command to find popular tourist attractions in China and save the information to a file.\\\\\\\\\\\\\\\\n- Use the write_file command to save the information to a file.\", \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually traveling to China.\", \"speak\": \"I am going to use the search command to find popular tourist attractions in China and save the information to a file. Then, I will use the write_file command to save the information to a file.\"}, \"command\": {\"name\": \"search\", \"args\": {\"query\": \"popular tourist attractions in China\"}}} \\nResult: Command search returned: China, officially the People\\'s Republic of China, is a country in East Asia. It has been the world\\'s most populous country since at least 1950, with a population exceeding 1.4 billion, but is expected to be overtaken by India in mid-2023. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I will use the search command to find information about the best places to visit in China. This will help me plan my itinerary for the month.\", \\n \"reasoning\": \"Now that I have booked my accommodations, transportation, and flights to China, I need to plan my itinerary. I will use the search command to find information about the best places to visit in China.\", \\n \"plan\": \"- Use the search command to find information about the best places to visit in China\", \\n \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually traveling to China.\", \\n \"speak\": \"I am going to use the search command to find information about the best places to visit in China.\"\\n }, \\n \"command\": {\\n \"name\": \"search\", \\n \"args\": {\\n \"query\": \"best places to visit in China\"\\n }\\n }\\n} \\nResult: Command search returned: China, officially the People\\'s Republic of China, is a country in East Asia. It has been the world\\'s most populous country since at least 1950, with a population exceeding 1.4 billion, but is expected to be overtaken by India in mid-2023. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I need to find the best places to visit in China. I should search for articles or travel guides that list the top tourist destinations in China.\",\\n \"reasoning\": \"I want to make sure I don\\'t miss any important tourist destinations in China.\",\\n \"plan\": \"- Search for articles or travel guides that list the top tourist destinations in China\",\\n \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually planning my trip.\",\\n \"speak\": \"I am going to search for articles or travel guides that list the top tourist destinations in China.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"query\": \"best tourist destinations in China\"\\n }\\n }\\n} \\nResult: Command search returned: China, officially the People\\'s Republic of China, is a country in East Asia. It has been the world\\'s most populous country since at least 1950, with a population exceeding 1.4 billion, but is expected to be overtaken by India in mid-2023. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I need to start planning my trip to China. I should start by researching the best places to visit and the most efficient way to travel between them.\",\\n \"reasoning\": \"I need to gather information to make informed decisions about my trip.\",\\n \"plan\": \"- Research the best places to visit in China\\\\n- Research the most efficient way to travel between destinations\\\\n- Create a rough itinerary for my trip\",\\n \"criticism\": \"I need to make sure I am not spending too much time on research and that I am making progress towards actually planning my trip.\",\\n \"speak\": \"I am going to start by researching the best places to visit in China and the most efficient way to travel between them.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"query\": \"best places to visit in China\"\\n }\\n }\\n} \\nResult: Command search returned: China, officially the People\\'s Republic of China, is a country in East Asia. It has been the world\\'s most populous country since at least 1950, with a population exceeding 1.4 billion, but is expected to be overtaken by India in mid-2023. ']\n", "\n", "\n", "Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "如下的示例是用AutoGPT进行Winning Marathon Times的查找。该示例代码中使用到的model是GPT-4,因此需要提前准备好GPT-4调用需要的环境条件" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "import pandas as pd\n", "from langchain.experimental.autonomous_agents.autogpt.agent import AutoGPT\n", "from langchain.chat_models import ChatOpenAI\n", "from langchain.agents.agent_toolkits.pandas.base import create_pandas_dataframe_agent\n", "from langchain.docstore.document import Document\n", "\"\"\"\n", "asyncio是一个Python标准库,用于编写异步代码。\n", "nest_asyncio是一个第三方库,用于在Python中使用asyncio的非阻塞I/O操作。\n", "调用nest_asyncio.apply()函数来运行所有异步代码。\n", "\"\"\"\n", "import asyncio\n", "import nest_asyncio\n", "\n", "nest_asyncio.apply()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "llm = ChatOpenAI(model_name=\"gpt-4\", temperature=1.0)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import os\n", "from contextlib import contextmanager\n", "from typing import Optional\n", "from langchain.agents import tool\n", "from langchain.tools.file_management.read import ReadFileTool\n", "from langchain.tools.file_management.write import WriteFileTool\n", "\n", "ROOT_DIR = \"./data/\"\n", "\"\"\"\n", "pushed函数定义了一个名为pushd的上下文管理器,用于更改当前工作目录。它接受一个参数new_dir,表示新的工作目录路径。\n", "在进入pushd上下文管理器时,当前工作目录将被保存为prev_dir,然后使用os.chdir()函数将当前工作目录更改为new_dir。在\n", "离开上下文管理器时,prev_dir将被恢复为当前工作目录。这个上下文管理器可以用来在需要暂时更改工作目录的情况下,保持代码\n", "中路径和文件名的正确性。例如,在一个Python脚本中,可以使用pushd上下文管理器来切换到数据集所在的目录,然后执行数据预\n", "处理或模型训练等任务。完成任务后,可以使用相同的上下文管理器将工作目录切换回原始目录。\n", "\"\"\"\n", "@contextmanager\n", "def pushd(new_dir):\n", " \"\"\"Context manager for changing the current working directory.\"\"\"\n", " prev_dir = os.getcwd()\n", " os.chdir(new_dir)\n", " try:\n", " yield\n", " finally:\n", " os.chdir(prev_dir)\n", "\n", "\"\"\"\n", "该函数名为process_csv,用于处理CSV文件并执行一些操作.\n", "接受三个参数:csv_file_path(字符串类型,表示CSV文件路径)\n", "instructions(字符串类型,表示指令)\n", "output_path(可选字符串类型,表示输出路径)。\n", "在函数中,使用了pandas库来读取CSV文件,然后创建了一个pandas数据帧代理对象agent。接下来,根据传入的指令对数据进行处理,\n", "并将结果保存到指定的输出路径中。如果处理过程中出现异常,则返回错误信息。此外,该代码还包含了一个注释@tool,说明该函数的作\n", "用是用于在REPL环境中使用pandas处理CSV文件。\n", "\"\"\"\n", "@tool\n", "def process_csv(\n", " csv_file_path: str, instructions: str, output_path: Optional[str] = None\n", ") -> str:\n", " \"\"\"Process a CSV by with pandas in a limited REPL.\\\n", " Only use this after writing data to disk as a csv file.\\\n", " Any figures must be saved to disk to be viewed by the human.\\\n", " Instructions should be written in natural language, not code. Assume the dataframe is already loaded.\"\"\"\n", " with pushd(ROOT_DIR):\n", " try:\n", " df = pd.read_csv(csv_file_path)\n", " except Exception as e:\n", " return f\"Error: {e}\"\n", " agent = create_pandas_dataframe_agent(llm, df, max_iterations=30, verbose=True)\n", " if output_path is not None:\n", " instructions += f\" Save output to disk at {output_path}\"\n", " try:\n", " result = agent.run(instructions)\n", " return result\n", " except Exception as e:\n", " return f\"Error: {e}\"" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "async def async_load_playwright(url: str) -> str:\n", " \"\"\"\n", " 加载指定的URL并使用Playwright解析为BeautifulSoup对象。\n", " 参数:\n", " url (str): 要加载和解析的URL。\n", " 返回值:\n", " str: 解析后的HTML文本。\n", " \"\"\"\n", " from bs4 import BeautifulSoup\n", " from playwright.async_api import async_playwright\n", "\n", " # 存储解析后的HTML文本\n", " results = \"\" \n", " #使用async with语句创建一个上下文环境,自动关闭浏览器实例\n", " async with async_playwright() as p:\n", " #在无头模式下启动Chromium浏览器实例\n", " browser = await p.chromium.launch(headless=True)\n", " try:\n", " #创建一个新的页面实例\n", " page = await browser.new_page()\n", " #加载指定的URL\n", " await page.goto(url)\n", "\n", " #获取页面源代码\n", " page_source = await page.content()\n", " #将页面源代码解析为BeautifulSoup对象\n", " soup = BeautifulSoup(page_source, \"html.parser\")\n", "\n", " #从HTML中提取所有脚本和样式标签的内容\n", " for script in soup([\"script\", \"style\"]):\n", " script.extract()\n", "\n", " #从HTML中提取纯文本内容\n", " text = soup.get_text()\n", " #将文本按行分割并去除空格\n", " lines = (line.strip() for line in text.splitlines())\n", " #将文本按单词或空格分割并去除空格\n", " chunks = (phrase.strip() for line in lines for phrase in line.split(\" \"))\n", " #将结果拼接成字符串并去除空格\n", " results = \"\\n\".join(chunk for chunk in chunks if chunk)\n", " except Exception as e:\n", " #如果出现异常,将错误信息添加到结果字符串中\n", " results = f\"Error: {e}\"\n", " #关闭浏览器实例\n", " await browser.close()\n", " #返回解析后的HTML文本\n", " return results\n", "#定义一个异步函数,用于运行线程\n", "def run_async(coro):\n", " #获取事件循环对象\n", " event_loop = asyncio.get_event_loop()\n", " #运行协程并返回结果\n", " return event_loop.run_until_complete(coro)\n", "\n", "#定义一个工具函数,用于浏览网页\n", "#以冗长的方式抓取整个网页。很可能会导致解析问题\n", "@tool\n", "def browse_web_page(url: str) -> str:\n", " \"\"\"调用异步函数,加载指定的URL并解析为BeautifulSoup对象\"\"\"\n", " return run_async(async_load_playwright(url))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "from langchain.tools import BaseTool, DuckDuckGoSearchTool\n", "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", "\n", "from pydantic import Field\n", "from langchain.chains.qa_with_sources.loading import load_qa_with_sources_chain, BaseCombineDocumentsChain\n", "\n", "\"\"\"\n", "定义了一个名为_get_text_splitter()的函数,该函数返回一个RecursiveCharacterTextSplitter对象。\n", "这个对象是一个用于将文本分割成更小部分的工具。在函数中,我们设置了一些参数来控制分割的行为,例如块的大小、\n", "块之间的重叠大小以及指定长度函数。这些参数可以根据具体的需求进行调整。\n", "\"\"\"\n", "def _get_text_splitter():\n", " return RecursiveCharacterTextSplitter(\n", " chunk_size = 500,\n", " chunk_overlap = 20,\n", " length_function = len,\n", " )\n", "\n", "\"\"\"\n", "定义了一个名为WebpageQATool的类,该类继承自BaseTool类。在类中,我们定义了一些属性和方法,用于实现浏览网页并提取文本信息的功能。具体来说,\n", "我们定义了一个名为text_splitter的属性,用于存储文本分割器对象;定义了一个名为qa_chain的属性,用于存储qa链对象;实现了run方法和异步run方\n", "法,分别用于执行具体任务的逻辑。在run方法中,我们首先调用browse_web_page.run方法浏览网页并提取文本信息。然后,我们将提取到的文本信息存储\n", "在一个Document对象中,并使用text_splitter对象对其进行分割。最后,我们使用qa_chain对象对分割后的文档进行处理,并返回结果。在异步run方法\n", "中,我们同样调用browse_web_page.run方法浏览网页并提取文本信息。但是,由于异步操作需要等待任务完成才能继续执行下一步操作,因此我们需要在函\n", "数中使用await关键字来等待任务的完成。需要注意的是,目前在异步run方法中还存在一些未实现的功能。具体来说,我们在函数末尾使用了\n", "raise NotImplementedError语句,这表示尚未实现该方法。因此,在实际应用中,如果需要使用异步run方法,则需要先完成未实现的部分。\n", "\"\"\"\n", "class WebpageQATool(BaseTool):\n", " #定义类名和描述信息\n", " name = \"query_webpage\"\n", " description = \"Browse a webpage and retrieve the information relevant to the question.\"\n", " #定义一个名为text_splitter的属性,用于存储文本分割器对象\n", " text_splitter: RecursiveCharacterTextSplitter = Field(default_factory=_get_text_splitter)\n", " #定义一个名为qa_chain的属性,用于存储qa链对象\n", " qa_chain: BaseCombineDocumentsChain\n", "\n", " #实现run方法,用于执行具体任务的逻辑\n", " def _run(self, url: str, question: str) -> str:\n", " \"\"\"浏览网站并提取文本信息\"\"\"\n", " result = browse_web_page.run(url)\n", " docs = [Document(page_content=result, metadata={\"source\": url})]\n", " web_docs = self.text_splitter.split_documents(docs)\n", " results = []\n", " # TODO: 实现MapReduceChain的相关功能\n", " for i in range(0, len(web_docs), 4):\n", " input_docs = web_docs[i:i+4]\n", " window_result = self.qa_chain({\"input_documents\": input_docs, \"question\": question}, return_only_outputs=True)\n", " results.append(f\"Response from window {i} - {window_result}\")\n", " results_docs = [Document(page_content=\"\\n\".join(results), metadata={\"source\": url})]\n", " return self.qa_chain({\"input_documents\": results_docs, \"question\": question}, return_only_outputs=True)\n", " \n", " #实现异步run方法,用于执行具体任务的逻辑\n", " async def _arun(self, url: str, question: str) -> str:\n", " raise NotImplementedError\n", " " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "query_website_tool = WebpageQATool(qa_chain=load_qa_with_sources_chain(llm))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "import faiss\n", "from langchain.vectorstores import FAISS\n", "from langchain.docstore import InMemoryDocstore\n", "from langchain.embeddings import OpenAIEmbeddings\n", "from langchain.tools.human.tool import HumanInputRun\n", "\n", "embeddings_model = OpenAIEmbeddings()\n", "embedding_size = 1536\n", "index = faiss.IndexFlatL2(embedding_size)\n", "vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# !pip install duckduckgo_search\n", "web_search = DuckDuckGoSearchTool()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "tools = [\n", " web_search,\n", " WriteFileTool(root_dir=\"./data\"),\n", " ReadFileTool(root_dir=\"./data\"),\n", " process_csv,\n", " query_website_tool,\n", " # human_in_the_loop=True, # 如果要在每个步骤中添加反馈,请将其设置为True。\n", "]" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "agent = AutoGPT.from_llm_and_tools(\n", " ai_name=\"Tom\",\n", " ai_role=\"Assistant\",\n", " tools=tools,\n", " llm=llm,\n", " memory=vectorstore.as_retriever(search_kwargs={\"k\": 8}),\n", " # human_in_the_loop=True, # 如果要在每个步骤中添加反馈,请将其设置为True。\n", ")\n", "# agent.chain.verbose = True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "agent.run([\"What were the winning boston marathon times for the past 5 years (ending in 2022)? Generate a table of the year, name, country of origin, and times.\"])" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 🌹 上述内容来自于[LangChain官网教程](https://python.langchain.com/en/latest/index.html)并有适当的更改,如有商业化等行为我们会特别说明。该文档请勿随意转载,如有相关建议或者更改需求,请与[我们取得联系✉️](helloegoalpha@gmail.com),再次感谢!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.15" } }, "nbformat": 4, "nbformat_minor": 0 }