2.2 LangChain基础知识.md 2.html 169 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244
  1. <!doctype html>
  2. <html lang="zh" class="no-js">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1">
  6. <link rel="prev" href="2.1%20Ollama%E5%A4%A7%E6%A8%A1%E5%9E%8B%E9%AB%98%E6%95%88%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7.html">
  7. <link rel="next" href="2.3%20%E5%90%91%E9%87%8F%E7%B4%A2%E5%BC%95%EF%BC%9AHNSW%E3%80%81IVF%E4%B8%8EIVF_PQ.html">
  8. <link rel="icon" href="../img/AI.jpg">
  9. <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
  10. <title>2.2 LangChain基础知识.md - 企业知识库RAG智能问答项目V1.0</title>
  11. <link rel="stylesheet" href="../assets/stylesheets/main.2a3383ac.min.css">
  12. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  13. <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
  14. <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
  15. <link rel="stylesheet" href="../stylesheets/extra.css">
  16. <script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
  17. </head>
  18. <body dir="ltr">
  19. <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
  20. <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
  21. <label class="md-overlay" for="__drawer"></label>
  22. <div data-md-component="skip">
  23. <a href="#_1" class="md-skip">
  24. 跳转至
  25. </a>
  26. </div>
  27. <div data-md-component="announce">
  28. </div>
  29. <header class="md-header md-header--shadow" data-md-component="header">
  30. <nav class="md-header__inner md-grid" aria-label="页眉">
  31. <a href="../index.html" title="企业知识库RAG智能问答项目V1.0" class="md-header__button md-logo" aria-label="企业知识库RAG智能问答项目V1.0" data-md-component="logo">
  32. <img src="../img/AI.jpg" alt="logo">
  33. </a>
  34. <label class="md-header__button md-icon" for="__drawer">
  35. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
  36. </label>
  37. <div class="md-header__title" data-md-component="header-title">
  38. <div class="md-header__ellipsis">
  39. <div class="md-header__topic">
  40. <span class="md-ellipsis">
  41. 企业知识库RAG智能问答项目V1.0
  42. </span>
  43. </div>
  44. <div class="md-header__topic" data-md-component="header-topic">
  45. <span class="md-ellipsis">
  46. 2.2 LangChain基础知识.md
  47. </span>
  48. </div>
  49. </div>
  50. </div>
  51. <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
  52. <label class="md-header__button md-icon" for="__search">
  53. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
  54. </label>
  55. <div class="md-search" data-md-component="search" role="dialog">
  56. <label class="md-search__overlay" for="__search"></label>
  57. <div class="md-search__inner" role="search">
  58. <form class="md-search__form" name="search">
  59. <input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
  60. <label class="md-search__icon md-icon" for="__search">
  61. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
  62. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
  63. </label>
  64. <nav class="md-search__options" aria-label="查找">
  65. <button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
  66. <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
  67. </button>
  68. </nav>
  69. </form>
  70. <div class="md-search__output">
  71. <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
  72. <div class="md-search-result" data-md-component="search-result">
  73. <div class="md-search-result__meta">
  74. 正在初始化搜索引擎
  75. </div>
  76. <ol class="md-search-result__list" role="presentation"></ol>
  77. </div>
  78. </div>
  79. </div>
  80. </div>
  81. </div>
  82. </nav>
  83. </header>
  84. <div class="md-container" data-md-component="container">
  85. <main class="md-main" data-md-component="main">
  86. <div class="md-main__inner md-grid">
  87. <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
  88. <div class="md-sidebar__scrollwrap">
  89. <div class="md-sidebar__inner">
  90. <nav class="md-nav md-nav--primary" aria-label="导航栏" data-md-level="0">
  91. <label class="md-nav__title" for="__drawer">
  92. <a href="../index.html" title="企业知识库RAG智能问答项目V1.0" class="md-nav__button md-logo" aria-label="企业知识库RAG智能问答项目V1.0" data-md-component="logo">
  93. <img src="../img/AI.jpg" alt="logo">
  94. </a>
  95. 企业知识库RAG智能问答项目V1.0
  96. </label>
  97. <ul class="md-nav__list" data-md-scrollfix>
  98. <li class="md-nav__item">
  99. <a href="../index.html" class="md-nav__link">
  100. <span class="md-ellipsis">
  101. 知识库内容
  102. </span>
  103. </a>
  104. </li>
  105. <li class="md-nav__item md-nav__item--nested">
  106. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
  107. <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
  108. <span class="md-ellipsis">
  109. ① 项目概述
  110. </span>
  111. <span class="md-nav__icon md-icon"></span>
  112. </label>
  113. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
  114. <label class="md-nav__title" for="__nav_2">
  115. <span class="md-nav__icon md-icon"></span>
  116. ① 项目概述
  117. </label>
  118. <ul class="md-nav__list" data-md-scrollfix>
  119. <li class="md-nav__item">
  120. <a href="../%E2%91%A0%20%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%BF%B0/1.1%20%E9%A1%B9%E7%9B%AE%E6%9E%B6%E6%9E%84.html" class="md-nav__link">
  121. <span class="md-ellipsis">
  122. 1.1 项目架构
  123. </span>
  124. </a>
  125. </li>
  126. <li class="md-nav__item">
  127. <a href="../%E2%91%A0%20%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%BF%B0/1.2%20%E9%A1%B9%E7%9B%AE%E7%8E%AF%E5%A2%83%28window%29.html" class="md-nav__link">
  128. <span class="md-ellipsis">
  129. 1.2 项目环境(window)
  130. </span>
  131. </a>
  132. </li>
  133. <li class="md-nav__item">
  134. <a href="../%E2%91%A0%20%E9%A1%B9%E7%9B%AE%E6%A6%82%E8%BF%B0/1.3%20%E9%A1%B9%E7%9B%AE%E7%8E%AF%E5%A2%83%28mac%29.html" class="md-nav__link">
  135. <span class="md-ellipsis">
  136. 1.3 项目环境(mac)
  137. </span>
  138. </a>
  139. </li>
  140. </ul>
  141. </nav>
  142. </li>
  143. <li class="md-nav__item md-nav__item--active md-nav__item--nested">
  144. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
  145. <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
  146. <span class="md-ellipsis">
  147. ② 项目工具
  148. </span>
  149. <span class="md-nav__icon md-icon"></span>
  150. </label>
  151. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
  152. <label class="md-nav__title" for="__nav_3">
  153. <span class="md-nav__icon md-icon"></span>
  154. ② 项目工具
  155. </label>
  156. <ul class="md-nav__list" data-md-scrollfix>
  157. <li class="md-nav__item">
  158. <a href="2.1%20Ollama%E5%A4%A7%E6%A8%A1%E5%9E%8B%E9%AB%98%E6%95%88%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7.html" class="md-nav__link">
  159. <span class="md-ellipsis">
  160. 2.1 Ollama大模型高效管理工具
  161. </span>
  162. </a>
  163. </li>
  164. <li class="md-nav__item md-nav__item--active">
  165. <a href="2.2%20LangChain%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md.html" class="md-nav__link md-nav__link--active">
  166. <span class="md-ellipsis">
  167. 2.2 LangChain基础知识.md
  168. </span>
  169. </a>
  170. </li>
  171. <li class="md-nav__item">
  172. <a href="2.3%20%E5%90%91%E9%87%8F%E7%B4%A2%E5%BC%95%EF%BC%9AHNSW%E3%80%81IVF%E4%B8%8EIVF_PQ.html" class="md-nav__link">
  173. <span class="md-ellipsis">
  174. 2.3 向量索引:HNSW、IVF与IVF_PQ
  175. </span>
  176. </a>
  177. </li>
  178. <li class="md-nav__item">
  179. <a href="2.4%20Milvus%E5%90%91%E9%87%8F%E6%95%B0%E6%8D%AE%E5%BA%93.html" class="md-nav__link">
  180. <span class="md-ellipsis">
  181. 2.4 Milvus向量数据库
  182. </span>
  183. </a>
  184. </li>
  185. </ul>
  186. </nav>
  187. </li>
  188. <li class="md-nav__item md-nav__item--nested">
  189. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
  190. <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
  191. <span class="md-ellipsis">
  192. ③ 基于Mysql库的问答系统
  193. </span>
  194. <span class="md-nav__icon md-icon"></span>
  195. </label>
  196. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
  197. <label class="md-nav__title" for="__nav_4">
  198. <span class="md-nav__icon md-icon"></span>
  199. ③ 基于Mysql库的问答系统
  200. </label>
  201. <ul class="md-nav__list" data-md-scrollfix>
  202. <li class="md-nav__item">
  203. <a href="../%E2%91%A2%20%E5%9F%BA%E4%BA%8EMysql%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/3.1%20Python%E6%97%A5%E5%BF%97%E4%BB%8B%E7%BB%8D%E4%B8%8E%E5%BA%94%E7%94%A8.html" class="md-nav__link">
  204. <span class="md-ellipsis">
  205. 3.1 Python日志介绍与应用
  206. </span>
  207. </a>
  208. </li>
  209. <li class="md-nav__item">
  210. <a href="../%E2%91%A2%20%E5%9F%BA%E4%BA%8EMysql%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/3.2%20Redis%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%80%E4%BB%8B%E4%B8%8E%E4%BD%BF%E7%94%A8.html" class="md-nav__link">
  211. <span class="md-ellipsis">
  212. 3.2 Redis数据库简介与使用
  213. </span>
  214. </a>
  215. </li>
  216. <li class="md-nav__item">
  217. <a href="../%E2%91%A2%20%E5%9F%BA%E4%BA%8EMysql%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/3.3%20%E5%9F%BA%E4%BA%8EMysql%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%9E%E7%8E%B0%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F.html" class="md-nav__link">
  218. <span class="md-ellipsis">
  219. 3.3 基于Mysql数据库实现问答系统
  220. </span>
  221. </a>
  222. </li>
  223. <li class="md-nav__item">
  224. <a href="../%E2%91%A2%20%E5%9F%BA%E4%BA%8EMysql%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/3.4%20BM25%E7%AE%97%E6%B3%95%E7%AE%80%E4%BB%8B%E4%B8%8E%E5%BA%94%E7%94%A8.html" class="md-nav__link">
  225. <span class="md-ellipsis">
  226. 3.4 BM25算法简介与应用
  227. </span>
  228. </a>
  229. </li>
  230. </ul>
  231. </nav>
  232. </li>
  233. <li class="md-nav__item md-nav__item--nested">
  234. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
  235. <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
  236. <span class="md-ellipsis">
  237. ④ 基于Milvus库的问答系统
  238. </span>
  239. <span class="md-nav__icon md-icon"></span>
  240. </label>
  241. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
  242. <label class="md-nav__title" for="__nav_5">
  243. <span class="md-nav__icon md-icon"></span>
  244. ④ 基于Milvus库的问答系统
  245. </label>
  246. <ul class="md-nav__list" data-md-scrollfix>
  247. <li class="md-nav__item">
  248. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.1%20%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84%E4%B8%8E%E5%B7%A5%E7%A8%8B%E6%B5%81%E7%A8%8B.html" class="md-nav__link">
  249. <span class="md-ellipsis">
  250. 4.1 整体架构与工程流程
  251. </span>
  252. </a>
  253. </li>
  254. <li class="md-nav__item">
  255. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.2%20%E5%9F%BA%E7%A1%80%E6%A8%A1%E5%9D%97.html" class="md-nav__link">
  256. <span class="md-ellipsis">
  257. 4.2 基础模块
  258. </span>
  259. </a>
  260. </li>
  261. <li class="md-nav__item">
  262. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.3%20%E6%96%87%E6%A1%A3%E5%A4%84%E7%90%86%E6%A8%A1%E5%9D%97.html" class="md-nav__link">
  263. <span class="md-ellipsis">
  264. 4.3 文档处理模块
  265. </span>
  266. </a>
  267. </li>
  268. <li class="md-nav__item">
  269. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.4%20%E5%90%91%E9%87%8F%E5%AD%98%E5%82%A8.html" class="md-nav__link">
  270. <span class="md-ellipsis">
  271. 4.4 向量存储
  272. </span>
  273. </a>
  274. </li>
  275. <li class="md-nav__item">
  276. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.5%20prompts%E8%AE%BE%E8%AE%A1%E4%B8%8Equery%E6%84%8F%E5%9B%BE%E8%AF%86%E5%88%AB.html" class="md-nav__link">
  277. <span class="md-ellipsis">
  278. 4.5 prompts设计与query意图识别
  279. </span>
  280. </a>
  281. </li>
  282. <li class="md-nav__item">
  283. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.6%20%E6%A3%80%E7%B4%A2%E7%AD%96%E7%95%A5%E4%B8%8ERAG%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1.html" class="md-nav__link">
  284. <span class="md-ellipsis">
  285. 4.6 检索策略与RAG系统设计
  286. </span>
  287. </a>
  288. </li>
  289. <li class="md-nav__item">
  290. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.7%20RAG%E7%B3%BB%E7%BB%9F%E8%BF%90%E8%A1%8C.html" class="md-nav__link">
  291. <span class="md-ellipsis">
  292. 4.7 RAG系统运行
  293. </span>
  294. </a>
  295. </li>
  296. <li class="md-nav__item">
  297. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.8%20%E6%96%87%E6%A1%A3%E8%A7%A3%E6%9E%90%E5%B7%A5%E5%85%B7%28%E6%89%A9%E5%B1%95%E8%B5%84%E6%96%99%29.html" class="md-nav__link">
  298. <span class="md-ellipsis">
  299. 4.8 文档解析工具(扩展资料)
  300. </span>
  301. </a>
  302. </li>
  303. <li class="md-nav__item">
  304. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/4.9%20RAG%E4%B8%AD%E7%9A%84Query%E6%94%B9%E5%86%99%28%E6%89%A9%E5%B1%95%E8%B5%84%E6%96%99%29.html" class="md-nav__link">
  305. <span class="md-ellipsis">
  306. 4.9 RAG中的Query改写(扩展资料)
  307. </span>
  308. </a>
  309. </li>
  310. <li class="md-nav__item">
  311. <a href="../%E2%91%A3%20%E5%9F%BA%E4%BA%8EMilvus%E5%BA%93%E7%9A%84%E9%97%AE%E7%AD%94%E7%B3%BB%E7%BB%9F/%E6%95%B0%E6%8D%AE%E9%9B%86%E7%94%9F%E6%88%90%E4%B8%8E%E4%BC%98%E5%8C%96%28%E6%89%A9%E5%B1%95%E8%B5%84%E6%96%99%29.html" class="md-nav__link">
  312. <span class="md-ellipsis">
  313. 数据集生成与优化(扩展资料)
  314. </span>
  315. </a>
  316. </li>
  317. </ul>
  318. </nav>
  319. </li>
  320. <li class="md-nav__item md-nav__item--nested">
  321. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
  322. <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
  323. <span class="md-ellipsis">
  324. ⑤ RAG系统评估
  325. </span>
  326. <span class="md-nav__icon md-icon"></span>
  327. </label>
  328. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
  329. <label class="md-nav__title" for="__nav_6">
  330. <span class="md-nav__icon md-icon"></span>
  331. ⑤ RAG系统评估
  332. </label>
  333. <ul class="md-nav__list" data-md-scrollfix>
  334. <li class="md-nav__item">
  335. <a href="../%E2%91%A4%20RAG%E7%B3%BB%E7%BB%9F%E8%AF%84%E4%BC%B0/5.1%20RAG%E7%B3%BB%E7%BB%9F%E8%AF%84%E4%BC%B0%E5%B7%A5%E5%85%B7.html" class="md-nav__link">
  336. <span class="md-ellipsis">
  337. 5.1 RAG系统评估工具
  338. </span>
  339. </a>
  340. </li>
  341. <li class="md-nav__item">
  342. <a href="../%E2%91%A4%20RAG%E7%B3%BB%E7%BB%9F%E8%AF%84%E4%BC%B0/5.2%20%E5%AE%9E%E7%8E%B0EnterpriseKB-RAG%E7%B3%BB%E7%BB%9F%E7%9A%84%E8%AF%84%E4%BC%B0.html" class="md-nav__link">
  343. <span class="md-ellipsis">
  344. 5.2 实现企业知识库RAG系统的评估
  345. </span>
  346. </a>
  347. </li>
  348. <li class="md-nav__item">
  349. <a href="../%E2%91%A4%20RAG%E7%B3%BB%E7%BB%9F%E8%AF%84%E4%BC%B0/5.3%20RAG%E8%AF%84%E4%BC%B0%E6%95%B0%E6%8D%AE%E9%9B%86%E7%9A%84%E6%9E%84%E9%80%A0%28%E6%89%A9%E5%B1%95%29.html" class="md-nav__link">
  350. <span class="md-ellipsis">
  351. 5.3 RAG评估数据集的构造(扩展)
  352. </span>
  353. </a>
  354. </li>
  355. </ul>
  356. </nav>
  357. </li>
  358. <li class="md-nav__item md-nav__item--nested">
  359. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7" >
  360. <label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
  361. <span class="md-ellipsis">
  362. ⑥ 融合Mysql的RAG系统
  363. </span>
  364. <span class="md-nav__icon md-icon"></span>
  365. </label>
  366. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
  367. <label class="md-nav__title" for="__nav_7">
  368. <span class="md-nav__icon md-icon"></span>
  369. ⑥ 融合Mysql的RAG系统
  370. </label>
  371. <ul class="md-nav__list" data-md-scrollfix>
  372. <li class="md-nav__item">
  373. <a href="../%E2%91%A5%20%E8%9E%8D%E5%90%88Mysql%E7%9A%84RAG%E7%B3%BB%E7%BB%9F/6.1%20%E8%9E%8D%E5%90%88FQA%E5%92%8C%E7%9F%A5%E8%AF%86%E5%BA%93%E6%9F%A5%E8%AF%A2.html" class="md-nav__link">
  374. <span class="md-ellipsis">
  375. 6.1 融合FQA和知识库查询
  376. </span>
  377. </a>
  378. </li>
  379. <li class="md-nav__item">
  380. <a href="../%E2%91%A5%20%E8%9E%8D%E5%90%88Mysql%E7%9A%84RAG%E7%B3%BB%E7%BB%9F/6.2%20%E8%9E%8D%E5%90%88FAQ%20%E5%92%8C%E7%9F%A5%E8%AF%86%E5%BA%93%E6%9F%A5%E8%AF%A2%EF%BC%88%E4%BC%98%E5%8C%96%E7%89%88%EF%BC%89.html" class="md-nav__link">
  381. <span class="md-ellipsis">
  382. 6.2 融合FAQ 和知识库查询(优化版)
  383. </span>
  384. </a>
  385. </li>
  386. <li class="md-nav__item">
  387. <a href="../%E2%91%A5%20%E8%9E%8D%E5%90%88Mysql%E7%9A%84RAG%E7%B3%BB%E7%BB%9F/6.3%20%E5%9F%BA%E4%BA%8E%20FastAPI%20%E7%9A%84%20FAQ%20%E4%B8%8E%E7%9F%A5%E8%AF%86%E5%BA%93%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3.html" class="md-nav__link">
  388. <span class="md-ellipsis">
  389. 6.3 基于 FastAPI 的 FAQ 与知识库查询接口
  390. </span>
  391. </a>
  392. </li>
  393. <li class="md-nav__item">
  394. <a href="../%E2%91%A5%20%E8%9E%8D%E5%90%88Mysql%E7%9A%84RAG%E7%B3%BB%E7%BB%9F/6.4%20FastAPI%E5%92%8CFlask%E7%9A%84%E5%8C%BA%E5%88%AB%E5%92%8C%E8%81%94%E7%B3%BB%28%E6%89%A9%E5%B1%95%E8%B5%84%E6%96%99%29.html" class="md-nav__link">
  395. <span class="md-ellipsis">
  396. 6.4 FastAPI和Flask的区别和联系(扩展资料)
  397. </span>
  398. </a>
  399. </li>
  400. </ul>
  401. </nav>
  402. </li>
  403. <li class="md-nav__item md-nav__item--nested">
  404. <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8" >
  405. <label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
  406. <span class="md-ellipsis">
  407. ⑦ 企业级生产环境部署
  408. </span>
  409. <span class="md-nav__icon md-icon"></span>
  410. </label>
  411. <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
  412. <label class="md-nav__title" for="__nav_8">
  413. <span class="md-nav__icon md-icon"></span>
  414. ⑦ 企业级生产环境部署
  415. </label>
  416. <ul class="md-nav__list" data-md-scrollfix>
  417. <li class="md-nav__item">
  418. <a href="../%E2%91%A6%20%E4%BC%81%E4%B8%9A%E7%BA%A7%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E9%83%A8%E7%BD%B2/7.1%20Docker%E7%9A%84%E5%8E%9F%E7%90%86%E5%92%8C%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8.html" class="md-nav__link">
  419. <span class="md-ellipsis">
  420. 7.1 Docker的原理和基本使用
  421. </span>
  422. </a>
  423. </li>
  424. <li class="md-nav__item">
  425. <a href="../%E2%91%A6%20%E4%BC%81%E4%B8%9A%E7%BA%A7%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E9%83%A8%E7%BD%B2/7.2%20%E6%9C%8D%E5%8A%A1%E9%83%A8%E7%BD%B2.html" class="md-nav__link">
  426. <span class="md-ellipsis">
  427. 7.2 服务部署
  428. </span>
  429. </a>
  430. </li>
  431. </ul>
  432. </nav>
  433. </li>
  434. </ul>
  435. </nav>
  436. </div>
  437. </div>
  438. </div>
  439. <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
  440. <div class="md-sidebar__scrollwrap">
  441. <div class="md-sidebar__inner">
  442. <nav class="md-nav md-nav--secondary" aria-label="目录">
  443. <label class="md-nav__title" for="__toc">
  444. <span class="md-nav__icon md-icon"></span>
  445. 目录
  446. </label>
  447. <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
  448. <li class="md-nav__item">
  449. <a href="#_1" class="md-nav__link">
  450. <span class="md-ellipsis">
  451. 学习目标
  452. </span>
  453. </a>
  454. </li>
  455. <li class="md-nav__item">
  456. <a href="#_2" class="md-nav__link">
  457. <span class="md-ellipsis">
  458. 一、简述
  459. </span>
  460. </a>
  461. <nav class="md-nav" aria-label="一、简述">
  462. <ul class="md-nav__list">
  463. <li class="md-nav__item">
  464. <a href="#1-langchain" class="md-nav__link">
  465. <span class="md-ellipsis">
  466. 1 什么是LangChain
  467. </span>
  468. </a>
  469. </li>
  470. <li class="md-nav__item">
  471. <a href="#2" class="md-nav__link">
  472. <span class="md-ellipsis">
  473. 2 主要组件
  474. </span>
  475. </a>
  476. </li>
  477. <li class="md-nav__item">
  478. <a href="#3-langchain" class="md-nav__link">
  479. <span class="md-ellipsis">
  480. 3 LangChain核心包
  481. </span>
  482. </a>
  483. </li>
  484. <li class="md-nav__item">
  485. <a href="#4" class="md-nav__link">
  486. <span class="md-ellipsis">
  487. 4 环境准备
  488. </span>
  489. </a>
  490. </li>
  491. </ul>
  492. </nav>
  493. </li>
  494. <li class="md-nav__item">
  495. <a href="#models" class="md-nav__link">
  496. <span class="md-ellipsis">
  497. 二、Models
  498. </span>
  499. </a>
  500. <nav class="md-nav" aria-label="二、Models">
  501. <ul class="md-nav__list">
  502. <li class="md-nav__item">
  503. <a href="#1-llms" class="md-nav__link">
  504. <span class="md-ellipsis">
  505. 1 LLMs
  506. </span>
  507. </a>
  508. </li>
  509. <li class="md-nav__item">
  510. <a href="#2-chat-models" class="md-nav__link">
  511. <span class="md-ellipsis">
  512. 2 Chat Models
  513. </span>
  514. </a>
  515. </li>
  516. <li class="md-nav__item">
  517. <a href="#3-embeddings-models" class="md-nav__link">
  518. <span class="md-ellipsis">
  519. 3 Embeddings Models
  520. </span>
  521. </a>
  522. </li>
  523. </ul>
  524. </nav>
  525. </li>
  526. <li class="md-nav__item">
  527. <a href="#prompts" class="md-nav__link">
  528. <span class="md-ellipsis">
  529. 三、Prompts
  530. </span>
  531. </a>
  532. <nav class="md-nav" aria-label="三、Prompts">
  533. <ul class="md-nav__list">
  534. <li class="md-nav__item">
  535. <a href="#1-prompt" class="md-nav__link">
  536. <span class="md-ellipsis">
  537. 1 通用prompt
  538. </span>
  539. </a>
  540. </li>
  541. <li class="md-nav__item">
  542. <a href="#2-chatprompts" class="md-nav__link">
  543. <span class="md-ellipsis">
  544. 2 ChatPrompts
  545. </span>
  546. </a>
  547. </li>
  548. </ul>
  549. </nav>
  550. </li>
  551. <li class="md-nav__item">
  552. <a href="#chains" class="md-nav__link">
  553. <span class="md-ellipsis">
  554. 四、Chains
  555. </span>
  556. </a>
  557. </li>
  558. <li class="md-nav__item">
  559. <a href="#output_parsers" class="md-nav__link">
  560. <span class="md-ellipsis">
  561. 五、output_parsers
  562. </span>
  563. </a>
  564. <nav class="md-nav" aria-label="五、output_parsers">
  565. <ul class="md-nav__list">
  566. <li class="md-nav__item">
  567. <a href="#1" class="md-nav__link">
  568. <span class="md-ellipsis">
  569. 1 字符串解析器
  570. </span>
  571. </a>
  572. </li>
  573. <li class="md-nav__item">
  574. <a href="#2_1" class="md-nav__link">
  575. <span class="md-ellipsis">
  576. 2 列表解析器
  577. </span>
  578. </a>
  579. </li>
  580. <li class="md-nav__item">
  581. <a href="#3-json" class="md-nav__link">
  582. <span class="md-ellipsis">
  583. 3 JSON解析器
  584. </span>
  585. </a>
  586. </li>
  587. <li class="md-nav__item">
  588. <a href="#4-pydantic" class="md-nav__link">
  589. <span class="md-ellipsis">
  590. 4 Pydantic解析器
  591. </span>
  592. </a>
  593. </li>
  594. <li class="md-nav__item">
  595. <a href="#5" class="md-nav__link">
  596. <span class="md-ellipsis">
  597. 5 自定义解析器
  598. </span>
  599. </a>
  600. </li>
  601. </ul>
  602. </nav>
  603. </li>
  604. <li class="md-nav__item">
  605. <a href="#memory" class="md-nav__link">
  606. <span class="md-ellipsis">
  607. 六、Memory
  608. </span>
  609. </a>
  610. <nav class="md-nav" aria-label="六、Memory">
  611. <ul class="md-nav__list">
  612. <li class="md-nav__item">
  613. <a href="#1-short-term-memory" class="md-nav__link">
  614. <span class="md-ellipsis">
  615. 1 短期记忆(Short-term Memory)
  616. </span>
  617. </a>
  618. </li>
  619. <li class="md-nav__item">
  620. <a href="#2_2" class="md-nav__link">
  621. <span class="md-ellipsis">
  622. 2 长期记忆
  623. </span>
  624. </a>
  625. </li>
  626. </ul>
  627. </nav>
  628. </li>
  629. <li class="md-nav__item">
  630. <a href="#indexes" class="md-nav__link">
  631. <span class="md-ellipsis">
  632. 七、Indexes
  633. </span>
  634. </a>
  635. <nav class="md-nav" aria-label="七、Indexes">
  636. <ul class="md-nav__list">
  637. <li class="md-nav__item">
  638. <a href="#1_1" class="md-nav__link">
  639. <span class="md-ellipsis">
  640. 1 文档加载器
  641. </span>
  642. </a>
  643. </li>
  644. <li class="md-nav__item">
  645. <a href="#2_3" class="md-nav__link">
  646. <span class="md-ellipsis">
  647. 2 文档分割器
  648. </span>
  649. </a>
  650. </li>
  651. <li class="md-nav__item">
  652. <a href="#3-vectorstores" class="md-nav__link">
  653. <span class="md-ellipsis">
  654. 3 VectorStores
  655. </span>
  656. </a>
  657. </li>
  658. <li class="md-nav__item">
  659. <a href="#4_1" class="md-nav__link">
  660. <span class="md-ellipsis">
  661. 4 检索器
  662. </span>
  663. </a>
  664. <nav class="md-nav" aria-label="4 检索器">
  665. <ul class="md-nav__list">
  666. <li class="md-nav__item">
  667. <a href="#41-langchain" class="md-nav__link">
  668. <span class="md-ellipsis">
  669. 4.1 LangChain的检索器定义
  670. </span>
  671. </a>
  672. </li>
  673. <li class="md-nav__item">
  674. <a href="#42" class="md-nav__link">
  675. <span class="md-ellipsis">
  676. 4.2 检索器的工作原理
  677. </span>
  678. </a>
  679. </li>
  680. <li class="md-nav__item">
  681. <a href="#43" class="md-nav__link">
  682. <span class="md-ellipsis">
  683. 4.3 检索器类型
  684. </span>
  685. </a>
  686. </li>
  687. <li class="md-nav__item">
  688. <a href="#44" class="md-nav__link">
  689. <span class="md-ellipsis">
  690. 4.4 拓展
  691. </span>
  692. </a>
  693. </li>
  694. </ul>
  695. </nav>
  696. </li>
  697. </ul>
  698. </nav>
  699. </li>
  700. <li class="md-nav__item">
  701. <a href="#agents" class="md-nav__link">
  702. <span class="md-ellipsis">
  703. 八、Agents
  704. </span>
  705. </a>
  706. <nav class="md-nav" aria-label="八、Agents">
  707. <ul class="md-nav__list">
  708. <li class="md-nav__item">
  709. <a href="#1-agent" class="md-nav__link">
  710. <span class="md-ellipsis">
  711. 1 Agent 概念
  712. </span>
  713. </a>
  714. </li>
  715. <li class="md-nav__item">
  716. <a href="#2-agent" class="md-nav__link">
  717. <span class="md-ellipsis">
  718. 2 Agent关键组成部分
  719. </span>
  720. </a>
  721. </li>
  722. <li class="md-nav__item">
  723. <a href="#3-langchainagent" class="md-nav__link">
  724. <span class="md-ellipsis">
  725. 3 langchain实现Agent
  726. </span>
  727. </a>
  728. </li>
  729. </ul>
  730. </nav>
  731. </li>
  732. <li class="md-nav__item">
  733. <a href="#langchain" class="md-nav__link">
  734. <span class="md-ellipsis">
  735. 九、LangChain使用场景
  736. </span>
  737. </a>
  738. </li>
  739. <li class="md-nav__item">
  740. <a href="#_3" class="md-nav__link">
  741. <span class="md-ellipsis">
  742. 十、本节小结
  743. </span>
  744. </a>
  745. </li>
  746. <li class="md-nav__item">
  747. <a href="#_4" class="md-nav__link">
  748. <span class="md-ellipsis">
  749. 十一、本节作业
  750. </span>
  751. </a>
  752. <nav class="md-nav" aria-label="十一、本节作业">
  753. <ul class="md-nav__list">
  754. <li class="md-nav__item">
  755. <a href="#1-1" class="md-nav__link">
  756. <span class="md-ellipsis">
  757. 1 作业1
  758. </span>
  759. </a>
  760. </li>
  761. <li class="md-nav__item">
  762. <a href="#2-2" class="md-nav__link">
  763. <span class="md-ellipsis">
  764. 2 作业2
  765. </span>
  766. </a>
  767. </li>
  768. </ul>
  769. </nav>
  770. </li>
  771. </ul>
  772. </nav>
  773. </div>
  774. </div>
  775. </div>
  776. <div class="md-content" data-md-component="content">
  777. <article class="md-content__inner md-typeset">
  778. <h1>2.2 LangChain基础知识.md</h1>
  779. <h2 id="_1">学习目标<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h2>
  780. <ul>
  781. <li>熟悉什么是LangChain及其作用</li>
  782. <li>熟悉LangChain中基本组件及使用</li>
  783. </ul>
  784. <h2 id="_2">一、简述<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h2>
  785. <h3 id="1-langchain">1 什么是LangChain<a class="headerlink" href="#1-langchain" title="Permanent link">&para;</a></h3>
  786. <p>LangChain由 Harrison Chase 创建于2022年10月,它是围绕LLMs(大语言模型)建立的一个框架,它的核心理念是为各种LLMs实现通用的接口,把LLMs相关的组件“链接”在一起,简化LLMs应用的开发难度,方便开发者快速地开发复杂的LLMs应用。</p>
  787. <blockquote>
  788. <p>LangChain 最初是于 2022 年 10 月开源的一个项目,在 GitHub 上获得大量关注之后迅速转变为一家初创公司。2017 年 Harrison Chase 还在哈佛上大学,如今已是硅谷的一家热门初创公司的 CEO,这对他来说是一次重大而迅速的跃迁。Insider 独家报道,人工智能初创公司 LangChain 在种子轮一周后,再次获得红杉领投的 2000 万至 2500 万美元融资,估值达到 2 亿美元。</p>
  789. </blockquote>
  790. <p><strong>LangChain官网</strong>:<a href="https://python.langchain.com/docs/introduction/">https://python.langchain.com/docs/introduction/</a></p>
  791. <p><strong>LangChain官网中文版</strong>:<a href="https://www.langchain.com.cn/">https://www.langchain.com.cn/</a></p>
  792. <p>LangChain 简化了 LLM 应用程序生命周期的每个阶段:</p>
  793. <ul>
  794. <li>开发:使用 LangChain 的开源组件和第三方集成构建应用程序。使用 LangGraph 构建具有一流流式和人机交互支持的状态智能体。</li>
  795. <li>生产化:使用 LangSmith 检查、监控和评估应用程序,方便持续优化和部署。</li>
  796. <li>部署:使用 LangGraph平台 将应用程序转变为可用于生产的 API 和助手。</li>
  797. </ul>
  798. <h3 id="2">2 主要组件<a class="headerlink" href="#2" title="Permanent link">&para;</a></h3>
  799. <p><img alt="image-20250703152303288" src="assets/image-20250703152303288.png" /></p>
  800. <ul>
  801. <li>Models:模型,各种类型的模型和模型集成,比如GPT-4</li>
  802. <li>Prompts:提示,包括提示管理、提示优化和提示序列化</li>
  803. <li>Chains:链,一系列对各种组件的调用</li>
  804. <li>Memory:记忆,用来保存和模型交互时的上下文状态</li>
  805. <li>Indexes:索引,用来结构化文档,以便和模型交互</li>
  806. <li>Agents:代理,决定模型采取哪些行动,执行并且观察流程,直到完成为止</li>
  807. </ul>
  808. <h3 id="3-langchain">3 LangChain核心包<a class="headerlink" href="#3-langchain" title="Permanent link">&para;</a></h3>
  809. <ul>
  810. <li><strong>langchain-core</strong>:聊天模型和其他组件的基础抽象。</li>
  811. <li>
  812. <p><strong>集成包(例如 langchain-openai、langchain-anthropic 等)</strong>:重要的集成被拆分为轻量级的独立包,由 LangChain 团队和集成方共同维护。</p>
  813. </li>
  814. <li>
  815. <p><strong>langchain</strong>:包含链(chains)、智能体(agents)和检索策略,这些构成了应用的认知架构。</p>
  816. </li>
  817. <li>
  818. <p><strong>langchain-community</strong>:由社区维护的第三方集成。</p>
  819. </li>
  820. <li>
  821. <p><strong>langgraph</strong>:一个编排框架,用于将 LangChain 组件组合成可用于生产的应用,支持持久化、流式处理及其他关键特性。</p>
  822. </li>
  823. </ul>
  824. <h3 id="4">4 环境准备<a class="headerlink" href="#4" title="Permanent link">&para;</a></h3>
  825. <p>本知识文档以LangChain+Qwen进行学习,需要提前安装</p>
  826. <blockquote>
  827. <p>pip install openai</p>
  828. <p>pip install langchain </p>
  829. <p>pip install modelscope</p>
  830. </blockquote>
  831. <p>借助阿里云-百炼平台(需要申请API Key 以及Secret Key):</p>
  832. <blockquote>
  833. <p><a href="https://bailian.console.aliyun.com/#/home">https://bailian.console.aliyun.com/#/home</a></p>
  834. </blockquote>
  835. <h2 id="models">二、Models<a class="headerlink" href="#models" title="Permanent link">&para;</a></h2>
  836. <p>现在市面上的模型多如牛毛,各种各样的模型不断出现,LangChain模型组件提供了与各种模型的集成,并为所有模型提供一个精简的统一接口。</p>
  837. <p>LangChain目前支持三种类型的模型:LLMs、Chat Models(聊天模型)、Embeddings Models(嵌入模型)。</p>
  838. <ul>
  839. <li>LLMs:大语言模型接收文本字符作为输入,返回的也是文本字符。</li>
  840. <li>聊天模型:基于LLMs, 不同的是它接收聊天消(一种特定格式的数据)作为输入,返回的也是聊天消息。</li>
  841. <li>文本嵌入模型:文本嵌入模型接收文本作为输入, 返回的是浮点数列表。</li>
  842. </ul>
  843. <p><img alt="image-20250704171332127" src="assets/image-20250704171332127.png" /></p>
  844. <p>LangChain支持的三类模型,它们的使用场景不同,输入和输出不同,开发者需要根据项目需要选择相应的模型。</p>
  845. <h3 id="1-llms">1 LLMs<a class="headerlink" href="#1-llms" title="Permanent link">&para;</a></h3>
  846. <p>LLMs(大语言模型)使用场景最多,常用大模型的下载库:</p>
  847. <blockquote>
  848. <p><a href="https://huggingface.co/models">https://huggingface.co/models</a></p>
  849. <p><a href="https://modelscope.cn/models">https://modelscope.cn/models</a></p>
  850. </blockquote>
  851. <p>下面Qwen为例进行讲解。</p>
  852. <hr />
  853. <p>模型调用有2种方式:</p>
  854. <ul>
  855. <li>通过ChatOpenAI进行调用</li>
  856. </ul>
  857. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatOpenAI</span>
  858. <span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
  859. <span class="c1"># 实例化模型</span>
  860. <span class="n">model</span> <span class="o">=</span> <span class="n">ChatOpenAI</span><span class="p">(</span>
  861. <span class="n">base_url</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;base_url&#39;</span><span class="p">,</span><span class="s1">&#39;https://dashscope.aliyuncs.com/compatible-mode/v1&#39;</span><span class="p">),</span>
  862. <span class="n">model</span><span class="o">=</span><span class="s1">&#39;qwen-plus&#39;</span><span class="p">,</span>
  863. <span class="n">openai_api_key</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;api_key&#39;</span><span class="p">,</span><span class="s1">&#39;sk-XXXXXX&#39;</span><span class="p">),</span>
  864. <span class="n">max_tokens</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
  865. <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span>
  866. <span class="p">)</span>
  867. <span class="c1"># 获取问答结果</span>
  868. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;帮我讲个笑话吧&quot;</span><span class="p">)</span>
  869. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
  870. </code></pre></div>
  871. <ul>
  872. <li>通过Ollama进行调用 <a href="https://ollama.com/">Ollama支持模型</a></li>
  873. </ul>
  874. <div class="highlight"><pre><span></span><code><span class="c1"># from langchain_community.llms import Ollama # Langchain 0.x版本使用</span>
  875. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  876. <span class="c1"># 实例化模型</span>
  877. <span class="c1"># model = Ollama(model=&quot;qwen2.5:7b&quot;) # Langchain 0.x版本使用</span>
  878. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  879. <span class="c1"># 获取问答结果</span>
  880. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;请给我讲个笑话吧&quot;</span><span class="p">)</span>
  881. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
  882. </code></pre></div>
  883. <h3 id="2-chat-models">2 Chat Models<a class="headerlink" href="#2-chat-models" title="Permanent link">&para;</a></h3>
  884. <p>聊天模型,聊天消息包含下面几种类型,使用时需要按照约定传入合适的值:</p>
  885. <ul>
  886. <li>
  887. <p><strong>AIMessage</strong>: 就是 AI 输出的消息,可以是针对问题的回答.</p>
  888. </li>
  889. <li>
  890. <p><strong>HumanMessage</strong>: 人类消息就是用户信息,由人给出的信息发送给LLMs的提示信息,比如“实现一个快速排序方法”.</p>
  891. </li>
  892. <li>
  893. <p><strong>SystemMessage</strong>: 可以用于指定模型具体所处的环境和背景,如角色扮演等。你可以在这里给出具体的指示,比如“作为一个代码专家”,或者“返回json格式”.</p>
  894. </li>
  895. <li>
  896. <p><strong>ChatMessage</strong>: Chat 消息可以接受任意角色的参数,但是在大多数时间,我们应该使用上面的三种类型.</p>
  897. </li>
  898. </ul>
  899. <p>LangChain支持大量的chat 模型,可以通过官网查询:</p>
  900. <blockquote>
  901. <p><a href="https://python.langchain.com/docs/integrations/chat/">https://python.langchain.com/docs/integrations/chat/</a></p>
  902. </blockquote>
  903. <p>也可以通过langchain源码查看</p>
  904. <p><img alt="image-20250704174858064" src="assets/image-20250704174858064.png" /></p>
  905. <ul>
  906. <li>SystemMessage+HumanMessage+AIMessage</li>
  907. </ul>
  908. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.messages</span><span class="w"> </span><span class="kn">import</span> <span class="n">HumanMessage</span><span class="p">,</span> <span class="n">SystemMessage</span><span class="p">,</span> <span class="n">AIMessage</span>
  909. <span class="c1"># from langchain_community.chat_models import ChatOllama # Langchain 0.x版本使用</span>
  910. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatOllama</span>
  911. <span class="c1"># 实例化模型</span>
  912. <span class="n">model</span> <span class="o">=</span> <span class="n">ChatOllama</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  913. <span class="c1"># 定义提示词</span>
  914. <span class="n">messages</span> <span class="o">=</span> <span class="p">[</span>
  915. <span class="n">SystemMessage</span><span class="p">(</span><span class="n">content</span><span class="o">=</span><span class="s2">&quot;现在你是一个著名的诗人&quot;</span><span class="p">),</span>
  916. <span class="n">HumanMessage</span><span class="p">(</span><span class="n">content</span><span class="o">=</span><span class="s2">&quot;给我写一首唐诗&quot;</span><span class="p">)]</span>
  917. <span class="c1"># 获取问答结果</span>
  918. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">messages</span><span class="p">)</span>
  919. <span class="c1"># print(result)</span>
  920. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
  921. </code></pre></div>
  922. <p><img src="assets/1762153476605.png" alt="image-20251004021532441" style="zoom:50%;" /></p>
  923. <h3 id="3-embeddings-models">3 Embeddings Models<a class="headerlink" href="#3-embeddings-models" title="Permanent link">&para;</a></h3>
  924. <p>Embeddings Models(嵌入模型)特点:将字符串作为输入,返回一个浮动数的列表。在NLP中,Embedding的作用就是将数据进行文本向量化。</p>
  925. <div align=center><img src="assets/6-4.png" style="zoom:40%" ><img/></div>
  926. <p>Embeddings Models可以为文本创建向量映射,这样就能在向量空间里去考虑文本,执行诸如语义搜索之类的操作,比如说寻找相似的文本片段。</p>
  927. <blockquote>
  928. <p><a href="https://python.langchain.com/docs/integrations/text_embedding/">https://python.langchain.com/docs/integrations/text_embedding/</a></p>
  929. </blockquote>
  930. <hr />
  931. <p>不同的Embedding模型对多语言支持和文本类型有不同的特点:</p>
  932. <ul>
  933. <li><strong>多语言支持</strong>:<ul>
  934. <li><code>text-embedding-ada-002</code>:支持多种语言,但对中文等亚洲语言的支持相对较弱</li>
  935. <li><code>bge-large-zh</code>:对中文有很好的支持</li>
  936. <li><code>multilingual-e5-large</code>:对多语言都有较好的支持</li>
  937. <li>mxbai-embed-large:</li>
  938. </ul>
  939. </li>
  940. <li><strong>文本类型适用性</strong>:<ul>
  941. <li>代码文本:建议使用专门的代码Embedding模型,如 <code>CodeBERT</code></li>
  942. <li>通用文本:可以使用<code>text-embedding-ada-002</code>或 <code>bge-large-zh</code></li>
  943. <li>专业领域文本:建议使用该领域的专门模型</li>
  944. </ul>
  945. </li>
  946. </ul>
  947. <p>可以参考MTEB(大规模文本嵌入基准)排行榜以获取最新模型效果:<a href="https://huggingface.co/spaces/mteb/leaderboard">https://huggingface.co/spaces/mteb/leaderboard</a></p>
  948. <p>接下来以一个文本嵌入模型的例子进行说明:</p>
  949. <div class="highlight"><pre><span></span><code><span class="c1"># from langchain_community.embeddings import OllamaEmbeddings # Langchain 0.x版本使用</span>
  950. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaEmbeddings</span>
  951. <span class="c1"># 初始化Ollama嵌入模型,使用mxbai-embed-large模型,温度设置为0</span>
  952. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaEmbeddings</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;mxbai-embed-large&quot;</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
  953. <span class="c1"># 对单个查询文本进行嵌入编码</span>
  954. <span class="n">res1</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">embed_query</span><span class="p">(</span><span class="s1">&#39;这是第一个测试文档&#39;</span><span class="p">)</span>
  955. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result1-&gt;</span><span class="si">{</span><span class="n">res1</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  956. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result1的长度-&gt;</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">res1</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  957. <span class="c1"># 对多个文档进行批量嵌入编码</span>
  958. <span class="n">res2</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">embed_documents</span><span class="p">([</span><span class="s1">&#39;这是第一个测试文档&#39;</span><span class="p">,</span> <span class="s1">&#39;这是第二个测试文档&#39;</span><span class="p">])</span>
  959. <span class="nb">print</span><span class="p">(</span><span class="n">res2</span><span class="p">)</span>
  960. </code></pre></div>
  961. <p>运行结果:</p>
  962. <p><img alt="1762164216432" src="assets/1762164216432.png" /></p>
  963. <h2 id="prompts">三、Prompts<a class="headerlink" href="#prompts" title="Permanent link">&para;</a></h2>
  964. <h3 id="1-prompt">1 通用prompt<a class="headerlink" href="#1-prompt" title="Permanent link">&para;</a></h3>
  965. <p>Prompt是指当用户输入信息给模型时加入的提示,这个提示的形式可以是zero-shot或者few-shot等方式,目的是让模型理解更为复杂的业务场景以便更好的解决问题。</p>
  966. <p>提示模板:如果你有了一个起作用的提示,你可能想把它作为一个模板用于解决其他问题,LangChain就提供了PromptTemplates组件,它可以帮助你更方便的构建提示。</p>
  967. <ul>
  968. <li><strong>zero-shot提示方式</strong></li>
  969. </ul>
  970. <div class="highlight"><pre><span></span><code><span class="c1"># from langchain import PromptTemplate # Langchain 0.x版本使用</span>
  971. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">PromptTemplate</span>
  972. <span class="c1"># from langchain_community.llms import Ollama # Langchain 0.x版本使用</span>
  973. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  974. <span class="c1"># model = Ollama(model=&quot;qwen2.5:7b&quot;) # Langchain 0.x版本使用</span>
  975. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  976. <span class="c1"># 定义模板</span>
  977. <span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字&quot;</span>
  978. <span class="n">prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
  979. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;lastname&quot;</span><span class="p">],</span>
  980. <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">)</span>
  981. <span class="n">prompt_text</span> <span class="o">=</span> <span class="n">prompt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lastname</span><span class="o">=</span><span class="s2">&quot;王&quot;</span><span class="p">)</span>
  982. <span class="nb">print</span><span class="p">(</span><span class="n">prompt_text</span><span class="p">)</span>
  983. <span class="c1"># result: 我的邻居姓王,他生了个儿子,给他儿子起个名字</span>
  984. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">prompt_text</span><span class="p">)</span>
  985. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
  986. </code></pre></div>
  987. <p>运行结果:</p>
  988. <p><img alt="image-20251002154154332" src="assets/image-20251002154154332.png" /></p>
  989. <ul>
  990. <li><strong>few-shot提示方式</strong></li>
  991. </ul>
  992. <div class="highlight"><pre><span></span><code><span class="c1"># from langchain import PromptTemplate, FewShotPromptTemplate # Langchain 0.x版本使用</span>
  993. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">PromptTemplate</span><span class="p">,</span> <span class="n">FewShotPromptTemplate</span>
  994. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  995. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  996. <span class="n">examples</span> <span class="o">=</span> <span class="p">[</span>
  997. <span class="p">{</span><span class="s2">&quot;word&quot;</span><span class="p">:</span> <span class="s2">&quot;开心&quot;</span><span class="p">,</span> <span class="s2">&quot;antonym&quot;</span><span class="p">:</span> <span class="s2">&quot;难过&quot;</span><span class="p">},</span>
  998. <span class="p">{</span><span class="s2">&quot;word&quot;</span><span class="p">:</span> <span class="s2">&quot;高&quot;</span><span class="p">,</span> <span class="s2">&quot;antonym&quot;</span><span class="p">:</span> <span class="s2">&quot;矮&quot;</span><span class="p">}]</span>
  999. <span class="n">example_template</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
  1000. <span class="s2">单词: </span><span class="si">{word}</span>
  1001. <span class="s2">反义词: </span><span class="si">{antonym}</span><span class="se">\\</span><span class="s2">n</span>
  1002. <span class="s2">&quot;&quot;&quot;</span>
  1003. <span class="n">example_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
  1004. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;word&quot;</span><span class="p">,</span> <span class="s2">&quot;antonym&quot;</span><span class="p">],</span>
  1005. <span class="n">template</span><span class="o">=</span><span class="n">example_template</span><span class="p">,</span>
  1006. <span class="p">)</span>
  1007. <span class="n">few_shot_prompt</span> <span class="o">=</span> <span class="n">FewShotPromptTemplate</span><span class="p">(</span>
  1008. <span class="n">examples</span><span class="o">=</span><span class="n">examples</span><span class="p">,</span>
  1009. <span class="n">example_prompt</span><span class="o">=</span><span class="n">example_prompt</span><span class="p">,</span>
  1010. <span class="n">prefix</span><span class="o">=</span><span class="s2">&quot;给出每个单词的反义词&quot;</span><span class="p">,</span>
  1011. <span class="n">suffix</span><span class="o">=</span><span class="s2">&quot;单词: </span><span class="si">{input}</span><span class="se">\\</span><span class="s2">n反义词:&quot;</span><span class="p">,</span>
  1012. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;input&quot;</span><span class="p">],</span>
  1013. <span class="n">example_separator</span><span class="o">=</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">n&quot;</span><span class="p">,</span>
  1014. <span class="p">)</span>
  1015. <span class="n">prompt_text</span> <span class="o">=</span> <span class="n">few_shot_prompt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">input</span><span class="o">=</span><span class="s2">&quot;粗&quot;</span><span class="p">)</span>
  1016. <span class="nb">print</span><span class="p">(</span><span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">prompt_text</span><span class="p">))</span>
  1017. <span class="c1"># 细</span>
  1018. </code></pre></div>
  1019. <p>运行结果:</p>
  1020. <p><img src="assets/image-20251002152859092.png" alt="image-20251002152859092" style="zoom:67%;" /></p>
  1021. <h3 id="2-chatprompts">2 ChatPrompts<a class="headerlink" href="#2-chatprompts" title="Permanent link">&para;</a></h3>
  1022. <p>适合交互式对话应用,如聊天机器人、智能客服等,这些应用需要处理用户和LLM之间的多轮对话。</p>
  1023. <blockquote>
  1024. <p>ChatPromptTemplate</p>
  1025. <p>SystemMessagePromptTemplate</p>
  1026. <p>HumanMessagePromptTemplate</p>
  1027. <p>history=[("system","......"),('human',"......"),("ai","......")]</p>
  1028. </blockquote>
  1029. <ul>
  1030. <li><strong>直接提问</strong></li>
  1031. </ul>
  1032. <p>提示模板就是把一些常见的提示整理成模板,用户只需要修改模板中特定的词语,就能快速准确地告诉模型自己的需求。我们看个例子:</p>
  1033. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1034. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1035. <span class="c1"># 实例化模型</span>
  1036. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1037. <span class="c1"># 定义提示词模版</span>
  1038. <span class="n">template_str</span> <span class="o">=</span> <span class="s2">&quot;帮我讲个关于</span><span class="si">{name}</span><span class="s2">笑话吧&quot;</span>
  1039. <span class="n">prompt_template</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span><span class="n">template_str</span><span class="p">)</span>
  1040. <span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt_template</span><span class="o">.</span><span class="n">format_messages</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;气球&quot;</span><span class="p">)</span>
  1041. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;prompt--&gt;</span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1042. <span class="c1"># 调用模型</span>
  1043. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">prompt</span><span class="p">)</span>
  1044. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result--&gt;</span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1045. </code></pre></div>
  1046. <p>运行结果:</p>
  1047. <p><img src="assets/image-20251002153543943.png" alt="image-20251002153543943" style="zoom:67%;" /></p>
  1048. <ul>
  1049. <li><strong>zero-shot提示方式</strong></li>
  1050. </ul>
  1051. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span><span class="p">,</span> <span class="n">HumanMessagePromptTemplate</span>
  1052. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.messages</span><span class="w"> </span><span class="kn">import</span> <span class="n">SystemMessage</span>
  1053. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1054. <span class="c1"># 实例化模型</span>
  1055. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1056. <span class="c1"># 系统信息</span>
  1057. <span class="n">system_prompt</span> <span class="o">=</span> <span class="n">SystemMessage</span><span class="p">(</span><span class="s2">&quot;你是取名专家。&quot;</span><span class="p">)</span>
  1058. <span class="c1"># 用户信息模版</span>
  1059. <span class="n">human_str</span> <span class="o">=</span> <span class="s2">&quot;我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字。&quot;</span>
  1060. <span class="n">human_template</span> <span class="o">=</span> <span class="n">HumanMessagePromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span><span class="n">human_str</span><span class="p">)</span>
  1061. <span class="c1"># 组装</span>
  1062. <span class="n">chat_template</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_messages</span><span class="p">([</span><span class="n">system_prompt</span><span class="p">,</span> <span class="n">human_template</span><span class="p">])</span>
  1063. <span class="c1"># 生成最终的提示词</span>
  1064. <span class="n">prompt</span> <span class="o">=</span> <span class="n">chat_template</span><span class="o">.</span><span class="n">format_messages</span><span class="p">(</span><span class="n">lastname</span><span class="o">=</span><span class="s2">&quot;王&quot;</span><span class="p">)</span>
  1065. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;prompt--&gt;</span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1066. <span class="c1"># 调用模型</span>
  1067. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">prompt</span><span class="p">)</span> <span class="c1"># 返回结果出了content外,还有元数据信息</span>
  1068. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result--&gt;</span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1069. </code></pre></div>
  1070. <p>运行结果:</p>
  1071. <p><img alt="image-20251002200159523" src="assets/image-20251002200159523.png" /></p>
  1072. <ul>
  1073. <li><strong>few-shot提示方式</strong></li>
  1074. </ul>
  1075. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span><span class="p">,</span> <span class="n">MessagesPlaceholder</span>
  1076. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1077. <span class="c1"># 实例化模型</span>
  1078. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1079. <span class="c1"># 创建 prompt 模版</span>
  1080. <span class="n">prompt_template</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_messages</span><span class="p">(</span>
  1081. <span class="p">[</span>
  1082. <span class="p">(</span><span class="s2">&quot;system&quot;</span><span class="p">,</span> <span class="s2">&quot;给出每个单词的反义词&quot;</span><span class="p">),</span>
  1083. <span class="n">MessagesPlaceholder</span><span class="p">(</span><span class="s2">&quot;history&quot;</span><span class="p">),</span>
  1084. <span class="p">(</span><span class="s2">&quot;human&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{question}</span><span class="s2">&quot;</span><span class="p">)</span>
  1085. <span class="p">]</span>
  1086. <span class="p">)</span>
  1087. <span class="c1"># 创建 few-shot prompt</span>
  1088. <span class="c1"># history = [</span>
  1089. <span class="c1"># HumanMessage(content=&quot;开心&quot;),</span>
  1090. <span class="c1"># AIMessage(content=&quot;难过&quot;),</span>
  1091. <span class="c1"># HumanMessage(content=&quot;高&quot;),</span>
  1092. <span class="c1"># AIMessage(content=&quot;矮&quot;)</span>
  1093. <span class="c1"># ]</span>
  1094. <span class="n">history</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">&quot;human&quot;</span><span class="p">,</span> <span class="s2">&quot;开心&quot;</span><span class="p">),</span> <span class="p">(</span><span class="s2">&quot;ai&quot;</span><span class="p">,</span> <span class="s2">&quot;难过&quot;</span><span class="p">),(</span><span class="s2">&quot;human&quot;</span><span class="p">,</span> <span class="s2">&quot;高&quot;</span><span class="p">),</span> <span class="p">(</span><span class="s2">&quot;ai&quot;</span><span class="p">,</span> <span class="s2">&quot;矮&quot;</span><span class="p">)]</span>
  1095. <span class="n">prompt</span> <span class="o">=</span> <span class="n">prompt_template</span><span class="o">.</span><span class="n">format_messages</span><span class="p">(</span><span class="n">history</span><span class="o">=</span><span class="n">history</span><span class="p">,</span> <span class="n">question</span><span class="o">=</span><span class="s2">&quot;富有&quot;</span><span class="p">)</span>
  1096. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;prompt--&gt;</span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
  1097. <span class="c1"># 调用模型</span>
  1098. <span class="n">result</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">prompt</span><span class="p">)</span>
  1099. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result--&gt;</span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1100. </code></pre></div>
  1101. <p>运行结果:</p>
  1102. <p><img alt="image-20251002205814344" src="assets/image-20251002205814344.png" /></p>
  1103. <h2 id="chains">四、Chains<a class="headerlink" href="#chains" title="Permanent link">&para;</a></h2>
  1104. <p>在LangChain中,Chains描述了将LLM与其他组件结合起来完成一个应用程序的过程。
  1105. 针对上一小节的提示模版例子,zero-shot里面,我们可以用链来连接提示模版组件和模型,进而可以实现代码的更改,主要使用LCEL方法。</p>
  1106. <p>LCEL(Lang Chain Expression Language) 是一种声明式的方法,用于轻松组合链条。</p>
  1107. <p>LCEL的基本语法规则是使用<code>|</code>符号将不同的组件连接起来,形成一个链式结构。<code>|</code>符号类似于Unix的管道操作符,它将一个组件的输出作为下一个组件的输入,从而实现数据的传递和处理。</p>
  1108. <p>上一个组件的输出作为下一个组件的输入,输出和输入的类型必须保持一致,否则不能连接。</p>
  1109. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain</span><span class="w"> </span><span class="kn">import</span> <span class="n">PromptTemplate</span>
  1110. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">PromptTemplate</span>
  1111. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1112. <span class="c1"># 定义模板</span>
  1113. <span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字&quot;</span>
  1114. <span class="n">prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
  1115. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;lastname&quot;</span><span class="p">],</span>
  1116. <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">)</span>
  1117. <span class="c1"># 实例化模型</span>
  1118. <span class="n">llm</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1119. <span class="n">chain</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">llm</span>
  1120. <span class="c1"># 执行链</span>
  1121. <span class="nb">print</span><span class="p">(</span><span class="n">chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;王&quot;</span><span class="p">))</span>
  1122. </code></pre></div>
  1123. <p>如果你想将第一个模型输出的结果,直接作为第二个模型的输入,直接使用管道符, 代码如下:</p>
  1124. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">PromptTemplate</span>
  1125. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1126. <span class="c1"># 创建第一条链</span>
  1127. <span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字&quot;</span>
  1128. <span class="n">first_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
  1129. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;lastname&quot;</span><span class="p">],</span>
  1130. <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">,)</span>
  1131. <span class="c1"># 实例化模型</span>
  1132. <span class="n">llm</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1133. <span class="n">first_chain</span> <span class="o">=</span> <span class="n">first_prompt</span> <span class="o">|</span> <span class="n">llm</span>
  1134. <span class="c1"># 创建第二条链</span>
  1135. <span class="n">second_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
  1136. <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;child_name&quot;</span><span class="p">],</span>
  1137. <span class="n">template</span><span class="o">=</span><span class="s2">&quot;邻居的儿子名字叫</span><span class="si">{child_name}</span><span class="s2">,给他起一个小名&quot;</span><span class="p">)</span>
  1138. <span class="n">second_chain</span> <span class="o">=</span> <span class="n">second_prompt</span> <span class="o">|</span> <span class="n">llm</span>
  1139. <span class="c1"># 链接两条链</span>
  1140. <span class="n">overall_chain</span> <span class="o">=</span> <span class="n">first_chain</span> <span class="o">|</span> <span class="n">second_chain</span>
  1141. <span class="nb">print</span><span class="p">(</span><span class="n">overall_chain</span><span class="p">)</span>
  1142. <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="o">*</span><span class="mi">80</span><span class="p">)</span>
  1143. <span class="c1"># 执行链,只需要传入第一个参数</span>
  1144. <span class="n">catchphrase</span> <span class="o">=</span> <span class="n">overall_chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;王&quot;</span><span class="p">)</span>
  1145. <span class="nb">print</span><span class="p">(</span><span class="n">catchphrase</span><span class="p">)</span>
  1146. </code></pre></div>
  1147. <p>运行结果:</p>
  1148. <p><img alt="image-20251002212834547" src="assets/image-20251002212834547.png" /></p>
  1149. <p><img alt="image-20251002212930745" src="assets/image-20251002212930745.png" /></p>
  1150. <h2 id="output_parsers">五、output_parsers<a class="headerlink" href="#output_parsers" title="Permanent link">&para;</a></h2>
  1151. <p>LLM 的输出是自然语言文本,但在应用开发中,我们经常需要将这些文本转换为结构化的数据格式,如列表、字典或对象。LangChain 输出解析器负责获取 LLM 的输出并将其转换为更合适的格式。</p>
  1152. <p>部分解析器如下:</p>
  1153. <table>
  1154. <thead>
  1155. <tr>
  1156. <th>解析器名称</th>
  1157. <th>核心功能</th>
  1158. <th>输出的 Python 类型</th>
  1159. <th>工业级应用场景</th>
  1160. </tr>
  1161. </thead>
  1162. <tbody>
  1163. <tr>
  1164. <td>StrOutputParser</td>
  1165. <td>默认解析器。将 LLM 的输出直接解析为字符串。</td>
  1166. <td>str</td>
  1167. <td>只需要原始回答时(如问答任务、对话场景)</td>
  1168. </tr>
  1169. <tr>
  1170. <td>CommaSeparatedListParser</td>
  1171. <td>将 LLM 输出的、用逗号分隔的文本解析为列表。</td>
  1172. <td>list[str]</td>
  1173. <td>列表/枚举型输出</td>
  1174. </tr>
  1175. <tr>
  1176. <td>JsonOutputParser</td>
  1177. <td>极其常用。将 LLM 输出的 JSON 字符串解析为 Python 字典。</td>
  1178. <td>dict</td>
  1179. <td>结构化 JSON 输出</td>
  1180. </tr>
  1181. <tr>
  1182. <td>PydanticOutputParser</td>
  1183. <td>极其常用。将 LLM 输出解析为预先定义的 Pydantic 对象,提供类型安全和数据验证。</td>
  1184. <td>自定义的 pydantic.BaseModel 对象</td>
  1185. <td>输出需要严格结构化(JSON-like)数据时</td>
  1186. </tr>
  1187. <tr>
  1188. <td>DatetimeOutputParser</td>
  1189. <td>从文本中智能地解析出日期和时间信息。</td>
  1190. <td>datetime.datetime</td>
  1191. <td>需要时间格式时</td>
  1192. </tr>
  1193. </tbody>
  1194. </table>
  1195. <h3 id="1">1 字符串解析器<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
  1196. <p>StrOutputParser,最简单的解析器,用于提取模型返回的原始文本:</p>
  1197. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.output_parsers</span><span class="w"> </span><span class="kn">import</span> <span class="n">StrOutputParser</span>
  1198. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1199. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1200. <span class="c1"># 实例化模型</span>
  1201. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1202. <span class="c1"># 创建简单链</span>
  1203. <span class="n">prompt</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span><span class="s2">&quot;解释</span><span class="si">{topic}</span><span class="s2">是什么?回答控制20字以内&quot;</span><span class="p">)</span>
  1204. <span class="n">chain1</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">model</span>
  1205. <span class="n">result1</span> <span class="o">=</span> <span class="n">chain1</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span><span class="s2">&quot;topic&quot;</span><span class="p">:</span> <span class="s2">&quot;ai&quot;</span><span class="p">})</span>
  1206. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;result1--&gt;</span><span class="si">{</span><span class="n">result1</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
  1207. <span class="c1"># 添加字符串解析器</span>
  1208. <span class="n">parser</span> <span class="o">=</span> <span class="n">StrOutputParser</span><span class="p">()</span>
  1209. <span class="n">chain2</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">model</span> <span class="o">|</span> <span class="n">parser</span>
  1210. <span class="n">result2</span> <span class="o">=</span> <span class="n">chain2</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span><span class="s2">&quot;topic&quot;</span><span class="p">:</span> <span class="s2">&quot;ai&quot;</span><span class="p">})</span>
  1211. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;result2--&gt;</span><span class="si">{</span><span class="n">result2</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
  1212. </code></pre></div>
  1213. <p>运行结果:</p>
  1214. <p><img alt="image-20251002230930266" src="assets/image-20251002230930266.png" /></p>
  1215. <h3 id="2_1">2 列表解析器<a class="headerlink" href="#2_1" title="Permanent link">&para;</a></h3>
  1216. <p>CommaSeparatedListOutputParser,将逗号分隔的文本转换为Python列表:</p>
  1217. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.output_parsers</span><span class="w"> </span><span class="kn">import</span> <span class="n">CommaSeparatedListOutputParser</span>
  1218. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1219. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1220. <span class="c1"># 实例化模型</span>
  1221. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1222. <span class="c1"># 创建列表解析器</span>
  1223. <span class="n">parser</span> <span class="o">=</span> <span class="n">CommaSeparatedListOutputParser</span><span class="p">()</span>
  1224. <span class="c1"># 创建带格式说明的提示模板</span>
  1225. <span class="n">format_instructions</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">get_format_instructions</span><span class="p">()</span>
  1226. <span class="n">prompt</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span>
  1227. <span class="s2">&quot;用中文列出</span><span class="si">{topic}</span><span class="s2">的五个最重要特点。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">&quot;</span>
  1228. <span class="p">)</span>
  1229. <span class="c1"># 组合组件</span>
  1230. <span class="n">chain</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">model</span> <span class="o">|</span> <span class="n">parser</span>
  1231. <span class="c1"># 调用链</span>
  1232. <span class="n">result</span> <span class="o">=</span> <span class="n">chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span>
  1233. <span class="s2">&quot;topic&quot;</span><span class="p">:</span> <span class="s2">&quot;大模型&quot;</span><span class="p">,</span>
  1234. <span class="s2">&quot;format_instructions&quot;</span><span class="p">:</span> <span class="n">format_instructions</span>
  1235. <span class="p">})</span>
  1236. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
  1237. </code></pre></div>
  1238. <p>运行结果:</p>
  1239. <p><img src="assets/image-20251002231200108.png" alt="image-20251002231200108" style="zoom: 67%;" /></p>
  1240. <h3 id="3-json">3 JSON解析器<a class="headerlink" href="#3-json" title="Permanent link">&para;</a></h3>
  1241. <p>JsonOutputParser,将JSON格式文本转换为Python字典或列表:</p>
  1242. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.output_parsers</span><span class="w"> </span><span class="kn">import</span> <span class="n">JsonOutputParser</span>
  1243. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1244. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1245. <span class="c1"># 实例化模型</span>
  1246. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1247. <span class="c1"># 创建JSON解析器</span>
  1248. <span class="n">json_parser</span> <span class="o">=</span> <span class="n">JsonOutputParser</span><span class="p">()</span>
  1249. <span class="c1"># 创建带格式说明的提示模板</span>
  1250. <span class="n">json_format_instructions</span> <span class="o">=</span> <span class="n">json_parser</span><span class="o">.</span><span class="n">get_format_instructions</span><span class="p">()</span>
  1251. <span class="n">json_prompt</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span>
  1252. <span class="s2">&quot;生成一个包含</span><span class="si">{person}</span><span class="s2">基本信息的JSON。应包括姓名、职业、年龄和技能列表, 不要包含任何注释或额外说明。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">&quot;</span>
  1253. <span class="p">)</span>
  1254. <span class="c1"># 组合组件</span>
  1255. <span class="n">json_chain</span> <span class="o">=</span> <span class="n">json_prompt</span> <span class="o">|</span> <span class="n">model</span> <span class="o">|</span> <span class="n">json_parser</span>
  1256. <span class="c1"># 调用链</span>
  1257. <span class="n">result</span> <span class="o">=</span> <span class="n">json_chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span>
  1258. <span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="s2">&quot;雷军&quot;</span><span class="p">,</span>
  1259. <span class="s2">&quot;format_instructions&quot;</span><span class="p">:</span> <span class="n">json_format_instructions</span>
  1260. <span class="p">})</span>
  1261. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
  1262. </code></pre></div>
  1263. <p>运行结果:</p>
  1264. <p><img alt="image-20251003000254030" src="assets/image-20251003000254030.png" /></p>
  1265. <h3 id="4-pydantic">4 Pydantic解析器<a class="headerlink" href="#4-pydantic" title="Permanent link">&para;</a></h3>
  1266. <p>PydanticOutputParser,使用Pydantic模型定义输出结构:</p>
  1267. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1268. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.output_parsers</span><span class="w"> </span><span class="kn">import</span> <span class="n">PydanticOutputParser</span>
  1269. <span class="kn">from</span><span class="w"> </span><span class="nn">pydantic</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseModel</span><span class="p">,</span> <span class="n">Field</span>
  1270. <span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">List</span>
  1271. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1272. <span class="c1"># 实例化模型</span>
  1273. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1274. <span class="c1"># 定义Pydantic模型</span>
  1275. <span class="k">class</span><span class="w"> </span><span class="nc">Movie</span><span class="p">(</span><span class="n">BaseModel</span><span class="p">):</span>
  1276. <span class="n">title</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;电影标题&quot;</span><span class="p">)</span>
  1277. <span class="n">director</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;导演姓名&quot;</span><span class="p">)</span>
  1278. <span class="n">year</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;上映年份&quot;</span><span class="p">)</span>
  1279. <span class="n">genre</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;电影类型&quot;</span><span class="p">)</span>
  1280. <span class="n">rating</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">Field</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;评分(1-10)&quot;</span><span class="p">)</span>
  1281. <span class="c1"># 创建Pydantic解析器</span>
  1282. <span class="n">pydantic_parser</span> <span class="o">=</span> <span class="n">PydanticOutputParser</span><span class="p">(</span><span class="n">pydantic_object</span><span class="o">=</span><span class="n">Movie</span><span class="p">)</span>
  1283. <span class="c1"># 创建带格式说明的提示模板</span>
  1284. <span class="n">format_instructions</span> <span class="o">=</span> <span class="n">pydantic_parser</span><span class="o">.</span><span class="n">get_format_instructions</span><span class="p">()</span>
  1285. <span class="n">pydantic_prompt</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span>
  1286. <span class="s2">&quot;生成一部</span><span class="si">{genre}</span><span class="s2">电影的信息。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">&quot;</span>
  1287. <span class="p">)</span>
  1288. <span class="c1"># 组合组件</span>
  1289. <span class="n">pydantic_chain</span> <span class="o">=</span> <span class="n">pydantic_prompt</span> <span class="o">|</span> <span class="n">model</span> <span class="o">|</span> <span class="n">pydantic_parser</span>
  1290. <span class="c1"># 调用链</span>
  1291. <span class="n">movie_data</span> <span class="o">=</span> <span class="n">pydantic_chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span>
  1292. <span class="s2">&quot;genre&quot;</span><span class="p">:</span> <span class="s2">&quot;科幻&quot;</span><span class="p">,</span>
  1293. <span class="s2">&quot;format_instructions&quot;</span><span class="p">:</span> <span class="n">format_instructions</span>
  1294. <span class="p">})</span>
  1295. <span class="nb">print</span><span class="p">(</span><span class="n">movie_data</span><span class="p">)</span>
  1296. </code></pre></div>
  1297. <p>运行结果:</p>
  1298. <p><img alt="image-20251003000720225" src="assets/image-20251003000720225.png" /></p>
  1299. <h3 id="5">5 自定义解析器<a class="headerlink" href="#5" title="Permanent link">&para;</a></h3>
  1300. <p>创建自定义输出解析器</p>
  1301. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.output_parsers</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseOutputParser</span>
  1302. <span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">Any</span>
  1303. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.prompts</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatPromptTemplate</span>
  1304. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1305. <span class="c1"># 实例化模型</span>
  1306. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1307. <span class="k">class</span><span class="w"> </span><span class="nc">CustomKeyValueParser</span><span class="p">(</span><span class="n">BaseOutputParser</span><span class="p">[</span><span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]]):</span>
  1308. <span class="w"> </span><span class="sd">&quot;&quot;&quot;解析形如&#39;key: value&#39;的文本&quot;&quot;&quot;</span>
  1309. <span class="k">def</span><span class="w"> </span><span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Any</span><span class="p">]:</span>
  1310. <span class="w"> </span><span class="sd">&quot;&quot;&quot;从文本中解析键值对&quot;&quot;&quot;</span>
  1311. <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
  1312. <span class="n">lines</span> <span class="o">=</span> <span class="n">text</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
  1313. <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
  1314. <span class="k">if</span> <span class="s1">&#39;:&#39;</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
  1315. <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
  1316. <span class="n">result</span><span class="p">[</span><span class="n">key</span><span class="o">.</span><span class="n">strip</span><span class="p">()]</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
  1317. <span class="k">return</span> <span class="n">result</span>
  1318. <span class="k">def</span><span class="w"> </span><span class="nf">get_format_instructions</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
  1319. <span class="w"> </span><span class="sd">&quot;&quot;&quot;提供格式指导给模型&quot;&quot;&quot;</span>
  1320. <span class="k">return</span> <span class="s2">&quot;&quot;&quot;请以&#39;键: 值&#39;的格式返回信息,每行一个键值对。</span>
  1321. <span class="s2"> 例如:</span>
  1322. <span class="s2"> 名称: 爱因斯坦</span>
  1323. <span class="s2"> 职业: 物理学家</span>
  1324. <span class="s2"> 贡献: 相对论&quot;&quot;&quot;</span>
  1325. <span class="c1"># 使用自定义解析器</span>
  1326. <span class="n">custom_parser</span> <span class="o">=</span> <span class="n">CustomKeyValueParser</span><span class="p">()</span>
  1327. <span class="n">custom_prompt</span> <span class="o">=</span> <span class="n">ChatPromptTemplate</span><span class="o">.</span><span class="n">from_template</span><span class="p">(</span>
  1328. <span class="s2">&quot;提供关于</span><span class="si">{person}</span><span class="s2">的基本信息。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">&quot;</span>
  1329. <span class="p">)</span>
  1330. <span class="c1"># 组合组件</span>
  1331. <span class="n">custom_chain</span> <span class="o">=</span> <span class="n">custom_prompt</span> <span class="o">|</span> <span class="n">model</span> <span class="o">|</span> <span class="n">custom_parser</span>
  1332. <span class="c1"># 调用模型</span>
  1333. <span class="n">result</span> <span class="o">=</span> <span class="n">custom_chain</span><span class="o">.</span><span class="n">invoke</span><span class="p">({</span>
  1334. <span class="s2">&quot;person&quot;</span><span class="p">:</span> <span class="s2">&quot;屠呦呦&quot;</span><span class="p">,</span>
  1335. <span class="s2">&quot;format_instructions&quot;</span><span class="p">:</span> <span class="n">custom_parser</span><span class="o">.</span><span class="n">get_format_instructions</span><span class="p">()</span>
  1336. <span class="p">})</span>
  1337. <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
  1338. </code></pre></div>
  1339. <p>运行结果:</p>
  1340. <p><img alt="image-20251003001007923" src="assets/image-20251003001007923.png" /></p>
  1341. <h2 id="memory">六、Memory<a class="headerlink" href="#memory" title="Permanent link">&para;</a></h2>
  1342. <p>大模型本身不具备上下文的概念,它并不保存上次交互的内容,ChatGPT之所以能够和人正常沟通对话,因为它进行了一层封装,将历史记录回传给了模型。</p>
  1343. <p>因此 LangChain 也提供了Memory组件, Memory分为两种类型: <strong>短期记忆和长期记忆</strong> 。短期记忆一般指单一会话时传递数据,长期记忆则是处理多个会话时获取和更新信息。</p>
  1344. <ul>
  1345. <li>使用 <strong>ChatMessageHistory</strong> 手动添加上下文</li>
  1346. </ul>
  1347. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.chat_message_histories</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatMessageHistory</span>
  1348. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.messages</span><span class="w"> </span><span class="kn">import</span> <span class="n">messages_to_dict</span><span class="p">,</span> <span class="n">messages_from_dict</span>
  1349. <span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
  1350. <span class="c1"># 1.创建一个ChatMessageHistory对象,用来存储对话信息</span>
  1351. <span class="n">history</span> <span class="o">=</span> <span class="n">ChatMessageHistory</span><span class="p">()</span>
  1352. <span class="c1"># 添加用户消息</span>
  1353. <span class="n">history</span><span class="o">.</span><span class="n">add_user_message</span><span class="p">(</span><span class="s2">&quot;在吗?&quot;</span><span class="p">)</span>
  1354. <span class="c1"># 添加大模型消息</span>
  1355. <span class="n">history</span><span class="o">.</span><span class="n">add_ai_message</span><span class="p">(</span><span class="s2">&quot;在&quot;</span><span class="p">)</span>
  1356. <span class="c1"># 打印所有消息</span>
  1357. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;history.messages--&gt;</span><span class="si">{</span><span class="n">history</span><span class="o">.</span><span class="n">messages</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1358. <span class="c1"># 2.可以将history.messages中的信息保存到字典中,然后保存到数据库或者文件中,方便后续读取</span>
  1359. <span class="c1"># 2.1 messages_to_dict()方法将history.messages中的信息转换成字典</span>
  1360. <span class="n">dicts</span> <span class="o">=</span> <span class="n">messages_to_dict</span><span class="p">(</span><span class="n">history</span><span class="o">.</span><span class="n">messages</span><span class="p">)</span>
  1361. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;dicts--&gt;</span><span class="si">{</span><span class="n">dicts</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1362. <span class="c1"># 2.2 这里将dicts保存到文件中</span>
  1363. <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;history.json&#39;</span><span class="p">,</span> <span class="s1">&#39;w&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
  1364. <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">dicts</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="kc">False</span><span class="p">))</span>
  1365. <span class="c1"># 3.从文件中读取出字典,然后将字典转换成消息</span>
  1366. <span class="c1"># 3.1 读取文件</span>
  1367. <span class="n">messages</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s1">&#39;history.json&#39;</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">))</span>
  1368. <span class="c1"># 3.2 然后将字典转换成消息</span>
  1369. <span class="n">chat_messages</span> <span class="o">=</span> <span class="n">messages_from_dict</span><span class="p">(</span><span class="n">messages</span><span class="p">)</span>
  1370. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;chat_messages--&gt;</span><span class="si">{</span><span class="n">chat_messages</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1371. </code></pre></div>
  1372. <p>运行结果:</p>
  1373. <p><img alt="image-20251003001546687" src="assets/image-20251003001546687.png" /></p>
  1374. <p>LangChain v1.0 版本对 Memory(记忆) 组件进行了深度优化与工程化重构,使其不仅支持多轮对话上下文管理,更成为构建生产级智能体(Agent)不可或缺的核心能力之一。在 LangChain 从“实验性框架”迈向“企业级平台”的关键转型中,Memory 模块被赋予了更清晰的职责边界、更灵活的策略机制以及更强的可扩展性,从而支撑复杂任务场景下的长期记忆、状态追踪与个性化交互。</p>
  1375. <h3 id="1-short-term-memory">1 短期记忆(Short-term Memory)<a class="headerlink" href="#1-short-term-memory" title="Permanent link">&para;</a></h3>
  1376. <p>短期记忆的本质是线程级状态管理]。在 LangGraph 中:</p>
  1377. <blockquote>
  1378. <p>短期记忆 = Agent 状态(State) + 检查点持久化(Checkpointer) + 线程标识(thread_id)。</p>
  1379. </blockquote>
  1380. <p><strong>(1)状态(State)</strong></p>
  1381. <p>通常是一个包含 messages 字段的字典或 Pydantic 模型(如 MessagesState 或自定义 CustomState),用于存储当前会话的所有消息、中间变量、工具调用结果等。</p>
  1382. <p><strong>(2)检查点器(Checkpointer)</strong></p>
  1383. <p>负责将状态序列化并持久化到内存、SQLite、PostgreSQL 等后端。每次状态变更(如新增一条消息)都会触发一次检查点保存。</p>
  1384. <p><strong>(3)会话ID(thread_id)</strong></p>
  1385. <p>作为会话的唯一标识符,确保不同用户或不同对话之间的状态完全隔离。即使多个用户并发交互,也不会发生记忆混淆。</p>
  1386. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_agent</span>
  1387. <span class="kn">from</span><span class="w"> </span><span class="nn">langgraph.checkpoint.memory</span><span class="w"> </span><span class="kn">import</span> <span class="n">InMemorySaver</span>
  1388. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain.messages</span><span class="w"> </span><span class="kn">import</span> <span class="n">HumanMessage</span>
  1389. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaLLM</span>
  1390. <span class="kn">import</span><span class="w"> </span><span class="nn">time</span>
  1391. <span class="c1"># 初始化大模型,这里使用的是 Qwen 的聊天模型</span>
  1392. <span class="n">model</span> <span class="o">=</span> <span class="n">OllamaLLM</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;qwen2.5:7b&quot;</span><span class="p">)</span>
  1393. <span class="c1"># 创建内存保存器 (Checkpointer)</span>
  1394. <span class="c1"># 这是 LangGraph 的核心概念之一,用于在对话过程中保存和恢复状态(记忆)</span>
  1395. <span class="n">checkpointer</span> <span class="o">=</span> <span class="n">InMemorySaver</span><span class="p">()</span>
  1396. <span class="c1"># 定义 Agent 的配置</span>
  1397. <span class="c1"># &quot;thread_id&quot; (线程ID) 非常关键:它相当于对话的 ID,用于区分不同的会话记忆</span>
  1398. <span class="c1"># 使用时间戳作为 ID,确保每次运行脚本时的线程 ID 不同(但在同一次运行中复用)</span>
  1399. <span class="n">timestamp</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
  1400. <span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
  1401. <span class="s2">&quot;configurable&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;thread_id&quot;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">int</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">}</span>
  1402. <span class="p">}</span>
  1403. <span class="c1"># 创建 Agent 实例</span>
  1404. <span class="c1"># model: 指定使用的底层大模型</span>
  1405. <span class="c1"># tools: 工具列表,这里为空,表示 Agent 只能进行对话,不能调用外部工具(如搜索、计算器等)</span>
  1406. <span class="c1"># checkpointer: 传入上面的内存保存器,赋予 Agent 记忆能力</span>
  1407. <span class="c1"># system_prompt: 设定 Agent 的角色和行为模式</span>
  1408. <span class="n">agent</span> <span class="o">=</span> <span class="n">create_agent</span><span class="p">(</span>
  1409. <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
  1410. <span class="n">tools</span><span class="o">=</span><span class="p">[],</span>
  1411. <span class="n">checkpointer</span><span class="o">=</span><span class="n">checkpointer</span><span class="p">,</span>
  1412. <span class="n">system_prompt</span><span class="o">=</span><span class="s2">&quot;你是一个翻译官,擅长中英互译。&quot;</span>
  1413. <span class="p">)</span>
  1414. <span class="c1"># 第一轮对话输入</span>
  1415. <span class="n">input_1</span> <span class="o">=</span> <span class="p">{</span>
  1416. <span class="s2">&quot;messages&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">HumanMessage</span><span class="p">(</span><span class="s2">&quot;你好,我叫小呆。&quot;</span><span class="p">)]</span>
  1417. <span class="p">}</span>
  1418. <span class="c1"># 调用 Agent (Response A)</span>
  1419. <span class="c1"># 使用 config,这意味着这次对话会记录在 thread_id 对应的内存中</span>
  1420. <span class="c1"># Agent 会记住 &quot;我叫小呆&quot; 这个信息</span>
  1421. <span class="n">response_a</span> <span class="o">=</span> <span class="n">agent</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span>
  1422. <span class="nb">input</span><span class="o">=</span><span class="n">input_1</span><span class="p">,</span>
  1423. <span class="n">config</span><span class="o">=</span><span class="n">config</span>
  1424. <span class="p">)</span>
  1425. <span class="c1"># 第二轮对话输入(测试是否记得之前的信息)</span>
  1426. <span class="n">input_2</span> <span class="o">=</span> <span class="p">{</span>
  1427. <span class="s2">&quot;messages&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">HumanMessage</span><span class="p">(</span><span class="s2">&quot;你好,我叫什么?&quot;</span><span class="p">)]</span>
  1428. <span class="p">}</span>
  1429. <span class="c1"># 定义一个新的配置 (config_2),使用完全不同的 thread_id</span>
  1430. <span class="c1"># 这代表开启了一个全新的、独立的对话会话</span>
  1431. <span class="n">config_2</span> <span class="o">=</span> <span class="p">{</span>
  1432. <span class="s2">&quot;configurable&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;thread_id&quot;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">}</span> <span class="c1"># 这里生成了一个新的时间戳 ID</span>
  1433. <span class="p">}</span>
  1434. <span class="c1"># 调用 Agent (Response B)</span>
  1435. <span class="c1"># 使用新的 config_2,Agent 看不到 config_1 中的历史记录</span>
  1436. <span class="c1"># 因此,Agent 应该不知道用户叫 &quot;小呆&quot;,因为它处于一个新的 &quot;线程&quot; 中</span>
  1437. <span class="n">response_b</span> <span class="o">=</span> <span class="n">agent</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span>
  1438. <span class="nb">input</span><span class="o">=</span><span class="n">input_2</span><span class="p">,</span>
  1439. <span class="n">config</span><span class="o">=</span><span class="n">config_2</span>
  1440. <span class="p">)</span>
  1441. <span class="c1"># 调用 Agent (Response C)</span>
  1442. <span class="c1"># 再次使用最初的 config</span>
  1443. <span class="c1"># 这会恢复到第一个会话的记忆中</span>
  1444. <span class="c1"># Agent 应该能回想起用户叫 &quot;小呆&quot;,因为它共享同一个 thread_id</span>
  1445. <span class="n">response_c</span> <span class="o">=</span> <span class="n">agent</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span>
  1446. <span class="nb">input</span><span class="o">=</span><span class="n">input_2</span><span class="p">,</span>
  1447. <span class="n">config</span><span class="o">=</span><span class="n">config</span>
  1448. <span class="p">)</span>
  1449. <span class="c1"># 输出结果进行对比</span>
  1450. <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Response A (第一次对话):&quot;</span><span class="p">)</span>
  1451. <span class="nb">print</span><span class="p">(</span><span class="n">response_a</span><span class="p">)</span>
  1452. <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Response B (新线程,无记忆):&quot;</span><span class="p">)</span>
  1453. <span class="nb">print</span><span class="p">(</span><span class="n">response_b</span><span class="p">)</span>
  1454. <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Response C (回到原线程,有记忆):&quot;</span><span class="p">)</span>
  1455. <span class="nb">print</span><span class="p">(</span><span class="n">response_c</span><span class="p">)</span>
  1456. </code></pre></div>
  1457. <p><strong>代码运行逻辑:</strong></p>
  1458. <ul>
  1459. <li><strong>checkpointer (记忆核心)</strong>:这是 LangGraph 区别于传统简单 API 调用的关键。它允许 Agent 在多次 invoke 调用之间保存状态。</li>
  1460. <li><strong>thread_id (记忆索引)</strong>:你可以把 thread_id 想象成数据库中的主键。</li>
  1461. <li>Response A:向 ID 为 100 的记录里写入了名字。</li>
  1462. <li>Response B:向 ID 为 200 的新记录提问,因为 200 是空的,所以 Agent 不知道名字。</li>
  1463. <li>Response C:又回到 ID 为 100 的记录提问,Agent 读取了历史记录,所以知道名字。</li>
  1464. <li><strong>System Prompt</strong>:虽然输入是在对话,但因为设定了 “你是一个翻译官”,Agent 可能会试图在回答的同时进行翻译,或者在回复格式上符合翻译官的身份。</li>
  1465. </ul>
  1466. <h3 id="2_2">2 长期记忆<a class="headerlink" href="#2_2" title="Permanent link">&para;</a></h3>
  1467. <p>对于需要长期运行和可靠记忆的应用,推荐使用数据库进行持久化。详见后面阶段LangGraph部分。</p>
  1468. <h2 id="indexes">七、Indexes<a class="headerlink" href="#indexes" title="Permanent link">&para;</a></h2>
  1469. <p>Indexes组件的目的是让LangChain具备处理文档处理的能力,包括:文档加载、检索等。注意,这里的文档不局限于txt、pdf等文本类内容,还涵盖email、区块链、视频等内容。</p>
  1470. <p>Indexes组件主要包含类型:</p>
  1471. <ul>
  1472. <li>文档加载器</li>
  1473. <li>文本分割器</li>
  1474. <li>VectorStores</li>
  1475. <li>检索器</li>
  1476. </ul>
  1477. <h3 id="1_1">1 文档加载器<a class="headerlink" href="#1_1" title="Permanent link">&para;</a></h3>
  1478. <blockquote>
  1479. <p><a href="https://python.langchain.com/v0.2/docs/introduction/">https://python.langchain.com/v0.2/docs/introduction/</a></p>
  1480. </blockquote>
  1481. <p>文档加载器主要基于<code>Unstructured</code> 包,<code>Unstructured</code> 是一个python包,可以把各种类型的文件转换成文本。文档加载器使用起来很简单,只需要引入相应的loader工具。</p>
  1482. <p>LangChain支持的文档加载器 (部分):</p>
  1483. <p><img alt="image-20250705100227413" src="assets/image-20250705100227413.png" /></p>
  1484. <p>示例代码:</p>
  1485. <blockquote>
  1486. <p>需要安装的包:</p>
  1487. <p>pip install unstructured</p>
  1488. <p>pip install langchain-unstructured</p>
  1489. </blockquote>
  1490. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_unstructured</span><span class="w"> </span><span class="kn">import</span> <span class="n">UnstructuredLoader</span>
  1491. <span class="c1"># 创建 UnstructuredLoader 对象</span>
  1492. <span class="n">loader</span> <span class="o">=</span> <span class="n">UnstructuredLoader</span><span class="p">(</span><span class="s1">&#39;./data/衣服属性.txt&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
  1493. <span class="n">docs</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
  1494. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;docs--&gt;</span><span class="si">{</span><span class="n">docs</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1495. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;len--&gt;</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1496. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;第一行数据--&gt;</span><span class="si">{</span><span class="n">docs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">page_content</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1497. <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;*&#39;</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span>
  1498. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.document_loaders</span><span class="w"> </span><span class="kn">import</span> <span class="n">TextLoader</span>
  1499. <span class="c1"># 创建 TextLoader 对象</span>
  1500. <span class="n">loader</span> <span class="o">=</span> <span class="n">TextLoader</span><span class="p">(</span><span class="s1">&#39;./data/衣服属性.txt&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf8&#39;</span><span class="p">)</span>
  1501. <span class="n">docs</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
  1502. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;docs--&gt;</span><span class="si">{</span><span class="n">docs</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1503. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;len--&gt;</span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1504. <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;第一行数据--&gt;</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">docs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">page_content</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]))</span>
  1505. </code></pre></div>
  1506. <p>运行结果:</p>
  1507. <p><img alt="image-20251003010445727" src="assets/image-20251003010445727.png" /></p>
  1508. <h3 id="2_3">2 文档分割器<a class="headerlink" href="#2_3" title="Permanent link">&para;</a></h3>
  1509. <p>由于模型对输入的字符长度有限制,我们在碰到很长的文本时,需要把文本分割成多个小的文本片段。</p>
  1510. <p>文本分割最简单的方式是按照字符长度进行分割,但是这会带来很多问题,比如说如果文本是一段代码,一个函数被分割到两段之后就成了没有意义的字符,所以整体的原则是把语义相关的文本片段放在一起。</p>
  1511. <p>LangChain中最基本的文本分割器是<code>CharacterTextSplitter</code> ,它按照指定的分隔符(默认“\n\n”)进行分割,并且考虑文本片段的最大长度。我们看个例子:</p>
  1512. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.documents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Document</span>
  1513. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_text_splitters</span><span class="w"> </span><span class="kn">import</span> <span class="n">CharacterTextSplitter</span>
  1514. <span class="c1"># 创建分词器 separator参数指的是分割的分隔符,chunk_size指的是分割出来的每个块的大小,chunk_overlap指的是每个块之间重叠的大小</span>
  1515. <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">CharacterTextSplitter</span><span class="p">(</span><span class="n">separator</span><span class="o">=</span><span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="n">chunk_size</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">chunk_overlap</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
  1516. <span class="c1"># 一句话分割</span>
  1517. <span class="n">result1</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">split_text</span><span class="p">(</span><span class="s2">&quot;a b c d e f&quot;</span><span class="p">)</span>
  1518. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result1---&gt;</span><span class="si">{</span><span class="n">result1</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1519. <span class="c1"># 多句话分割</span>
  1520. <span class="n">result2</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">create_documents</span><span class="p">([</span><span class="s2">&quot;a b c d e f&quot;</span><span class="p">,</span> <span class="s2">&quot;e f g h&quot;</span><span class="p">])</span>
  1521. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result2---&gt;</span><span class="si">{</span><span class="n">result2</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1522. <span class="c1"># 多句话分割</span>
  1523. <span class="n">result3</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">split_documents</span><span class="p">([</span><span class="n">Document</span><span class="p">(</span><span class="n">page_content</span><span class="o">=</span><span class="s2">&quot;a b c d e f&quot;</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;1&quot;</span><span class="p">})])</span>
  1524. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result3---&gt;</span><span class="si">{</span><span class="n">result3</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1525. </code></pre></div>
  1526. <p>运行结果:</p>
  1527. <p><img alt="image-20251003011030583" src="assets/image-20251003011030583.png" /></p>
  1528. <hr />
  1529. <p>除了CharacterTextSplitter分割器,LangChain还支持其他文档分割器 (部分):</p>
  1530. <table>
  1531. <thead>
  1532. <tr>
  1533. <th>分割器名称</th>
  1534. <th>功能描述</th>
  1535. <th>类型</th>
  1536. <th>工业场景应用</th>
  1537. </tr>
  1538. </thead>
  1539. <tbody>
  1540. <tr>
  1541. <td>CharacterTextSplitter</td>
  1542. <td>简单按指定分隔符(如换行、逗号)直接分割。</td>
  1543. <td>基础字符解析</td>
  1544. <td>简单字符串或 CSV 数据处理,如传感器数据日志。</td>
  1545. </tr>
  1546. <tr>
  1547. <td>RecursiveCharacterTextSplitter</td>
  1548. <td>递归按字符分割,先尝试自然边界(如段落、句子),太大则继续细分。</td>
  1549. <td>通用字符解析</td>
  1550. <td>通用文本处理,如日志、报告、PDF 文档分割,便于 RAG 检索。</td>
  1551. </tr>
  1552. <tr>
  1553. <td>TokenTextSplitter</td>
  1554. <td>按 token(词元)分割,支持 LLM token 计数。</td>
  1555. <td>Token 基于解析</td>
  1556. <td>LLM 输入优化,如处理 API 响应或长查询,控制 token 限制。</td>
  1557. </tr>
  1558. <tr>
  1559. <td>SentenceTextSplitter</td>
  1560. <td>按句子边界分割,使用 NLP 识别句子(包括标点)。</td>
  1561. <td>语义解析</td>
  1562. <td>自然语言文本,如文章或对话分析,保持句子完整。</td>
  1563. </tr>
  1564. <tr>
  1565. <td>SpacyTextSplitter</td>
  1566. <td>使用 SpaCy NLP 库按句子或实体分割(需安装 SpaCy)。</td>
  1567. <td>语义解析</td>
  1568. <td>高级 NLP 场景,如实体提取或生物医学文本。</td>
  1569. </tr>
  1570. <tr>
  1571. <td>NLTKTextSplitter</td>
  1572. <td>使用 NLTK 库按句子或词分割(需安装 NLTK)。</td>
  1573. <td>语义解析</td>
  1574. <td>文本研究或分析,如时间序列数据描述。</td>
  1575. </tr>
  1576. <tr>
  1577. <td>MarkdownHeaderTextSplitter</td>
  1578. <td>按 Markdown 结构(如标题、列表)智能分割。</td>
  1579. <td>结构化解析</td>
  1580. <td>Markdown 文档分割,保留语义结构,用于知识库构建。</td>
  1581. </tr>
  1582. <tr>
  1583. <td>HTMLSplitter</td>
  1584. <td>按 HTML 标签(如 、)分割网页内容。</td>
  1585. <td>结构化解析</td>
  1586. <td>网页数据爬取,如在线技术文档或新闻提取。</td>
  1587. </tr>
  1588. <tr>
  1589. <td>LatexTextSplitter</td>
  1590. <td>按 LaTeX 结构(如章节、公式)分割。</td>
  1591. <td>结构化解析</td>
  1592. <td>学术论文或数学文档处理。</td>
  1593. </tr>
  1594. <tr>
  1595. <td>PythonCodeTextSplitter</td>
  1596. <td>按 Python 代码结构(如函数、类)分割。</td>
  1597. <td>代码解析</td>
  1598. <td>源代码文件分析,如脚本调试或代码库管理。</td>
  1599. </tr>
  1600. </tbody>
  1601. </table>
  1602. <p>下面就几个重要的分割器进行讲解。</p>
  1603. <ul>
  1604. <li>递归字符文本分割器(RecursiveCharacterTextSplitter)</li>
  1605. </ul>
  1606. <blockquote>
  1607. <p>递归字符文本分割器是一种更智能的分割方法,它尝试在特定分隔符处分割文本,以保持更好的语义完整性。 特点:</p>
  1608. <ul>
  1609. <li>尝试在自然断点处分割文本</li>
  1610. <li>比简单的字符分割更能保持语义完整性</li>
  1611. <li>适用于结构化程度较高的文本,如 Markdown、HTML 等</li>
  1612. </ul>
  1613. <p>运行流程:</p>
  1614. <ul>
  1615. <li>首先尝试使用第一个分隔符(如 "\n\n")分割文本</li>
  1616. <li>如果分割后的块仍然过大,则使用下一个分隔符继续分割</li>
  1617. <li>重复此过程,直到达到指定的 chunk_size 或用完所有分隔符</li>
  1618. </ul>
  1619. <p>示例代码</p>
  1620. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_text_splitters</span><span class="w"> </span><span class="kn">import</span> <span class="n">RecursiveCharacterTextSplitter</span>
  1621. <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">RecursiveCharacterTextSplitter</span><span class="p">(</span>
  1622. <span class="n">chunk_size</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="c1"># 每个块最多 100 个字符</span>
  1623. <span class="n">chunk_overlap</span><span class="o">=</span><span class="mi">6</span><span class="p">,</span> <span class="c1"># 相邻分块会共享 20 个字符</span>
  1624. <span class="n">length_function</span><span class="o">=</span><span class="nb">len</span><span class="p">,</span> <span class="c1"># 用字符数来衡量长度</span>
  1625. <span class="n">separators</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">]</span> <span class="c1"># 会优先尝试按 \n\n 分段,如果太长,再按 \n → 空格 → 逐字符切分。</span>
  1626. <span class="p">)</span>
  1627. <span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
  1628. <span class="s2">人工智能正在快速发展,尤其是大语言模型的应用,正在改变人类的工作方式。</span>
  1629. <span class="s2">它们可以帮助人们进行写作、代码生成、甚至是科研探索。</span>
  1630. <span class="s2">相比之下,新能源的发展同样重要。</span>
  1631. <span class="s2">电动车和太阳能正在逐渐替代传统能源,减少碳排放,对全球环境保护至关重要。</span>
  1632. <span class="s2">&quot;&quot;&quot;</span>
  1633. <span class="n">docs</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">split_text</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
  1634. <span class="nb">print</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
  1635. </code></pre></div>
  1636. <p>运行结果</p>
  1637. <p><img alt="1768393012466" src="assets/1768393012466.png" /></p>
  1638. </blockquote>
  1639. <ul>
  1640. <li>语义文档分割器(SemanticChunker)</li>
  1641. </ul>
  1642. <blockquote>
  1643. <p>语义文档分割器使用语义理解来分割文本,这是一种更高级的分割方法。 特点:</p>
  1644. <ul>
  1645. <li>基于语义相似性分割文本</li>
  1646. <li>能够更好地保持语义完整性</li>
  1647. <li>计算成本较高,处理大量文本时可能效率较低</li>
  1648. <li>适用于需要高度语义理解的场景</li>
  1649. </ul>
  1650. <p>示例代码</p>
  1651. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_experimental.text_splitter</span><span class="w"> </span><span class="kn">import</span> <span class="n">SemanticChunker</span>
  1652. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaEmbeddings</span>
  1653. <span class="n">embed</span> <span class="o">=</span> <span class="n">OllamaEmbeddings</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;mxbai-embed-large&quot;</span><span class="p">)</span>
  1654. <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">SemanticChunker</span><span class="p">(</span>
  1655. <span class="n">embeddings</span><span class="o">=</span><span class="n">embed</span><span class="p">,</span>
  1656. <span class="n">breakpoint_threshold_type</span><span class="o">=</span><span class="s1">&#39;percentile&#39;</span><span class="p">,</span>
  1657. <span class="c1"># 更低的百分位会更“积极”地切分(数值越小 =&gt; 切得越多)</span>
  1658. <span class="n">breakpoint_threshold_amount</span><span class="o">=</span><span class="mf">70.0</span><span class="p">,</span>
  1659. <span class="c1"># 句子拆分正则为同时识别中/英文终结符</span>
  1660. <span class="n">sentence_split_regex</span><span class="o">=</span><span class="sa">r</span><span class="s1">&#39;(?&lt;=[。!?.!?])\s*&#39;</span><span class="p">,</span>
  1661. <span class="c1"># 每个切分后片段(chunk)至少要有多少个字符</span>
  1662. <span class="n">min_chunk_size</span><span class="o">=</span><span class="mi">10</span>
  1663. <span class="p">)</span>
  1664. <span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
  1665. <span class="s2">人工智能正在快速发展,尤其是大语言模型的应用,正在改变人类的工作方式。</span>
  1666. <span class="s2">它们可以帮助人们进行写作、代码生成、甚至是科研探索。</span>
  1667. <span class="s2">相比之下,新能源的发展同样重要。</span>
  1668. <span class="s2">电动车和太阳能正在逐渐替代传统能源,减少碳排放,对全球环境保护至关重要。</span>
  1669. <span class="s2">&quot;&quot;&quot;</span>
  1670. <span class="n">docs</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">split_text</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
  1671. <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">docs</span><span class="p">):</span>
  1672. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;------ Chunk </span><span class="si">{</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="si">}</span><span class="s2"> ------&quot;</span><span class="p">)</span>
  1673. <span class="nb">print</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
  1674. <span class="nb">print</span><span class="p">()</span>
  1675. </code></pre></div>
  1676. <p>运行结果</p>
  1677. <p><img alt="image-20251003095433705" src="assets/image-20251003095433705.png" /></p>
  1678. </blockquote>
  1679. <ul>
  1680. <li>MarkdownHeaderTextSplitter(Markdown文档切割器)</li>
  1681. </ul>
  1682. <blockquote>
  1683. <p>适用于Markdown文档,按照标题进行拆分</p>
  1684. <p>示例代码</p>
  1685. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_text_splitters</span><span class="w"> </span><span class="kn">import</span> <span class="n">MarkdownHeaderTextSplitter</span>
  1686. <span class="n">headers_to_split_on</span> <span class="o">=</span> <span class="p">[</span>
  1687. <span class="p">(</span><span class="s2">&quot;#&quot;</span><span class="p">,</span> <span class="s2">&quot;Header 1&quot;</span><span class="p">),</span>
  1688. <span class="p">(</span><span class="s2">&quot;##&quot;</span><span class="p">,</span> <span class="s2">&quot;Header 2&quot;</span><span class="p">),</span>
  1689. <span class="p">(</span><span class="s2">&quot;###&quot;</span><span class="p">,</span> <span class="s2">&quot;Header 3&quot;</span><span class="p">),</span>
  1690. <span class="p">]</span>
  1691. <span class="n">markdown_splitter</span> <span class="o">=</span> <span class="n">MarkdownHeaderTextSplitter</span><span class="p">(</span><span class="n">headers_to_split_on</span><span class="o">=</span><span class="n">headers_to_split_on</span><span class="p">)</span>
  1692. <span class="n">markdown_text</span> <span class="o">=</span> <span class="s2">&quot;# Header 1</span><span class="se">\n</span><span class="s2">Some text</span><span class="se">\n</span><span class="s2">## Header 2</span><span class="se">\n</span><span class="s2">More text</span><span class="se">\n</span><span class="s2">### Header 3</span><span class="se">\n</span><span class="s2">Even more text&quot;</span>
  1693. <span class="n">docs</span> <span class="o">=</span> <span class="n">markdown_splitter</span><span class="o">.</span><span class="n">split_text</span><span class="p">(</span><span class="n">markdown_text</span><span class="p">)</span>
  1694. <span class="nb">print</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
  1695. </code></pre></div>
  1696. <p>运行结果</p>
  1697. <p><img alt="image-20251003100510115" src="assets/image-20251003100510115.png" /></p>
  1698. </blockquote>
  1699. <p>其他拓展知识可以参考:<a href="https://blog.csdn.net/qq_28540861/article/details/149161419">https://blog.csdn.net/qq_28540861/article/details/149161419</a></p>
  1700. <h3 id="3-vectorstores">3 VectorStores<a class="headerlink" href="#3-vectorstores" title="Permanent link">&para;</a></h3>
  1701. <p>VectorStores是一种特殊类型的数据库,它的作用是存储由嵌入创建的向量,提供相似查询等功能。</p>
  1702. <p>LangChain支持的VectorStore有<a href="https://python.langchain.com/docs/integrations/vectorstores/">https://python.langchain.com/docs/integrations/vectorstores/</a>,常见的如下:</p>
  1703. <p><img alt="image-20250705114738060" src="assets/image-20250705114738060.png" /></p>
  1704. <blockquote>
  1705. <p>我们使用其中一个<code>Chroma</code> 组件作为例子:</p>
  1706. <p>pip install chromadb</p>
  1707. <p>pip install langchain-chroma</p>
  1708. </blockquote>
  1709. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_text_splitters</span><span class="w"> </span><span class="kn">import</span> <span class="n">CharacterTextSplitter</span>
  1710. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_chroma</span><span class="w"> </span><span class="kn">import</span> <span class="n">Chroma</span>
  1711. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.document_loaders</span><span class="w"> </span><span class="kn">import</span> <span class="n">TextLoader</span>
  1712. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaEmbeddings</span>
  1713. <span class="c1"># 1.加载文档</span>
  1714. <span class="c1"># 创建 TextLoader 对象</span>
  1715. <span class="n">loader</span> <span class="o">=</span> <span class="n">TextLoader</span><span class="p">(</span><span class="s1">&#39;./data/pku.txt&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span>
  1716. <span class="c1"># 加载文档</span>
  1717. <span class="n">docs</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load</span><span class="p">()</span>
  1718. <span class="c1"># print(f&#39;docs--&gt;{docs}&#39;)</span>
  1719. <span class="c1"># 2.将文档进行分块</span>
  1720. <span class="c1"># 创建 CharacterTextSplitter 对象</span>
  1721. <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">CharacterTextSplitter</span><span class="p">(</span><span class="n">separator</span><span class="o">=</span><span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">chunk_size</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">chunk_overlap</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
  1722. <span class="c1"># 分块</span>
  1723. <span class="n">split_docs</span> <span class="o">=</span> <span class="n">text_splitter</span><span class="o">.</span><span class="n">split_documents</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
  1724. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;split_docs--&gt;</span><span class="si">{</span><span class="n">split_docs</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1725. <span class="c1"># 3.将分割后的文档存储到向量数据库中</span>
  1726. <span class="c1"># 加载embedding模型</span>
  1727. <span class="n">embedding</span> <span class="o">=</span> <span class="n">OllamaEmbeddings</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;mxbai-embed-large&quot;</span><span class="p">)</span>
  1728. <span class="c1"># 创建向量数据库,需要指定 存储的文档和向量模型名称以及持久化目录</span>
  1729. <span class="n">chromadaDB</span> <span class="o">=</span> <span class="n">Chroma</span><span class="o">.</span><span class="n">from_documents</span><span class="p">(</span><span class="n">documents</span><span class="o">=</span><span class="n">split_docs</span><span class="p">,</span>
  1730. <span class="n">embedding</span><span class="o">=</span><span class="n">embedding</span><span class="p">,</span>
  1731. <span class="n">persist_directory</span><span class="o">=</span><span class="s1">&#39;./chroma_db&#39;</span><span class="p">)</span>
  1732. <span class="c1"># 假如你的向量数据库已经存在,那么可以直接加载</span>
  1733. <span class="c1"># chromadaDB = Chroma(persist_directory=&#39;./chroma_db&#39;, embedding_function=embedding)</span>
  1734. <span class="c1"># 4.使用向量数据库进行查询</span>
  1735. <span class="n">query</span> <span class="o">=</span> <span class="s2">&quot;1937年北京大学发生了什么?&quot;</span>
  1736. <span class="n">result</span> <span class="o">=</span> <span class="n">chromadaDB</span><span class="o">.</span><span class="n">similarity_search</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
  1737. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result--&gt;</span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1738. </code></pre></div>
  1739. <p>运行结果:</p>
  1740. <p><img alt="image-20251003101141993" src="assets/image-20251003101141993.png" /></p>
  1741. <h3 id="4_1">4 检索器<a class="headerlink" href="#4_1" title="Permanent link">&para;</a></h3>
  1742. <h4 id="41-langchain">4.1 LangChain的检索器定义<a class="headerlink" href="#41-langchain" title="Permanent link">&para;</a></h4>
  1743. <p>检索器是 LangChain 中负责信息检索的模块,通常与 索引(Indexes) 模块(如向量存储、嵌入模型)结合使用。它的核心功能是:</p>
  1744. <ul>
  1745. <li>输入:接收用户查询(通常是文本)。</li>
  1746. <li>处理:根据查询从数据源中检索相关内容。</li>
  1747. <li>输出:返回一组相关文档或文本片段(通常是 Document 对象列表)。</li>
  1748. </ul>
  1749. <p>检索器在以下场景中扮演关键角色:</p>
  1750. <ul>
  1751. <li>问答系统:从文档或知识库中检索答案的上下文。</li>
  1752. <li>语义搜索:根据查询的语义返回相关结果。</li>
  1753. <li>上下文增强:为语言模型提供外部知识,解决其知识局限。</li>
  1754. </ul>
  1755. <h4 id="42">4.2 检索器的工作原理<a class="headerlink" href="#42" title="Permanent link">&para;</a></h4>
  1756. <p>检索器通常与 向量存储(Vector Stores) 配合,通过嵌入模型(Embedding Models)将查询和文档转为向量,基于相似性进行检索。工作流程可以分为以下步骤:</p>
  1757. <ul>
  1758. <li>查询嵌入:将用户查询通过嵌入模型(如 OpenAIEmbeddings)转为向量表示</li>
  1759. <li>相似性搜索:在向量存储中查找与查询向量最相似的文档向量。</li>
  1760. <li>文档返回:返回匹配的文档(包含内容、元数据等)。</li>
  1761. <li>后处理(可选):对检索结果进行排序、过滤或重新排名。</li>
  1762. </ul>
  1763. <p>检索器的核心依赖:</p>
  1764. <ul>
  1765. <li>嵌入模型:将文本转为向量(如 OpenAIEmbeddings, HuggingFaceEmbeddings)。</li>
  1766. <li>向量存储:存储文档向量(如 Chroma、FAISS、Pinecone)。</li>
  1767. <li>相似性度量:如余弦相似度、欧几里得距离</li>
  1768. </ul>
  1769. <h4 id="43">4.3 检索器类型<a class="headerlink" href="#43" title="Permanent link">&para;</a></h4>
  1770. <p>langchain支持很多检索器<a href="https://python.langchain.com/docs/integrations/retrievers/">https://python.langchain.com/docs/integrations/retrievers/</a>,部分如下:</p>
  1771. <p><img alt="image-20250705114709874" src="assets/image-20250705114709874-17594578225791.png" /></p>
  1772. <p>此处我们讲解VectorStoreRetriever。</p>
  1773. <p>在 LangChain 中,as_retriever() 方法的 search_type 参数决定了向量检索的具体算法和行为。</p>
  1774. <div class="highlight"><pre><span></span><code><span class="n">retriever</span> <span class="o">=</span> <span class="n">vector_store</span><span class="o">.</span><span class="n">as_retriever</span><span class="p">(</span>
  1775. <span class="n">search_type</span><span class="o">=</span><span class="s2">&quot;similarity&quot;</span><span class="p">,</span> <span class="c1"># 可选 &quot;similarity&quot;|&quot;mmr&quot;|&quot;similarity_score_threshold&quot;</span>
  1776. <span class="n">search_kwargs</span><span class="o">=</span><span class="p">{</span>
  1777. <span class="s2">&quot;k&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="c1"># 返回结果数量</span>
  1778. <span class="s2">&quot;score_threshold&quot;</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">,</span> <span class="c1"># 仅当search_type=&quot;similarity_score_threshold&quot;时有效,低于阈值的都丢弃。</span>
  1779. <span class="s2">&quot;filter&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;source&quot;</span><span class="p">:</span> <span class="s2">&quot;重要文档.pdf&quot;</span><span class="p">},</span> <span class="c1"># 元数据过滤,只会检索满足条件的文档。</span>
  1780. <span class="s2">&quot;lambda_mult&quot;</span><span class="p">:</span> <span class="mf">0.25</span> <span class="c1"># 仅MMR搜索有效(控制多样性):接近 0 则更强调和查询的相关性;接近 1 则更强调结果之间的差异性</span>
  1781. <span class="p">}</span>
  1782. <span class="p">)</span>
  1783. </code></pre></div>
  1784. <p>以下是三种搜索类型的对比:</p>
  1785. <p><img alt="image-20250714160215042" src="assets/image-20250714160215042-17594581318012.png" /></p>
  1786. <p>示例代码:</p>
  1787. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_chroma</span><span class="w"> </span><span class="kn">import</span> <span class="n">Chroma</span>
  1788. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_ollama</span><span class="w"> </span><span class="kn">import</span> <span class="n">OllamaEmbeddings</span>
  1789. <span class="n">embedding</span> <span class="o">=</span> <span class="n">OllamaEmbeddings</span><span class="p">(</span><span class="n">model</span><span class="o">=</span><span class="s2">&quot;mxbai-embed-large&quot;</span><span class="p">)</span>
  1790. <span class="c1"># 向量数据库已经存在,那么可以直接加载</span>
  1791. <span class="n">chromadaDB</span> <span class="o">=</span> <span class="n">Chroma</span><span class="p">(</span><span class="n">persist_directory</span><span class="o">=</span><span class="s1">&#39;./chroma_db&#39;</span><span class="p">,</span> <span class="n">embedding_function</span><span class="o">=</span><span class="n">embedding</span><span class="p">)</span>
  1792. <span class="c1"># 使用向量数据库进行查询</span>
  1793. <span class="n">query</span> <span class="o">=</span> <span class="s2">&quot;1937年北京大学发生了什么?&quot;</span>
  1794. <span class="c1"># result = chromadaDB.similarity_search(query, k=2)</span>
  1795. <span class="c1"># 使用 as_retriever 方法返回 Retriever 对象,然后调用 invoke 方法进行查询</span>
  1796. <span class="n">retriever</span> <span class="o">=</span> <span class="n">chromadaDB</span><span class="o">.</span><span class="n">as_retriever</span><span class="p">(</span><span class="n">search_kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;k&quot;</span><span class="p">:</span><span class="mi">2</span><span class="p">})</span>
  1797. <span class="n">result</span> <span class="o">=</span> <span class="n">retriever</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
  1798. <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;result--&gt;</span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
  1799. </code></pre></div>
  1800. <p>运行结果:</p>
  1801. <p><img alt="image-20251003102843558" src="assets/image-20251003102843558.png" /></p>
  1802. <p><strong>拓展:</strong></p>
  1803. <p><code>vectordb.as_retriever()</code> 和 <code>vectordb.similarity_search()</code> 都是用于从向量数据库中检索相关文档的方法,它们有什么异同:</p>
  1804. <ul>
  1805. <li>
  1806. <p>相同</p>
  1807. <ul>
  1808. <li>核心功能:两者都基于向量相似度(如余弦相似度)从向量数据库中检索与查询最相关的文档。</li>
  1809. <li>底层技术:通常使用相同的嵌入模型和相似度计算方式(如 FAISS、Chroma、Pinecone 等)。</li>
  1810. </ul>
  1811. </li>
  1812. <li>
  1813. <p>不同</p>
  1814. <p><img alt="image-20250705114109276" src="assets/image-20250705114109276.png" /></p>
  1815. </li>
  1816. </ul>
  1817. <h4 id="44">4.4 拓展<a class="headerlink" href="#44" title="Permanent link">&para;</a></h4>
  1818. <p>其他几种常用的检索器介绍如下。</p>
  1819. <ul>
  1820. <li>TFIDFRetriever</li>
  1821. </ul>
  1822. <blockquote>
  1823. <p>功能:基于 TF-IDF(词频-逆文档频率)的检索器。 </p>
  1824. <p>特点:</p>
  1825. <ul>
  1826. <li>使用 TF-IDF 向量表示文档和查询。</li>
  1827. <li>适合快速构建原型。</li>
  1828. <li>不支持语义搜索。</li>
  1829. </ul>
  1830. <p>适用场景:</p>
  1831. <ul>
  1832. <li>文本搜索</li>
  1833. <li>关键词提取</li>
  1834. </ul>
  1835. <p><strong>补充:理解 TF 和 IDF</strong></p>
  1836. <p>为了理解后面的 BM25,可以先把 TF-IDF 拆成两个部分来看:</p>
  1837. <ul>
  1838. <li><strong>TF(Term Frequency,词频)</strong>:回答“这个词在当前文档中出现得多不多?”</li>
  1839. <li><strong>IDF(Inverse Document Frequency,逆文档频率)</strong>:回答“这个词在整个知识库中是否稀有?”</li>
  1840. </ul>
  1841. <p>常见公式如下:</p>
  1842. <div class="highlight"><pre><span></span><code>TF(t,d) = 词 t 在文档 d 中出现次数 / 文档 d 总词数
  1843. IDF(t) = log(N / df(t))
  1844. </code></pre></div>
  1845. <ul>
  1846. <li><code>N</code>:知识库文档总数。</li>
  1847. <li><code>df(t)</code>:包含词 <code>t</code> 的文档数量。</li>
  1848. </ul>
  1849. <p>一个词越普遍,<code>df(t)</code> 越大,IDF 越小;一个词越稀有,<code>df(t)</code> 越小,IDF 越大。</p>
  1850. <p>例如,知识库有 10 篇文档。当前 100 词的文章中,“asyncio”出现 4 次,整个知识库只有 2 篇包含它:</p>
  1851. <div class="highlight"><pre><span></span><code>TF = 4 / 100 = 0.04
  1852. IDF = ln(10 / 2) = ln(5) ≈ 1.609
  1853. TF-IDF = 0.04 × 1.609 ≈ 0.064
  1854. </code></pre></div>
  1855. <p>如果“使用”出现在全部 10 篇文档中,则 <code>IDF = ln(10 / 10) = 0</code>。即使它在某篇文章里出现很多次,最终 TF-IDF 权重也会很低,因为它缺乏区分主题的能力。</p>
  1856. <p>所以,TF-IDF 的核心思想是:<strong>一个词在当前文档中越常见,并且在整个知识库中越稀有,它越能代表当前文档的主题。</strong> BM25 正是在这个思想上继续加入了长度归一化和词频饱和控制。</p>
  1857. <p>示例代码:</p>
  1858. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.retrievers</span><span class="w"> </span><span class="kn">import</span> <span class="n">TFIDFRetriever</span>
  1859. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.documents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Document</span>
  1860. <span class="n">docs</span> <span class="o">=</span> <span class="p">[</span>
  1861. <span class="n">Document</span><span class="p">(</span><span class="n">page_content</span><span class="o">=</span><span class="s2">&quot;量子计算是一种基于量子力学的计算范式。&quot;</span><span class="p">),</span>
  1862. <span class="n">Document</span><span class="p">(</span><span class="n">page_content</span><span class="o">=</span><span class="s2">&quot;人工智能是模拟人类智能的技术。&quot;</span><span class="p">)</span>
  1863. <span class="p">]</span>
  1864. <span class="n">retriever</span> <span class="o">=</span> <span class="n">TFIDFRetriever</span><span class="o">.</span><span class="n">from_documents</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
  1865. <span class="n">retriever</span><span class="o">.</span><span class="n">k</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># 返回 1 个结果</span>
  1866. <span class="n">results</span> <span class="o">=</span> <span class="n">retriever</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;量子计算&quot;</span><span class="p">)</span>
  1867. <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
  1868. </code></pre></div>
  1869. <p>运行结果:</p>
  1870. <p><img src="assets/image-20251003104151768.png" alt="image-20251003104151768" style="zoom:80%;" /></p>
  1871. </blockquote>
  1872. <ul>
  1873. <li>BM25Retriever</li>
  1874. </ul>
  1875. <blockquote>
  1876. <p>BM25算法:BM25 是对 TF-IDF 的改进版本,在 TF-IDF 基础上做了归一化(防止长文档优势)与饱和控制(防止词频无限增长)。</p>
  1877. <p><img src="assets/image-20251003105157106.png" alt="image-20251003105157106" style="zoom: 60%;" /></p>
  1878. <p><img src="assets/image-20251006090343544.png" alt="image-20251006090343544" style="zoom:67%;" /></p>
  1879. <p>功能:基于 BM25 算法的关键词检索器,适合基于词频的搜索。</p>
  1880. <p>特点:</p>
  1881. <ul>
  1882. <li>不依赖嵌入模型,使用词频和逆文档频率(TF-IDF)计算相关性。</li>
  1883. <li>适合关键词匹配场景,计算成本低。</li>
  1884. <li>不支持语义搜索,效果依赖文本的字面匹配。</li>
  1885. </ul>
  1886. <p>适用场景:</p>
  1887. <ul>
  1888. <li>传统搜索场景。</li>
  1889. <li>关键词驱动的问答。</li>
  1890. </ul>
  1891. <p>环境依赖:</p>
  1892. <p>pip install rank_bm25</p>
  1893. <p>示例代码:</p>
  1894. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.retrievers</span><span class="w"> </span><span class="kn">import</span> <span class="n">BM25Retriever</span>
  1895. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.documents</span><span class="w"> </span><span class="kn">import</span> <span class="n">Document</span>
  1896. <span class="n">docs</span> <span class="o">=</span> <span class="p">[</span>
  1897. <span class="n">Document</span><span class="p">(</span><span class="n">page_content</span><span class="o">=</span><span class="s2">&quot;量子计算是一种基于量子力学的计算范式。&quot;</span><span class="p">),</span>
  1898. <span class="n">Document</span><span class="p">(</span><span class="n">page_content</span><span class="o">=</span><span class="s2">&quot;人工智能是模拟人类智能的技术。&quot;</span><span class="p">)</span>
  1899. <span class="p">]</span>
  1900. <span class="n">retriever</span> <span class="o">=</span> <span class="n">BM25Retriever</span><span class="o">.</span><span class="n">from_documents</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
  1901. <span class="n">retriever</span><span class="o">.</span><span class="n">k</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># 返回 1 个结果</span>
  1902. <span class="n">results</span> <span class="o">=</span> <span class="n">retriever</span><span class="o">.</span><span class="n">invoke</span><span class="p">(</span><span class="s2">&quot;量子计算&quot;</span><span class="p">)</span>
  1903. <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
  1904. </code></pre></div>
  1905. <p>运行结果:</p>
  1906. <p><img src="assets/image-20251003104151768.png" alt="image-20251003104151768" style="zoom:80%;" /></p>
  1907. </blockquote>
  1908. <ul>
  1909. <li>MultiQueryRetriever</li>
  1910. </ul>
  1911. <blockquote>
  1912. <p>功能:它借助 LLM 自动生成多个语义等价的改写查询,把用户的问题扩展成多个角度,然后对每个改写进行检索,最后合并结果,以提高召回率。 </p>
  1913. <p>特点:</p>
  1914. <ul>
  1915. <li>使用语言模型生成查询的多种表达方式</li>
  1916. <li>从向量存储中检索所有变体的结果并合并</li>
  1917. <li>提高召回率,适合复杂查询</li>
  1918. </ul>
  1919. <p>适用场景:</p>
  1920. <ul>
  1921. <li>查询表达不明确或需要覆盖多种语义</li>
  1922. <li>提高检索的全面性
  1923. </li>
  1924. </ul>
  1925. </blockquote>
  1926. <ul>
  1927. <li>EnsembleRetriever</li>
  1928. </ul>
  1929. <blockquote>
  1930. <p>功能:结合多种检索器(如 BM25 和向量存储),融合结果。</p>
  1931. <p>特点:</p>
  1932. <ul>
  1933. <li>结合关键词搜索和语义搜索的优点</li>
  1934. <li>支持加权融合,调整不同检索器的权重</li>
  1935. <li>提高召回率和精准度</li>
  1936. </ul>
  1937. <p>适用场景:</p>
  1938. <ul>
  1939. <li>需要综合关键词和语义的搜索</li>
  1940. <li>复杂查询场景
  1941. </li>
  1942. </ul>
  1943. </blockquote>
  1944. <ul>
  1945. <li>ContextualCompressionRetriever</li>
  1946. </ul>
  1947. <blockquote>
  1948. <p>功能:对检索结果进行压缩,提取最相关的内容 </p>
  1949. <p>特点:</p>
  1950. <ul>
  1951. <li>使用语言模型对检索到的文档进行重新排序或精炼</li>
  1952. <li>减少无关内容,提高结果质量</li>
  1953. <li>增加计算开销,但提升精准度</li>
  1954. </ul>
  1955. <p>适用场景:</p>
  1956. <ul>
  1957. <li>文档内容冗长,需要提取关键信息</li>
  1958. <li>提高问答系统的答案质量
  1959. </li>
  1960. </ul>
  1961. </blockquote>
  1962. <ul>
  1963. <li>Custom Retriever</li>
  1964. </ul>
  1965. <blockquote>
  1966. <p>功能:开发者可以自定义检索逻辑,适配特定数据源或算法 </p>
  1967. <p>特点:</p>
  1968. <ul>
  1969. <li>继承 BaseRetriever 类,实现 get_relevant_documents 方法</li>
  1970. <li>支持任意数据源(如数据库、API)</li>
  1971. </ul>
  1972. <p>适用场景:</p>
  1973. <ul>
  1974. <li>特定领域的数据源(如内部数据库)</li>
  1975. <li>自定义检索算法
  1976. </li>
  1977. </ul>
  1978. </blockquote>
  1979. <h2 id="agents">八、Agents<a class="headerlink" href="#agents" title="Permanent link">&para;</a></h2>
  1980. <h3 id="1-agent">1 Agent 概念<a class="headerlink" href="#1-agent" title="Permanent link">&para;</a></h3>
  1981. <p>Agent(智能体)是一种能够感知环境、进行决策和执行动作的智能实体。不同于传统的人工智能,Agent 具备通过主动思考、调用工具去逐步完成给定目标的能力。</p>
  1982. <p>为什么要调用工具?</p>
  1983. <ul>
  1984. <li>因为大模型虽然非常强大,但是也具备一定的局限性,比如不能回答实时信息、处理数学逻辑问题仍然非常的初级等等。因此,可以借助第三方工具来辅助大模型的应用。</li>
  1985. </ul>
  1986. <p>从大模型的角度来看,<strong>Agent其实就是基于大模型的语义理解和推理能力,让大模型拥有解决复杂问题时的任务规划能力,并调用外部工具来执行各种任务,利用向量数据库保留“记忆”的一个智能体</strong>。</p>
  1987. <blockquote>
  1988. <p>Agent = 大模型 + 任务规划(Planning) + 使用外部工具执行任务(Tools&amp;Action) + 记忆(Memory)</p>
  1989. <p>把Agent比作一个人的话,<strong>他应该有大脑(语义理解、存储记忆、推理规划、专业知识)、五官(接收文本、视觉输入、听觉输入等)、四肢(使用工具完成各种具体任务)等主要部件</strong></p>
  1990. </blockquote>
  1991. <hr />
  1992. <p><strong>工作流程概述:</strong></p>
  1993. <ul>
  1994. <li>用户提出任务。</li>
  1995. <li>Agent 启动: 将用户输入与预设的“提示词模板”结合,并结合当前的“上下文”和“变量”,形成一个完整的输入发送给大模型。</li>
  1996. <li>大模型思考与决策 (循环):<ul>
  1997. <li>大模型接收输入后,根据其内置的逻辑和提示词的指导,进行“思考”。</li>
  1998. <li>它会判断完成当前任务是需要继续使用工具来获取更多信息/执行操作,还是已经可以直接生成最终答案。</li>
  1999. <li>如果需要工具: 大模型会根据任务需求和对工具的描述,选择合适的工具,并生成执行该工具所需的输入参数。这些参数通常会从上下文或变量中提取。</li>
  2000. <li>工具执行: 选定的工具被调用,执行其功能。</li>
  2001. <li>结果反馈: 工具执行的结果会返回给 Agent,并被用来更新“上下文”和“变量”。</li>
  2002. <li>循环: Agent 将更新后的“上下文”、“变量”以及工具执行结果再次反馈给大模型,大模型继续进行新一轮的“思考-行动”循环,直到任务完成。</li>
  2003. <li>如果直接回答: 当大模型判断任务已完成,或无需额外工具即可回答时,它会生成最终的答案。</li>
  2004. </ul>
  2005. </li>
  2006. <li>用户输出: 最终答案被呈现给用户。</li>
  2007. </ul>
  2008. <h3 id="2-agent">2 Agent关键组成部分<a class="headerlink" href="#2-agent" title="Permanent link">&para;</a></h3>
  2009. <p><img alt="image-20250705115745718" src="assets/image-20250705115745718.png" /></p>
  2010. <ul>
  2011. <li>
  2012. <p>任务规划(Planning)</p>
  2013. <p>Agent需要提前将一项复杂任务拆解为多个更小、更易于处理的子任务,从而实现对复杂任务的高效处理</p>
  2014. </li>
  2015. <li>
  2016. <p>长短期记忆(Memory)</p>
  2017. <p>聊天上下文,长期保留和回忆信息</p>
  2018. </li>
  2019. <li>
  2020. <p>工具&amp;执行(Tools&amp;Action)</p>
  2021. <p>根据拆分好的子任务,调用外部提供好的专业API解决专业问题,完成一个个具体的子任务,并把处理结果返回给大模型</p>
  2022. </li>
  2023. </ul>
  2024. <h3 id="3-langchainagent">3 langchain实现Agent<a class="headerlink" href="#3-langchainagent" title="Permanent link">&para;</a></h3>
  2025. <p>LangChain 提供了不同类型的代理(主要罗列一下三种):</p>
  2026. <ul>
  2027. <li>
  2028. <p><strong>Zero-shot ReAct Description</strong></p>
  2029. <ul>
  2030. <li>
  2031. <p>基于 <strong>ReAct 框架</strong>(推理 + 行动),仅依赖工具的 <strong>描述</strong> 来决定调用哪个工具。</p>
  2032. </li>
  2033. <li>
  2034. <p>特点:无需额外示例(zero-shot),但 <strong>不具备记忆能力</strong>,每次推理都独立进行。</p>
  2035. </li>
  2036. <li>
  2037. <p>使用场景:简单任务,工具选择完全靠工具描述即可。</p>
  2038. </li>
  2039. </ul>
  2040. </li>
  2041. <li>
  2042. <p><strong>Structured Chat Zero-shot ReAct Description</strong></p>
  2043. <ul>
  2044. <li>
  2045. <p>同样基于 <strong>ReAct 框架</strong>,但可以处理 <strong>结构化输入</strong>,即支持带多个参数的工具(类似函数调用)。</p>
  2046. </li>
  2047. <li>
  2048. <p>特点:不仅能像第一种代理那样根据描述选择工具,还能正确组织并传递复杂参数。</p>
  2049. </li>
  2050. <li>
  2051. <p>使用场景:调用接口类工具、需要多参数输入的任务。</p>
  2052. </li>
  2053. </ul>
  2054. </li>
  2055. <li>
  2056. <p><strong>Conversational ReAct Description</strong></p>
  2057. <ul>
  2058. <li>
  2059. <p>在 ReAct 框架基础上,增强了 <strong>对话记忆能力</strong>。</p>
  2060. </li>
  2061. <li>
  2062. <p>特点:能根据上下文对话历史来做出工具选择和回应,更适合持续性对话场景。</p>
  2063. </li>
  2064. <li>
  2065. <p>使用场景:多轮对话,用户可能引用之前的内容或需要长期上下文跟踪。</p>
  2066. </li>
  2067. </ul>
  2068. </li>
  2069. </ul>
  2070. <hr />
  2071. <p>LangChain 中集成了很多工具,可以通过下面的方式进行查询:</p>
  2072. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.agent_toolkits.load_tools</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_all_tool_names</span>
  2073. <span class="n">results</span> <span class="o">=</span> <span class="n">get_all_tool_names</span><span class="p">()</span>
  2074. <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
  2075. </code></pre></div>
  2076. <p>运行结果:</p>
  2077. <div class="highlight"><pre><span></span><code>[&#39;sleep&#39;, &#39;wolfram-alpha&#39;, &#39;google-search&#39;, &#39;google-search-results-json&#39;, &#39;searx-search-results-json&#39;, &#39;bing-search&#39;, &#39;metaphor-search&#39;, &#39;ddg-search&#39;, &#39;google-books&#39;, &#39;google-lens&#39;, &#39;google-serper&#39;, &#39;google-scholar&#39;, &#39;google-finance&#39;, &#39;google-trends&#39;, &#39;google-jobs&#39;, &#39;google-serper-results-json&#39;, &#39;searchapi&#39;, &#39;searchapi-results-json&#39;, &#39;serpapi&#39;, &#39;dalle-image-generator&#39;, &#39;twilio&#39;, &#39;searx-search&#39;, &#39;merriam-webster&#39;, &#39;wikipedia&#39;, &#39;arxiv&#39;, &#39;golden-query&#39;, &#39;pubmed&#39;, &#39;human&#39;, &#39;awslambda&#39;, &#39;stackexchange&#39;, &#39;sceneXplain&#39;, &#39;graphql&#39;, &#39;openweathermap-api&#39;, &#39;dataforseo-api-search&#39;, &#39;dataforseo-api-search-json&#39;, &#39;eleven_labs_text2speech&#39;, &#39;google_cloud_texttospeech&#39;, &#39;read_file&#39;, &#39;reddit_search&#39;, &#39;news-api&#39;, &#39;tmdb-api&#39;, &#39;podcast-api&#39;, &#39;memorize&#39;, &#39;llm-math&#39;, &#39;open-meteo-api&#39;, &#39;requests&#39;, &#39;requests_get&#39;, &#39;requests_post&#39;, &#39;requests_patch&#39;, &#39;requests_put&#39;, &#39;requests_delete&#39;, &#39;terminal&#39;]
  2078. </code></pre></div>
  2079. <hr />
  2080. <p>接下来,通过一个示例来学习Agent的基本使用。</p>
  2081. <ul>
  2082. <li>问题1:计算一下300的25%是多少?</li>
  2083. <li>问题2:请帮我介绍一下故宫</li>
  2084. </ul>
  2085. <p>示例代码:</p>
  2086. <blockquote>
  2087. <p>需要提前安装 wikipedia</p>
  2088. <p>pip install wikipedia</p>
  2089. </blockquote>
  2090. <div class="highlight"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">langchain_core.messages</span><span class="w"> </span><span class="kn">import</span> <span class="n">HumanMessage</span>
  2091. <span class="kn">from</span><span class="w"> </span><span class="nn">langgraph.checkpoint.memory</span><span class="w"> </span><span class="kn">import</span> <span class="n">MemorySaver</span>
  2092. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain.agents</span><span class="w"> </span><span class="kn">import</span> <span class="n">create_agent</span>
  2093. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_community.agent_toolkits.load_tools</span><span class="w"> </span><span class="kn">import</span> <span class="n">load_tools</span>
  2094. <span class="kn">from</span><span class="w"> </span><span class="nn">langchain_openai</span><span class="w"> </span><span class="kn">import</span> <span class="n">ChatOpenAI</span>
  2095. <span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
  2096. <span class="c1"># 实例化模型</span>
  2097. <span class="n">model</span> <span class="o">=</span> <span class="n">ChatOpenAI</span><span class="p">(</span>
  2098. <span class="n">base_url</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;base_url&#39;</span><span class="p">,</span><span class="s1">&#39;https://dashscope.aliyuncs.com/compatible-mode/v1&#39;</span><span class="p">),</span>
  2099. <span class="n">model</span><span class="o">=</span><span class="s1">&#39;qwen-plus&#39;</span><span class="p">,</span>
  2100. <span class="n">openai_api_key</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;api_key&#39;</span><span class="p">,</span><span class="s1">&#39;sk-XXXXXXXX&#39;</span><span class="p">),</span>
  2101. <span class="n">max_tokens</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
  2102. <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span>
  2103. <span class="p">)</span>
  2104. <span class="c1"># Create the agent</span>
  2105. <span class="n">memory</span> <span class="o">=</span> <span class="n">MemorySaver</span><span class="p">()</span>
  2106. <span class="n">tools</span> <span class="o">=</span> <span class="n">load_tools</span><span class="p">([</span><span class="s1">&#39;wikipedia&#39;</span><span class="p">,</span> <span class="s1">&#39;llm-math&#39;</span><span class="p">],</span> <span class="n">llm</span><span class="o">=</span><span class="n">model</span><span class="p">)</span>
  2107. <span class="n">agent_executor</span> <span class="o">=</span> <span class="n">create_agent</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">tools</span><span class="p">,</span> <span class="n">checkpointer</span><span class="o">=</span><span class="n">memory</span><span class="p">)</span>
  2108. <span class="c1"># Use the agent</span>
  2109. <span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;configurable&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;thread_id&quot;</span><span class="p">:</span> <span class="s2">&quot;abc123&quot;</span><span class="p">}}</span>
  2110. <span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="n">agent_executor</span><span class="o">.</span><span class="n">stream</span><span class="p">(</span>
  2111. <span class="p">{</span><span class="s2">&quot;messages&quot;</span><span class="p">:</span> <span class="p">[</span><span class="n">HumanMessage</span><span class="p">(</span><span class="n">content</span><span class="o">=</span><span class="s2">&quot;计算一下300的25%是多少?&quot;</span><span class="p">)]},</span> <span class="n">config</span>
  2112. <span class="p">):</span>
  2113. <span class="nb">print</span><span class="p">(</span><span class="n">chunk</span><span class="p">)</span>
  2114. <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;----&quot;</span><span class="p">)</span>
  2115. <span class="c1"># for chunk in agent_executor.stream(</span>
  2116. <span class="c1"># {&quot;messages&quot;: [HumanMessage(content=&quot;大熊猫是哪个国家的国宝?&quot;)]}, config</span>
  2117. <span class="c1"># ):</span>
  2118. <span class="c1"># print(chunk)</span>
  2119. <span class="c1"># print(&quot;----&quot;)</span>
  2120. </code></pre></div>
  2121. <p>运行结果:</p>
  2122. <p><img alt="1768397211211" src="assets/1768397211211.png" /></p>
  2123. <blockquote>
  2124. <p>参考官网 <a href="https://python.langchain.com/docs/how_to/custom_tools/">https://python.langchain.com/docs/how_to/custom_tools/</a></p>
  2125. </blockquote>
  2126. <h2 id="langchain">九、LangChain使用场景<a class="headerlink" href="#langchain" title="Permanent link">&para;</a></h2>
  2127. <ul>
  2128. <li>个人助手</li>
  2129. <li>基于文档的问答系统</li>
  2130. <li>聊天机器人</li>
  2131. <li>Tabular数据查询</li>
  2132. <li>API交互</li>
  2133. <li>信息提取</li>
  2134. <li>文档总结</li>
  2135. </ul>
  2136. <h2 id="_3">十、本节小结<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h2>
  2137. <p>本章主要介绍了LangChain的基本组件及使用方式。</p>
  2138. <h2 id="_4">十一、本节作业<a class="headerlink" href="#_4" title="Permanent link">&para;</a></h2>
  2139. <h3 id="1-1">1 作业1<a class="headerlink" href="#1-1" title="Permanent link">&para;</a></h3>
  2140. <ul>
  2141. <li>题目1:什么是LangChain?请解释其核心组件和设计思想。</li>
  2142. <li>题目2:解释LangChain中的链(Chain)概念,并介绍主要的链类型。</li>
  2143. <li>题目3:解释LangChain中的Prompts概念,并介绍主要类型。</li>
  2144. <li>题目4:实现LangChain中的output_parsers的具体使用方式</li>
  2145. </ul>
  2146. <h3 id="2-2">2 作业2<a class="headerlink" href="#2-2" title="Permanent link">&para;</a></h3>
  2147. <ul>
  2148. <li>题目1:什么是Memory组件?请解释LangChain中不同类型的记忆机制。</li>
  2149. <li>题目2:解释LangChain中的提示工程及其最佳实践。</li>
  2150. <li>题目3:LangChain的Document Loaders?请介绍其功能和主要类型。</li>
  2151. <li>题目4 :什么是LangChain的代理(Agent)?请说明其工作原理和应用。</li>
  2152. </ul>
  2153. </article>
  2154. </div>
  2155. <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
  2156. </div>
  2157. </main>
  2158. <footer class="md-footer">
  2159. <div class="md-footer-meta md-typeset">
  2160. <div class="md-footer-meta__inner md-grid">
  2161. <div class="md-copyright">
  2162. <div class="md-copyright__highlight">
  2163. © EnterpriseKB-RAG 2026. Internal knowledge base demo site.
  2164. </div>
  2165. Made with
  2166. <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
  2167. Material for MkDocs
  2168. </a>
  2169. </div>
  2170. </div>
  2171. </div>
  2172. </footer>
  2173. </div>
  2174. <div class="md-dialog" data-md-component="dialog">
  2175. <div class="md-dialog__inner md-typeset"></div>
  2176. </div>
  2177. <script id="__config" type="application/json">{"base": "..", "features": [], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "\u5df2\u590d\u5236", "clipboard.copy": "\u590d\u5236", "search.result.more.one": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.other": "\u5728\u8be5\u9875\u4e0a\u8fd8\u6709 # \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.term.missing": "\u7f3a\u5c11", "select.version": "\u9009\u62e9\u5f53\u524d\u7248\u672c"}, "version": null}</script>
  2178. <script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
  2179. <script src="../javascripts/extra.js"></script>
  2180. <script src="../javascripts/mathjax.js"></script>
  2181. <!-- <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>-->
  2182. <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
  2183. </body>
  2184. </html>