| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243 |
- <!doctype html>
- <html lang="zh" class="no-js">
- <head>
-
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width,initial-scale=1">
-
-
-
-
- <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">
-
-
- <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">
-
-
- <link rel="icon" href="../img/AI.jpg">
- <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
-
-
-
- <title>2.2 LangChain基础知识.md - 企业知识库RAG智能问答项目V1.0</title>
-
-
-
- <link rel="stylesheet" href="../assets/stylesheets/main.2a3383ac.min.css">
-
-
-
-
-
-
-
-
-
-
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
- <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">
- <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
-
-
-
- <link rel="stylesheet" href="../stylesheets/extra.css">
-
- <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>
-
-
-
-
-
- </head>
-
-
- <body dir="ltr">
-
-
- <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
- <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
- <label class="md-overlay" for="__drawer"></label>
- <div data-md-component="skip">
-
-
- <a href="#_1" class="md-skip">
- 跳转至
- </a>
-
- </div>
- <div data-md-component="announce">
-
- </div>
-
-
-
-
- <header class="md-header md-header--shadow" data-md-component="header">
- <nav class="md-header__inner md-grid" aria-label="页眉">
- <a href="../index.html" title="企业知识库RAG智能问答项目V1.0" class="md-header__button md-logo" aria-label="企业知识库RAG智能问答项目V1.0" data-md-component="logo">
-
- <img src="../img/AI.jpg" alt="logo">
- </a>
- <label class="md-header__button md-icon" for="__drawer">
-
- <svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"></path></svg>
- </label>
- <div class="md-header__title" data-md-component="header-title">
- <div class="md-header__ellipsis">
- <div class="md-header__topic">
- <span class="md-ellipsis">
- 企业知识库RAG智能问答项目V1.0
- </span>
- </div>
- <div class="md-header__topic" data-md-component="header-topic">
- <span class="md-ellipsis">
-
- 2.2 LangChain基础知识.md
-
- </span>
- </div>
- </div>
- </div>
-
-
- <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>
-
-
-
-
-
- <label class="md-header__button md-icon" for="__search">
-
- <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"></path></svg>
- </label>
- <div class="md-search" data-md-component="search" role="dialog">
- <label class="md-search__overlay" for="__search"></label>
- <div class="md-search__inner" role="search">
- <form class="md-search__form" name="search">
- <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>
- <label class="md-search__icon md-icon" for="__search">
-
- <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"></path></svg>
-
- <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"></path></svg>
- </label>
- <nav class="md-search__options" aria-label="查找">
-
- <button type="reset" class="md-search__icon md-icon" title="清空当前内容" aria-label="清空当前内容" tabindex="-1">
-
- <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"></path></svg>
- </button>
- </nav>
-
- </form>
- <div class="md-search__output">
- <div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
- <div class="md-search-result" data-md-component="search-result">
- <div class="md-search-result__meta">
- 正在初始化搜索引擎
- </div>
- <ol class="md-search-result__list" role="presentation"></ol>
- </div>
- </div>
- </div>
- </div>
- </div>
-
-
-
- </nav>
-
- </header>
-
- <div class="md-container" data-md-component="container">
-
-
-
-
-
-
- <main class="md-main" data-md-component="main">
- <div class="md-main__inner md-grid">
-
-
-
- <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation">
- <div class="md-sidebar__scrollwrap">
- <div class="md-sidebar__inner">
-
- <nav class="md-nav md-nav--primary" aria-label="导航栏" data-md-level="0">
- <label class="md-nav__title" for="__drawer">
- <a href="../index.html" title="企业知识库RAG智能问答项目V1.0" class="md-nav__button md-logo" aria-label="企业知识库RAG智能问答项目V1.0" data-md-component="logo">
-
- <img src="../img/AI.jpg" alt="logo">
- </a>
- 企业知识库RAG智能问答项目V1.0
- </label>
-
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <a href="../index.html" class="md-nav__link">
-
-
-
- <span class="md-ellipsis">
- 知识库内容
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2">
-
-
- <label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ① 项目概述
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_2">
- <span class="md-nav__icon md-icon"></span>
- ① 项目概述
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 1.1 项目架构
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 1.2 项目环境(window)
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 1.3 项目环境(mac)
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--active md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
-
-
- <label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ② 项目工具
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
- <label class="md-nav__title" for="__nav_3">
- <span class="md-nav__icon md-icon"></span>
- ② 项目工具
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 2.1 Ollama大模型高效管理工具
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--active">
- <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">
-
-
-
- <span class="md-ellipsis">
- 2.2 LangChain基础知识.md
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 2.3 向量索引:HNSW、IVF与IVF_PQ
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 2.4 Milvus向量数据库
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4">
-
-
- <label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ③ 基于Mysql库的问答系统
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_4">
- <span class="md-nav__icon md-icon"></span>
- ③ 基于Mysql库的问答系统
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 3.1 Python日志介绍与应用
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 3.2 Redis数据库简介与使用
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 3.3 基于Mysql数据库实现问答系统
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 3.4 BM25算法简介与应用
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5">
-
-
- <label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ④ 基于Milvus库的问答系统
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_5">
- <span class="md-nav__icon md-icon"></span>
- ④ 基于Milvus库的问答系统
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 4.1 整体架构与工程流程
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 4.2 基础模块
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 4.3 文档处理模块
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 4.4 向量存储
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item"><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%20BERT%E5%9F%BA%E7%A1%80%E4%B8%8E%E4%BB%BB%E5%8A%A1%E5%BE%AE%E8%B0%83.html" class="md-nav__link"><span class="md-ellipsis">4.5 BERT基础与任务微调</span></a></li><li class="md-nav__item">
- <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%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">
-
-
-
- <span class="md-ellipsis">
- 4.6 prompts设计与query意图识别
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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%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">
-
-
-
- <span class="md-ellipsis">
- 4.7 检索策略与RAG系统设计
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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%20RAG%E7%B3%BB%E7%BB%9F%E8%BF%90%E8%A1%8C.html" class="md-nav__link">
-
-
-
- <span class="md-ellipsis">
- 4.8 RAG系统运行
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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%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">
-
-
-
- <span class="md-ellipsis">
- 4.9 文档解析工具(扩展资料)
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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.10%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">
-
-
-
- <span class="md-ellipsis">
- 4.10 RAG中的Query改写(扩展资料)
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 数据集生成与优化(扩展资料)
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6">
-
-
- <label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ⑤ RAG系统评估
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_6">
- <span class="md-nav__icon md-icon"></span>
- ⑤ RAG系统评估
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 5.1 RAG系统评估工具
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 5.2 实现企业知识库RAG系统的评估
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 5.3 RAG评估数据集的构造(扩展)
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_7">
-
-
- <label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ⑥ 融合Mysql的RAG系统
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_7">
- <span class="md-nav__icon md-icon"></span>
- ⑥ 融合Mysql的RAG系统
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 6.1 融合FQA和知识库查询
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 6.2 融合FAQ 和知识库查询(优化版)
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 6.3 基于 FastAPI 的 FAQ 与知识库查询接口
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 6.4 FastAPI和Flask的区别和联系(扩展资料)
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item md-nav__item--nested">
-
-
-
- <input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_8">
-
-
- <label class="md-nav__link" for="__nav_8" id="__nav_8_label" tabindex="0">
-
-
-
- <span class="md-ellipsis">
- ⑦ 企业级生产环境部署
-
- </span>
-
- <span class="md-nav__icon md-icon"></span>
- </label>
-
- <nav class="md-nav" data-md-level="1" aria-labelledby="__nav_8_label" aria-expanded="false">
- <label class="md-nav__title" for="__nav_8">
- <span class="md-nav__icon md-icon"></span>
- ⑦ 企业级生产环境部署
- </label>
- <ul class="md-nav__list" data-md-scrollfix>
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 7.1 Docker的原理和基本使用
-
- </span>
-
- </a>
- </li>
-
-
-
-
-
-
-
-
-
- <li class="md-nav__item">
- <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">
-
-
-
- <span class="md-ellipsis">
- 7.2 服务部署
-
- </span>
-
- </a>
- </li>
-
-
-
- </ul>
- </nav>
-
- </li>
-
-
- </ul>
- </nav>
- </div>
- </div>
- </div>
-
-
-
- <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc">
- <div class="md-sidebar__scrollwrap">
- <div class="md-sidebar__inner">
-
- <nav class="md-nav md-nav--secondary" aria-label="目录">
-
-
-
-
- <label class="md-nav__title" for="__toc">
- <span class="md-nav__icon md-icon"></span>
- 目录
- </label>
- <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
-
- <li class="md-nav__item">
- <a href="#_1" class="md-nav__link">
- <span class="md-ellipsis">
- 学习目标
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#_2" class="md-nav__link">
- <span class="md-ellipsis">
- 一、简述
- </span>
- </a>
-
- <nav class="md-nav" aria-label="一、简述">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-langchain" class="md-nav__link">
- <span class="md-ellipsis">
- 1 什么是LangChain
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2" class="md-nav__link">
- <span class="md-ellipsis">
- 2 主要组件
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#3-langchain" class="md-nav__link">
- <span class="md-ellipsis">
- 3 LangChain核心包
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#4" class="md-nav__link">
- <span class="md-ellipsis">
- 4 环境准备
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#models" class="md-nav__link">
- <span class="md-ellipsis">
- 二、Models
- </span>
- </a>
-
- <nav class="md-nav" aria-label="二、Models">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-llms" class="md-nav__link">
- <span class="md-ellipsis">
- 1 LLMs
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2-chat-models" class="md-nav__link">
- <span class="md-ellipsis">
- 2 Chat Models
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#3-embeddings-models" class="md-nav__link">
- <span class="md-ellipsis">
- 3 Embeddings Models
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#prompts" class="md-nav__link">
- <span class="md-ellipsis">
- 三、Prompts
- </span>
- </a>
-
- <nav class="md-nav" aria-label="三、Prompts">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-prompt" class="md-nav__link">
- <span class="md-ellipsis">
- 1 通用prompt
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2-chatprompts" class="md-nav__link">
- <span class="md-ellipsis">
- 2 ChatPrompts
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#chains" class="md-nav__link">
- <span class="md-ellipsis">
- 四、Chains
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#output_parsers" class="md-nav__link">
- <span class="md-ellipsis">
- 五、output_parsers
- </span>
- </a>
-
- <nav class="md-nav" aria-label="五、output_parsers">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1" class="md-nav__link">
- <span class="md-ellipsis">
- 1 字符串解析器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2_1" class="md-nav__link">
- <span class="md-ellipsis">
- 2 列表解析器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#3-json" class="md-nav__link">
- <span class="md-ellipsis">
- 3 JSON解析器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#4-pydantic" class="md-nav__link">
- <span class="md-ellipsis">
- 4 Pydantic解析器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#5" class="md-nav__link">
- <span class="md-ellipsis">
- 5 自定义解析器
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#memory" class="md-nav__link">
- <span class="md-ellipsis">
- 六、Memory
- </span>
- </a>
-
- <nav class="md-nav" aria-label="六、Memory">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-short-term-memory" class="md-nav__link">
- <span class="md-ellipsis">
- 1 短期记忆(Short-term Memory)
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2_2" class="md-nav__link">
- <span class="md-ellipsis">
- 2 长期记忆
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#indexes" class="md-nav__link">
- <span class="md-ellipsis">
- 七、Indexes
- </span>
- </a>
-
- <nav class="md-nav" aria-label="七、Indexes">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1_1" class="md-nav__link">
- <span class="md-ellipsis">
- 1 文档加载器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2_3" class="md-nav__link">
- <span class="md-ellipsis">
- 2 文档分割器
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#3-vectorstores" class="md-nav__link">
- <span class="md-ellipsis">
- 3 VectorStores
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#4_1" class="md-nav__link">
- <span class="md-ellipsis">
- 4 检索器
- </span>
- </a>
-
- <nav class="md-nav" aria-label="4 检索器">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#41-langchain" class="md-nav__link">
- <span class="md-ellipsis">
- 4.1 LangChain的检索器定义
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#42" class="md-nav__link">
- <span class="md-ellipsis">
- 4.2 检索器的工作原理
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#43" class="md-nav__link">
- <span class="md-ellipsis">
- 4.3 检索器类型
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#44" class="md-nav__link">
- <span class="md-ellipsis">
- 4.4 拓展
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#agents" class="md-nav__link">
- <span class="md-ellipsis">
- 八、Agents
- </span>
- </a>
-
- <nav class="md-nav" aria-label="八、Agents">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-agent" class="md-nav__link">
- <span class="md-ellipsis">
- 1 Agent 概念
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2-agent" class="md-nav__link">
- <span class="md-ellipsis">
- 2 Agent关键组成部分
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#3-langchainagent" class="md-nav__link">
- <span class="md-ellipsis">
- 3 langchain实现Agent
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#langchain" class="md-nav__link">
- <span class="md-ellipsis">
- 九、LangChain使用场景
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#_3" class="md-nav__link">
- <span class="md-ellipsis">
- 十、本节小结
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#_4" class="md-nav__link">
- <span class="md-ellipsis">
- 十一、本节作业
- </span>
- </a>
-
- <nav class="md-nav" aria-label="十一、本节作业">
- <ul class="md-nav__list">
-
- <li class="md-nav__item">
- <a href="#1-1" class="md-nav__link">
- <span class="md-ellipsis">
- 1 作业1
- </span>
- </a>
-
- </li>
-
- <li class="md-nav__item">
- <a href="#2-2" class="md-nav__link">
- <span class="md-ellipsis">
- 2 作业2
- </span>
- </a>
-
- </li>
-
- </ul>
- </nav>
-
- </li>
-
- </ul>
-
- </nav>
- </div>
- </div>
- </div>
-
-
-
- <div class="md-content" data-md-component="content">
- <article class="md-content__inner md-typeset">
-
-
- <h1>2.2 LangChain基础知识.md</h1>
- <h2 id="_1">学习目标<a class="headerlink" href="#_1" title="Permanent link">¶</a></h2>
- <ul>
- <li>熟悉什么是LangChain及其作用</li>
- <li>熟悉LangChain中基本组件及使用</li>
- </ul>
- <h2 id="_2">一、简述<a class="headerlink" href="#_2" title="Permanent link">¶</a></h2>
- <h3 id="1-langchain">1 什么是LangChain<a class="headerlink" href="#1-langchain" title="Permanent link">¶</a></h3>
- <p>LangChain由 Harrison Chase 创建于2022年10月,它是围绕LLMs(大语言模型)建立的一个框架,它的核心理念是为各种LLMs实现通用的接口,把LLMs相关的组件“链接”在一起,简化LLMs应用的开发难度,方便开发者快速地开发复杂的LLMs应用。</p>
- <blockquote>
- <p>LangChain 最初是于 2022 年 10 月开源的一个项目,在 GitHub 上获得大量关注之后迅速转变为一家初创公司。2017 年 Harrison Chase 还在哈佛上大学,如今已是硅谷的一家热门初创公司的 CEO,这对他来说是一次重大而迅速的跃迁。Insider 独家报道,人工智能初创公司 LangChain 在种子轮一周后,再次获得红杉领投的 2000 万至 2500 万美元融资,估值达到 2 亿美元。</p>
- </blockquote>
- <p><strong>LangChain官网</strong>:<a href="https://python.langchain.com/docs/introduction/">https://python.langchain.com/docs/introduction/</a></p>
- <p><strong>LangChain官网中文版</strong>:<a href="https://www.langchain.com.cn/">https://www.langchain.com.cn/</a></p>
- <p>LangChain 简化了 LLM 应用程序生命周期的每个阶段:</p>
- <ul>
- <li>开发:使用 LangChain 的开源组件和第三方集成构建应用程序。使用 LangGraph 构建具有一流流式和人机交互支持的状态智能体。</li>
- <li>生产化:使用 LangSmith 检查、监控和评估应用程序,方便持续优化和部署。</li>
- <li>部署:使用 LangGraph平台 将应用程序转变为可用于生产的 API 和助手。</li>
- </ul>
- <h3 id="2">2 主要组件<a class="headerlink" href="#2" title="Permanent link">¶</a></h3>
- <p><img alt="image-20250703152303288" src="assets/image-20250703152303288.png"></p>
- <ul>
- <li>Models:模型,各种类型的模型和模型集成,比如GPT-4</li>
- <li>Prompts:提示,包括提示管理、提示优化和提示序列化</li>
- <li>Chains:链,一系列对各种组件的调用</li>
- <li>Memory:记忆,用来保存和模型交互时的上下文状态</li>
- <li>Indexes:索引,用来结构化文档,以便和模型交互</li>
- <li>Agents:代理,决定模型采取哪些行动,执行并且观察流程,直到完成为止</li>
- </ul>
- <h3 id="3-langchain">3 LangChain核心包<a class="headerlink" href="#3-langchain" title="Permanent link">¶</a></h3>
- <ul>
- <li><strong>langchain-core</strong>:聊天模型和其他组件的基础抽象。</li>
- <li>
- <p><strong>集成包(例如 langchain-openai、langchain-anthropic 等)</strong>:重要的集成被拆分为轻量级的独立包,由 LangChain 团队和集成方共同维护。</p>
- </li>
- <li>
- <p><strong>langchain</strong>:包含链(chains)、智能体(agents)和检索策略,这些构成了应用的认知架构。</p>
- </li>
- <li>
- <p><strong>langchain-community</strong>:由社区维护的第三方集成。</p>
- </li>
- <li>
- <p><strong>langgraph</strong>:一个编排框架,用于将 LangChain 组件组合成可用于生产的应用,支持持久化、流式处理及其他关键特性。</p>
- </li>
- </ul>
- <h3 id="4">4 环境准备<a class="headerlink" href="#4" title="Permanent link">¶</a></h3>
- <p>本知识文档以LangChain+Qwen进行学习,需要提前安装</p>
- <blockquote>
- <p>pip install openai</p>
- <p>pip install langchain </p>
- <p>pip install modelscope</p>
- </blockquote>
- <p>借助阿里云-百炼平台(需要申请API Key 以及Secret Key):</p>
- <blockquote>
- <p><a href="https://bailian.console.aliyun.com/#/home">https://bailian.console.aliyun.com/#/home</a></p>
- </blockquote>
- <h2 id="models">二、Models<a class="headerlink" href="#models" title="Permanent link">¶</a></h2>
- <p>现在市面上的模型多如牛毛,各种各样的模型不断出现,LangChain模型组件提供了与各种模型的集成,并为所有模型提供一个精简的统一接口。</p>
- <p>LangChain目前支持三种类型的模型:LLMs、Chat Models(聊天模型)、Embeddings Models(嵌入模型)。</p>
- <ul>
- <li>LLMs:大语言模型接收文本字符作为输入,返回的也是文本字符。</li>
- <li>聊天模型:基于LLMs, 不同的是它接收聊天消(一种特定格式的数据)作为输入,返回的也是聊天消息。</li>
- <li>文本嵌入模型:文本嵌入模型接收文本作为输入, 返回的是浮点数列表。</li>
- </ul>
- <p><img alt="image-20250704171332127" src="assets/image-20250704171332127.png"></p>
- <p>LangChain支持的三类模型,它们的使用场景不同,输入和输出不同,开发者需要根据项目需要选择相应的模型。</p>
- <h3 id="1-llms">1 LLMs<a class="headerlink" href="#1-llms" title="Permanent link">¶</a></h3>
- <p>LLMs(大语言模型)使用场景最多,常用大模型的下载库:</p>
- <blockquote>
- <p><a href="https://huggingface.co/models">https://huggingface.co/models</a></p>
- <p><a href="https://modelscope.cn/models">https://modelscope.cn/models</a></p>
- </blockquote>
- <p>下面Qwen为例进行讲解。</p>
- <hr>
- <p>模型调用有2种方式:</p>
- <ul>
- <li>通过ChatOpenAI进行调用</li>
- </ul>
- <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>
- <span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
- <span class="c1"># 实例化模型</span>
- <span class="n">model</span> <span class="o">=</span> <span class="n">ChatOpenAI</span><span class="p">(</span>
- <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">'base_url'</span><span class="p">,</span><span class="s1">'https://dashscope.aliyuncs.com/compatible-mode/v1'</span><span class="p">),</span>
- <span class="n">model</span><span class="o">=</span><span class="s1">'qwen-plus'</span><span class="p">,</span>
- <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">'api_key'</span><span class="p">,</span><span class="s1">'sk-XXXXXX'</span><span class="p">),</span>
- <span class="n">max_tokens</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
- <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span>
- <span class="p">)</span>
- <span class="c1"># 获取问答结果</span>
- <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">"帮我讲个笑话吧"</span><span class="p">)</span>
- <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>
- </code></pre></div>
- <ul>
- <li>通过Ollama进行调用 <a href="https://ollama.com/">Ollama支持模型</a></li>
- </ul>
- <div class="highlight"><pre><span></span><code><span class="c1"># from langchain_community.llms import Ollama # Langchain 0.x版本使用</span>
- <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>
- <span class="c1"># 实例化模型</span>
- <span class="c1"># model = Ollama(model="qwen2.5:7b") # Langchain 0.x版本使用</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 获取问答结果</span>
- <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">"请给我讲个笑话吧"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- </code></pre></div>
- <h3 id="2-chat-models">2 Chat Models<a class="headerlink" href="#2-chat-models" title="Permanent link">¶</a></h3>
- <p>聊天模型,聊天消息包含下面几种类型,使用时需要按照约定传入合适的值:</p>
- <ul>
- <li>
- <p><strong>AIMessage</strong>: 就是 AI 输出的消息,可以是针对问题的回答.</p>
- </li>
- <li>
- <p><strong>HumanMessage</strong>: 人类消息就是用户信息,由人给出的信息发送给LLMs的提示信息,比如“实现一个快速排序方法”.</p>
- </li>
- <li>
- <p><strong>SystemMessage</strong>: 可以用于指定模型具体所处的环境和背景,如角色扮演等。你可以在这里给出具体的指示,比如“作为一个代码专家”,或者“返回json格式”.</p>
- </li>
- <li>
- <p><strong>ChatMessage</strong>: Chat 消息可以接受任意角色的参数,但是在大多数时间,我们应该使用上面的三种类型.</p>
- </li>
- </ul>
- <p>LangChain支持大量的chat 模型,可以通过官网查询:</p>
- <blockquote>
- <p><a href="https://python.langchain.com/docs/integrations/chat/">https://python.langchain.com/docs/integrations/chat/</a></p>
- </blockquote>
- <p>也可以通过langchain源码查看</p>
- <p><img alt="image-20250704174858064" src="assets/image-20250704174858064.png"></p>
- <ul>
- <li>SystemMessage+HumanMessage+AIMessage</li>
- </ul>
- <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>
- <span class="c1"># from langchain_community.chat_models import ChatOllama # Langchain 0.x版本使用</span>
- <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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 定义提示词</span>
- <span class="n">messages</span> <span class="o">=</span> <span class="p">[</span>
- <span class="n">SystemMessage</span><span class="p">(</span><span class="n">content</span><span class="o">=</span><span class="s2">"现在你是一个著名的诗人"</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">"给我写一首唐诗"</span><span class="p">)]</span>
- <span class="c1"># 获取问答结果</span>
- <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>
- <span class="c1"># print(result)</span>
- <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>
- </code></pre></div>
- <p><img src="assets/1762153476605.png" alt="image-20251004021532441" style="zoom:50%;"></p>
- <h3 id="3-embeddings-models">3 Embeddings Models<a class="headerlink" href="#3-embeddings-models" title="Permanent link">¶</a></h3>
- <p>Embeddings Models(嵌入模型)特点:将字符串作为输入,返回一个浮动数的列表。在NLP中,Embedding的作用就是将数据进行文本向量化。</p>
- <div align="center"><img src="assets/6-4.png" style="zoom:40%"><img></div>
- <p>Embeddings Models可以为文本创建向量映射,这样就能在向量空间里去考虑文本,执行诸如语义搜索之类的操作,比如说寻找相似的文本片段。</p>
- <blockquote>
- <p><a href="https://python.langchain.com/docs/integrations/text_embedding/">https://python.langchain.com/docs/integrations/text_embedding/</a></p>
- </blockquote>
- <hr>
- <p>不同的Embedding模型对多语言支持和文本类型有不同的特点:</p>
- <ul>
- <li><strong>多语言支持</strong>:<ul>
- <li><code>text-embedding-ada-002</code>:支持多种语言,但对中文等亚洲语言的支持相对较弱</li>
- <li><code>bge-large-zh</code>:对中文有很好的支持</li>
- <li><code>multilingual-e5-large</code>:对多语言都有较好的支持</li>
- <li>mxbai-embed-large:</li>
- </ul>
- </li>
- <li><strong>文本类型适用性</strong>:<ul>
- <li>代码文本:建议使用专门的代码Embedding模型,如 <code>CodeBERT</code></li>
- <li>通用文本:可以使用<code>text-embedding-ada-002</code>或 <code>bge-large-zh</code></li>
- <li>专业领域文本:建议使用该领域的专门模型</li>
- </ul>
- </li>
- </ul>
- <p>可以参考MTEB(大规模文本嵌入基准)排行榜以获取最新模型效果:<a href="https://huggingface.co/spaces/mteb/leaderboard">https://huggingface.co/spaces/mteb/leaderboard</a></p>
- <p>接下来以一个文本嵌入模型的例子进行说明:</p>
- <div class="highlight"><pre><span></span><code><span class="c1"># from langchain_community.embeddings import OllamaEmbeddings # Langchain 0.x版本使用</span>
- <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>
- <span class="c1"># 初始化Ollama嵌入模型,使用mxbai-embed-large模型,温度设置为0</span>
- <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">"mxbai-embed-large"</span><span class="p">,</span> <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
- <span class="c1"># 对单个查询文本进行嵌入编码</span>
- <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">'这是第一个测试文档'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result1-></span><span class="si">{</span><span class="n">res1</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result1的长度-></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">'</span><span class="p">)</span>
- <span class="c1"># 对多个文档进行批量嵌入编码</span>
- <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">'这是第一个测试文档'</span><span class="p">,</span> <span class="s1">'这是第二个测试文档'</span><span class="p">])</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">res2</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="1762164216432" src="assets/1762164216432.png"></p>
- <h2 id="prompts">三、Prompts<a class="headerlink" href="#prompts" title="Permanent link">¶</a></h2>
- <h3 id="1-prompt">1 通用prompt<a class="headerlink" href="#1-prompt" title="Permanent link">¶</a></h3>
- <p>Prompt是指当用户输入信息给模型时加入的提示,这个提示的形式可以是zero-shot或者few-shot等方式,目的是让模型理解更为复杂的业务场景以便更好的解决问题。</p>
- <p>提示模板:如果你有了一个起作用的提示,你可能想把它作为一个模板用于解决其他问题,LangChain就提供了PromptTemplates组件,它可以帮助你更方便的构建提示。</p>
- <ul>
- <li><strong>zero-shot提示方式</strong></li>
- </ul>
- <div class="highlight"><pre><span></span><code><span class="c1"># from langchain import PromptTemplate # Langchain 0.x版本使用</span>
- <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="c1"># from langchain_community.llms import Ollama # Langchain 0.x版本使用</span>
- <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>
- <span class="c1"># model = Ollama(model="qwen2.5:7b") # Langchain 0.x版本使用</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 定义模板</span>
- <span class="n">template</span> <span class="o">=</span> <span class="s2">"我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字"</span>
- <span class="n">prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"lastname"</span><span class="p">],</span>
- <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">)</span>
- <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">"王"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">prompt_text</span><span class="p">)</span>
- <span class="c1"># result: 我的邻居姓王,他生了个儿子,给他儿子起个名字</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251002154154332" src="assets/image-20251002154154332.png"></p>
- <ul>
- <li><strong>few-shot提示方式</strong></li>
- </ul>
- <div class="highlight"><pre><span></span><code><span class="c1"># from langchain import PromptTemplate, FewShotPromptTemplate # Langchain 0.x版本使用</span>
- <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>
- <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>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="n">examples</span> <span class="o">=</span> <span class="p">[</span>
- <span class="p">{</span><span class="s2">"word"</span><span class="p">:</span> <span class="s2">"开心"</span><span class="p">,</span> <span class="s2">"antonym"</span><span class="p">:</span> <span class="s2">"难过"</span><span class="p">},</span>
- <span class="p">{</span><span class="s2">"word"</span><span class="p">:</span> <span class="s2">"高"</span><span class="p">,</span> <span class="s2">"antonym"</span><span class="p">:</span> <span class="s2">"矮"</span><span class="p">}]</span>
- <span class="n">example_template</span> <span class="o">=</span> <span class="s2">"""</span>
- <span class="s2">单词: </span><span class="si">{word}</span>
- <span class="s2">反义词: </span><span class="si">{antonym}</span><span class="se">\\</span><span class="s2">n</span>
- <span class="s2">"""</span>
- <span class="n">example_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"word"</span><span class="p">,</span> <span class="s2">"antonym"</span><span class="p">],</span>
- <span class="n">template</span><span class="o">=</span><span class="n">example_template</span><span class="p">,</span>
- <span class="p">)</span>
- <span class="n">few_shot_prompt</span> <span class="o">=</span> <span class="n">FewShotPromptTemplate</span><span class="p">(</span>
- <span class="n">examples</span><span class="o">=</span><span class="n">examples</span><span class="p">,</span>
- <span class="n">example_prompt</span><span class="o">=</span><span class="n">example_prompt</span><span class="p">,</span>
- <span class="n">prefix</span><span class="o">=</span><span class="s2">"给出每个单词的反义词"</span><span class="p">,</span>
- <span class="n">suffix</span><span class="o">=</span><span class="s2">"单词: </span><span class="si">{input}</span><span class="se">\\</span><span class="s2">n反义词:"</span><span class="p">,</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"input"</span><span class="p">],</span>
- <span class="n">example_separator</span><span class="o">=</span><span class="s2">"</span><span class="se">\\</span><span class="s2">n"</span><span class="p">,</span>
- <span class="p">)</span>
- <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">"粗"</span><span class="p">)</span>
- <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>
- <span class="c1"># 细</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img src="assets/image-20251002152859092.png" alt="image-20251002152859092" style="zoom:67%;"></p>
- <h3 id="2-chatprompts">2 ChatPrompts<a class="headerlink" href="#2-chatprompts" title="Permanent link">¶</a></h3>
- <p>适合交互式对话应用,如聊天机器人、智能客服等,这些应用需要处理用户和LLM之间的多轮对话。</p>
- <blockquote>
- <p>ChatPromptTemplate</p>
- <p>SystemMessagePromptTemplate</p>
- <p>HumanMessagePromptTemplate</p>
- <p>history=[("system","......"),('human',"......"),("ai","......")]</p>
- </blockquote>
- <ul>
- <li><strong>直接提问</strong></li>
- </ul>
- <p>提示模板就是把一些常见的提示整理成模板,用户只需要修改模板中特定的词语,就能快速准确地告诉模型自己的需求。我们看个例子:</p>
- <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="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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 定义提示词模版</span>
- <span class="n">template_str</span> <span class="o">=</span> <span class="s2">"帮我讲个关于</span><span class="si">{name}</span><span class="s2">笑话吧"</span>
- <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>
- <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">"气球"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'prompt--></span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 调用模型</span>
- <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="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result--></span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img src="assets/image-20251002153543943.png" alt="image-20251002153543943" style="zoom:67%;"></p>
- <ul>
- <li><strong>zero-shot提示方式</strong></li>
- </ul>
- <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>
- <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>
- <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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 系统信息</span>
- <span class="n">system_prompt</span> <span class="o">=</span> <span class="n">SystemMessage</span><span class="p">(</span><span class="s2">"你是取名专家。"</span><span class="p">)</span>
- <span class="c1"># 用户信息模版</span>
- <span class="n">human_str</span> <span class="o">=</span> <span class="s2">"我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字。"</span>
- <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>
- <span class="c1"># 组装</span>
- <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>
- <span class="c1"># 生成最终的提示词</span>
- <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">"王"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'prompt--></span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 调用模型</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result--></span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251002200159523" src="assets/image-20251002200159523.png"></p>
- <ul>
- <li><strong>few-shot提示方式</strong></li>
- </ul>
- <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>
- <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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 创建 prompt 模版</span>
- <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>
- <span class="p">[</span>
- <span class="p">(</span><span class="s2">"system"</span><span class="p">,</span> <span class="s2">"给出每个单词的反义词"</span><span class="p">),</span>
- <span class="n">MessagesPlaceholder</span><span class="p">(</span><span class="s2">"history"</span><span class="p">),</span>
- <span class="p">(</span><span class="s2">"human"</span><span class="p">,</span> <span class="s2">"</span><span class="si">{question}</span><span class="s2">"</span><span class="p">)</span>
- <span class="p">]</span>
- <span class="p">)</span>
- <span class="c1"># 创建 few-shot prompt</span>
- <span class="c1"># history = [</span>
- <span class="c1"># HumanMessage(content="开心"),</span>
- <span class="c1"># AIMessage(content="难过"),</span>
- <span class="c1"># HumanMessage(content="高"),</span>
- <span class="c1"># AIMessage(content="矮")</span>
- <span class="c1"># ]</span>
- <span class="n">history</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">"human"</span><span class="p">,</span> <span class="s2">"开心"</span><span class="p">),</span> <span class="p">(</span><span class="s2">"ai"</span><span class="p">,</span> <span class="s2">"难过"</span><span class="p">),(</span><span class="s2">"human"</span><span class="p">,</span> <span class="s2">"高"</span><span class="p">),</span> <span class="p">(</span><span class="s2">"ai"</span><span class="p">,</span> <span class="s2">"矮"</span><span class="p">)]</span>
- <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">"富有"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"prompt--></span><span class="si">{</span><span class="n">prompt</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
- <span class="c1"># 调用模型</span>
- <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="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result--></span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251002205814344" src="assets/image-20251002205814344.png"></p>
- <h2 id="chains">四、Chains<a class="headerlink" href="#chains" title="Permanent link">¶</a></h2>
- <p>在LangChain中,Chains描述了将LLM与其他组件结合起来完成一个应用程序的过程。
- 针对上一小节的提示模版例子,zero-shot里面,我们可以用链来连接提示模版组件和模型,进而可以实现代码的更改,主要使用LCEL方法。</p>
- <p>LCEL(Lang Chain Expression Language) 是一种声明式的方法,用于轻松组合链条。</p>
- <p>LCEL的基本语法规则是使用<code>|</code>符号将不同的组件连接起来,形成一个链式结构。<code>|</code>符号类似于Unix的管道操作符,它将一个组件的输出作为下一个组件的输入,从而实现数据的传递和处理。</p>
- <p>上一个组件的输出作为下一个组件的输入,输出和输入的类型必须保持一致,否则不能连接。</p>
- <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>
- <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="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>
- <span class="c1"># 定义模板</span>
- <span class="n">template</span> <span class="o">=</span> <span class="s2">"我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字"</span>
- <span class="n">prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"lastname"</span><span class="p">],</span>
- <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">)</span>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="n">chain</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">llm</span>
- <span class="c1"># 执行链</span>
- <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">"王"</span><span class="p">))</span>
- </code></pre></div>
- <p>如果你想将第一个模型输出的结果,直接作为第二个模型的输入,直接使用管道符, 代码如下:</p>
- <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>
- <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>
- <span class="c1"># 创建第一条链</span>
- <span class="n">template</span> <span class="o">=</span> <span class="s2">"我的邻居姓</span><span class="si">{lastname}</span><span class="s2">,他生了个儿子,给他儿子起个名字"</span>
- <span class="n">first_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"lastname"</span><span class="p">],</span>
- <span class="n">template</span><span class="o">=</span><span class="n">template</span><span class="p">,)</span>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <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>
- <span class="c1"># 创建第二条链</span>
- <span class="n">second_prompt</span> <span class="o">=</span> <span class="n">PromptTemplate</span><span class="p">(</span>
- <span class="n">input_variables</span><span class="o">=</span><span class="p">[</span><span class="s2">"child_name"</span><span class="p">],</span>
- <span class="n">template</span><span class="o">=</span><span class="s2">"邻居的儿子名字叫</span><span class="si">{child_name}</span><span class="s2">,给他起一个小名"</span><span class="p">)</span>
- <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>
- <span class="c1"># 链接两条链</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="n">overall_chain</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'*'</span><span class="o">*</span><span class="mi">80</span><span class="p">)</span>
- <span class="c1"># 执行链,只需要传入第一个参数</span>
- <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">"王"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">catchphrase</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251002212834547" src="assets/image-20251002212834547.png"></p>
- <p><img alt="image-20251002212930745" src="assets/image-20251002212930745.png"></p>
- <h2 id="output_parsers">五、output_parsers<a class="headerlink" href="#output_parsers" title="Permanent link">¶</a></h2>
- <p>LLM 的输出是自然语言文本,但在应用开发中,我们经常需要将这些文本转换为结构化的数据格式,如列表、字典或对象。LangChain 输出解析器负责获取 LLM 的输出并将其转换为更合适的格式。</p>
- <p>部分解析器如下:</p>
- <table>
- <thead>
- <tr>
- <th>解析器名称</th>
- <th>核心功能</th>
- <th>输出的 Python 类型</th>
- <th>工业级应用场景</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>StrOutputParser</td>
- <td>默认解析器。将 LLM 的输出直接解析为字符串。</td>
- <td>str</td>
- <td>只需要原始回答时(如问答任务、对话场景)</td>
- </tr>
- <tr>
- <td>CommaSeparatedListParser</td>
- <td>将 LLM 输出的、用逗号分隔的文本解析为列表。</td>
- <td>list[str]</td>
- <td>列表/枚举型输出</td>
- </tr>
- <tr>
- <td>JsonOutputParser</td>
- <td>极其常用。将 LLM 输出的 JSON 字符串解析为 Python 字典。</td>
- <td>dict</td>
- <td>结构化 JSON 输出</td>
- </tr>
- <tr>
- <td>PydanticOutputParser</td>
- <td>极其常用。将 LLM 输出解析为预先定义的 Pydantic 对象,提供类型安全和数据验证。</td>
- <td>自定义的 pydantic.BaseModel 对象</td>
- <td>输出需要严格结构化(JSON-like)数据时</td>
- </tr>
- <tr>
- <td>DatetimeOutputParser</td>
- <td>从文本中智能地解析出日期和时间信息。</td>
- <td>datetime.datetime</td>
- <td>需要时间格式时</td>
- </tr>
- </tbody>
- </table>
- <h3 id="1">1 字符串解析器<a class="headerlink" href="#1" title="Permanent link">¶</a></h3>
- <p>StrOutputParser,最简单的解析器,用于提取模型返回的原始文本:</p>
- <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>
- <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="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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 创建简单链</span>
- <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">"解释</span><span class="si">{topic}</span><span class="s2">是什么?回答控制20字以内"</span><span class="p">)</span>
- <span class="n">chain1</span> <span class="o">=</span> <span class="n">prompt</span> <span class="o">|</span> <span class="n">model</span>
- <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">"topic"</span><span class="p">:</span> <span class="s2">"ai"</span><span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"result1--></span><span class="si">{</span><span class="n">result1</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
- <span class="c1"># 添加字符串解析器</span>
- <span class="n">parser</span> <span class="o">=</span> <span class="n">StrOutputParser</span><span class="p">()</span>
- <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>
- <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">"topic"</span><span class="p">:</span> <span class="s2">"ai"</span><span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"result2--></span><span class="si">{</span><span class="n">result2</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251002230930266" src="assets/image-20251002230930266.png"></p>
- <h3 id="2_1">2 列表解析器<a class="headerlink" href="#2_1" title="Permanent link">¶</a></h3>
- <p>CommaSeparatedListOutputParser,将逗号分隔的文本转换为Python列表:</p>
- <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>
- <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="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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 创建列表解析器</span>
- <span class="n">parser</span> <span class="o">=</span> <span class="n">CommaSeparatedListOutputParser</span><span class="p">()</span>
- <span class="c1"># 创建带格式说明的提示模板</span>
- <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>
- <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">"用中文列出</span><span class="si">{topic}</span><span class="s2">的五个最重要特点。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">"</span>
- <span class="p">)</span>
- <span class="c1"># 组合组件</span>
- <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>
- <span class="c1"># 调用链</span>
- <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>
- <span class="s2">"topic"</span><span class="p">:</span> <span class="s2">"大模型"</span><span class="p">,</span>
- <span class="s2">"format_instructions"</span><span class="p">:</span> <span class="n">format_instructions</span>
- <span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img src="assets/image-20251002231200108.png" alt="image-20251002231200108" style="zoom: 67%;"></p>
- <h3 id="3-json">3 JSON解析器<a class="headerlink" href="#3-json" title="Permanent link">¶</a></h3>
- <p>JsonOutputParser,将JSON格式文本转换为Python字典或列表:</p>
- <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>
- <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="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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 创建JSON解析器</span>
- <span class="n">json_parser</span> <span class="o">=</span> <span class="n">JsonOutputParser</span><span class="p">()</span>
- <span class="c1"># 创建带格式说明的提示模板</span>
- <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>
- <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>
- <span class="s2">"生成一个包含</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">"</span>
- <span class="p">)</span>
- <span class="c1"># 组合组件</span>
- <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>
- <span class="c1"># 调用链</span>
- <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>
- <span class="s2">"person"</span><span class="p">:</span> <span class="s2">"雷军"</span><span class="p">,</span>
- <span class="s2">"format_instructions"</span><span class="p">:</span> <span class="n">json_format_instructions</span>
- <span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003000254030" src="assets/image-20251003000254030.png"></p>
- <h3 id="4-pydantic">4 Pydantic解析器<a class="headerlink" href="#4-pydantic" title="Permanent link">¶</a></h3>
- <p>PydanticOutputParser,使用Pydantic模型定义输出结构:</p>
- <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="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>
- <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>
- <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>
- <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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 定义Pydantic模型</span>
- <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>
- <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">"电影标题"</span><span class="p">)</span>
- <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">"导演姓名"</span><span class="p">)</span>
- <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">"上映年份"</span><span class="p">)</span>
- <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">"电影类型"</span><span class="p">)</span>
- <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">"评分(1-10)"</span><span class="p">)</span>
- <span class="c1"># 创建Pydantic解析器</span>
- <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>
- <span class="c1"># 创建带格式说明的提示模板</span>
- <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>
- <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>
- <span class="s2">"生成一部</span><span class="si">{genre}</span><span class="s2">电影的信息。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">"</span>
- <span class="p">)</span>
- <span class="c1"># 组合组件</span>
- <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>
- <span class="c1"># 调用链</span>
- <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>
- <span class="s2">"genre"</span><span class="p">:</span> <span class="s2">"科幻"</span><span class="p">,</span>
- <span class="s2">"format_instructions"</span><span class="p">:</span> <span class="n">format_instructions</span>
- <span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">movie_data</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003000720225" src="assets/image-20251003000720225.png"></p>
- <h3 id="5">5 自定义解析器<a class="headerlink" href="#5" title="Permanent link">¶</a></h3>
- <p>创建自定义输出解析器</p>
- <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>
- <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>
- <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="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>
- <span class="c1"># 实例化模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <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>
- <span class="w"> </span><span class="sd">"""解析形如'key: value'的文本"""</span>
- <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">-></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>
- <span class="w"> </span><span class="sd">"""从文本中解析键值对"""</span>
- <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
- <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">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
- <span class="k">if</span> <span class="s1">':'</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
- <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">':'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
- <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>
- <span class="k">return</span> <span class="n">result</span>
- <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">-></span> <span class="nb">str</span><span class="p">:</span>
- <span class="w"> </span><span class="sd">"""提供格式指导给模型"""</span>
- <span class="k">return</span> <span class="s2">"""请以'键: 值'的格式返回信息,每行一个键值对。</span>
- <span class="s2"> 例如:</span>
- <span class="s2"> 名称: 爱因斯坦</span>
- <span class="s2"> 职业: 物理学家</span>
- <span class="s2"> 贡献: 相对论"""</span>
- <span class="c1"># 使用自定义解析器</span>
- <span class="n">custom_parser</span> <span class="o">=</span> <span class="n">CustomKeyValueParser</span><span class="p">()</span>
- <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>
- <span class="s2">"提供关于</span><span class="si">{person}</span><span class="s2">的基本信息。</span><span class="se">\n</span><span class="si">{format_instructions}</span><span class="s2">"</span>
- <span class="p">)</span>
- <span class="c1"># 组合组件</span>
- <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>
- <span class="c1"># 调用模型</span>
- <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>
- <span class="s2">"person"</span><span class="p">:</span> <span class="s2">"屠呦呦"</span><span class="p">,</span>
- <span class="s2">"format_instructions"</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>
- <span class="p">})</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003001007923" src="assets/image-20251003001007923.png"></p>
- <h2 id="memory">六、Memory<a class="headerlink" href="#memory" title="Permanent link">¶</a></h2>
- <p>大模型本身不具备上下文的概念,它并不保存上次交互的内容,ChatGPT之所以能够和人正常沟通对话,因为它进行了一层封装,将历史记录回传给了模型。</p>
- <p>因此 LangChain 也提供了Memory组件, Memory分为两种类型: <strong>短期记忆和长期记忆</strong> 。短期记忆一般指单一会话时传递数据,长期记忆则是处理多个会话时获取和更新信息。</p>
- <ul>
- <li>使用 <strong>ChatMessageHistory</strong> 手动添加上下文</li>
- </ul>
- <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>
- <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>
- <span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
- <span class="c1"># 1.创建一个ChatMessageHistory对象,用来存储对话信息</span>
- <span class="n">history</span> <span class="o">=</span> <span class="n">ChatMessageHistory</span><span class="p">()</span>
- <span class="c1"># 添加用户消息</span>
- <span class="n">history</span><span class="o">.</span><span class="n">add_user_message</span><span class="p">(</span><span class="s2">"在吗?"</span><span class="p">)</span>
- <span class="c1"># 添加大模型消息</span>
- <span class="n">history</span><span class="o">.</span><span class="n">add_ai_message</span><span class="p">(</span><span class="s2">"在"</span><span class="p">)</span>
- <span class="c1"># 打印所有消息</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'history.messages--></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">'</span><span class="p">)</span>
- <span class="c1"># 2.可以将history.messages中的信息保存到字典中,然后保存到数据库或者文件中,方便后续读取</span>
- <span class="c1"># 2.1 messages_to_dict()方法将history.messages中的信息转换成字典</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'dicts--></span><span class="si">{</span><span class="n">dicts</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 2.2 这里将dicts保存到文件中</span>
- <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'history.json'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
- <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>
- <span class="c1"># 3.从文件中读取出字典,然后将字典转换成消息</span>
- <span class="c1"># 3.1 读取文件</span>
- <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">'history.json'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">))</span>
- <span class="c1"># 3.2 然后将字典转换成消息</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'chat_messages--></span><span class="si">{</span><span class="n">chat_messages</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003001546687" src="assets/image-20251003001546687.png"></p>
- <p>LangChain v1.0 版本对 Memory(记忆) 组件进行了深度优化与工程化重构,使其不仅支持多轮对话上下文管理,更成为构建生产级智能体(Agent)不可或缺的核心能力之一。在 LangChain 从“实验性框架”迈向“企业级平台”的关键转型中,Memory 模块被赋予了更清晰的职责边界、更灵活的策略机制以及更强的可扩展性,从而支撑复杂任务场景下的长期记忆、状态追踪与个性化交互。</p>
- <h3 id="1-short-term-memory">1 短期记忆(Short-term Memory)<a class="headerlink" href="#1-short-term-memory" title="Permanent link">¶</a></h3>
- <p>短期记忆的本质是线程级状态管理]。在 LangGraph 中:</p>
- <blockquote>
- <p>短期记忆 = Agent 状态(State) + 检查点持久化(Checkpointer) + 线程标识(thread_id)。</p>
- </blockquote>
- <p><strong>(1)状态(State)</strong></p>
- <p>通常是一个包含 messages 字段的字典或 Pydantic 模型(如 MessagesState 或自定义 CustomState),用于存储当前会话的所有消息、中间变量、工具调用结果等。</p>
- <p><strong>(2)检查点器(Checkpointer)</strong></p>
- <p>负责将状态序列化并持久化到内存、SQLite、PostgreSQL 等后端。每次状态变更(如新增一条消息)都会触发一次检查点保存。</p>
- <p><strong>(3)会话ID(thread_id)</strong></p>
- <p>作为会话的唯一标识符,确保不同用户或不同对话之间的状态完全隔离。即使多个用户并发交互,也不会发生记忆混淆。</p>
- <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>
- <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>
- <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>
- <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>
- <span class="kn">import</span><span class="w"> </span><span class="nn">time</span>
- <span class="c1"># 初始化大模型,这里使用的是 Qwen 的聊天模型</span>
- <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">"qwen2.5:7b"</span><span class="p">)</span>
- <span class="c1"># 创建内存保存器 (Checkpointer)</span>
- <span class="c1"># 这是 LangGraph 的核心概念之一,用于在对话过程中保存和恢复状态(记忆)</span>
- <span class="n">checkpointer</span> <span class="o">=</span> <span class="n">InMemorySaver</span><span class="p">()</span>
- <span class="c1"># 定义 Agent 的配置</span>
- <span class="c1"># "thread_id" (线程ID) 非常关键:它相当于对话的 ID,用于区分不同的会话记忆</span>
- <span class="c1"># 使用时间戳作为 ID,确保每次运行脚本时的线程 ID 不同(但在同一次运行中复用)</span>
- <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>
- <span class="n">config</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s2">"configurable"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"thread_id"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"</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">"</span><span class="p">}</span>
- <span class="p">}</span>
- <span class="c1"># 创建 Agent 实例</span>
- <span class="c1"># model: 指定使用的底层大模型</span>
- <span class="c1"># tools: 工具列表,这里为空,表示 Agent 只能进行对话,不能调用外部工具(如搜索、计算器等)</span>
- <span class="c1"># checkpointer: 传入上面的内存保存器,赋予 Agent 记忆能力</span>
- <span class="c1"># system_prompt: 设定 Agent 的角色和行为模式</span>
- <span class="n">agent</span> <span class="o">=</span> <span class="n">create_agent</span><span class="p">(</span>
- <span class="n">model</span><span class="o">=</span><span class="n">model</span><span class="p">,</span>
- <span class="n">tools</span><span class="o">=</span><span class="p">[],</span>
- <span class="n">checkpointer</span><span class="o">=</span><span class="n">checkpointer</span><span class="p">,</span>
- <span class="n">system_prompt</span><span class="o">=</span><span class="s2">"你是一个翻译官,擅长中英互译。"</span>
- <span class="p">)</span>
- <span class="c1"># 第一轮对话输入</span>
- <span class="n">input_1</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s2">"messages"</span><span class="p">:</span> <span class="p">[</span><span class="n">HumanMessage</span><span class="p">(</span><span class="s2">"你好,我叫小呆。"</span><span class="p">)]</span>
- <span class="p">}</span>
- <span class="c1"># 调用 Agent (Response A)</span>
- <span class="c1"># 使用 config,这意味着这次对话会记录在 thread_id 对应的内存中</span>
- <span class="c1"># Agent 会记住 "我叫小呆" 这个信息</span>
- <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>
- <span class="nb">input</span><span class="o">=</span><span class="n">input_1</span><span class="p">,</span>
- <span class="n">config</span><span class="o">=</span><span class="n">config</span>
- <span class="p">)</span>
- <span class="c1"># 第二轮对话输入(测试是否记得之前的信息)</span>
- <span class="n">input_2</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s2">"messages"</span><span class="p">:</span> <span class="p">[</span><span class="n">HumanMessage</span><span class="p">(</span><span class="s2">"你好,我叫什么?"</span><span class="p">)]</span>
- <span class="p">}</span>
- <span class="c1"># 定义一个新的配置 (config_2),使用完全不同的 thread_id</span>
- <span class="c1"># 这代表开启了一个全新的、独立的对话会话</span>
- <span class="n">config_2</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s2">"configurable"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"thread_id"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"</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">"</span><span class="p">}</span> <span class="c1"># 这里生成了一个新的时间戳 ID</span>
- <span class="p">}</span>
- <span class="c1"># 调用 Agent (Response B)</span>
- <span class="c1"># 使用新的 config_2,Agent 看不到 config_1 中的历史记录</span>
- <span class="c1"># 因此,Agent 应该不知道用户叫 "小呆",因为它处于一个新的 "线程" 中</span>
- <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>
- <span class="nb">input</span><span class="o">=</span><span class="n">input_2</span><span class="p">,</span>
- <span class="n">config</span><span class="o">=</span><span class="n">config_2</span>
- <span class="p">)</span>
- <span class="c1"># 调用 Agent (Response C)</span>
- <span class="c1"># 再次使用最初的 config</span>
- <span class="c1"># 这会恢复到第一个会话的记忆中</span>
- <span class="c1"># Agent 应该能回想起用户叫 "小呆",因为它共享同一个 thread_id</span>
- <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>
- <span class="nb">input</span><span class="o">=</span><span class="n">input_2</span><span class="p">,</span>
- <span class="n">config</span><span class="o">=</span><span class="n">config</span>
- <span class="p">)</span>
- <span class="c1"># 输出结果进行对比</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"Response A (第一次对话):"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">response_a</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Response B (新线程,无记忆):"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">response_b</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Response C (回到原线程,有记忆):"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">response_c</span><span class="p">)</span>
- </code></pre></div>
- <p><strong>代码运行逻辑:</strong></p>
- <ul>
- <li><strong>checkpointer (记忆核心)</strong>:这是 LangGraph 区别于传统简单 API 调用的关键。它允许 Agent 在多次 invoke 调用之间保存状态。</li>
- <li><strong>thread_id (记忆索引)</strong>:你可以把 thread_id 想象成数据库中的主键。</li>
- <li>Response A:向 ID 为 100 的记录里写入了名字。</li>
- <li>Response B:向 ID 为 200 的新记录提问,因为 200 是空的,所以 Agent 不知道名字。</li>
- <li>Response C:又回到 ID 为 100 的记录提问,Agent 读取了历史记录,所以知道名字。</li>
- <li><strong>System Prompt</strong>:虽然输入是在对话,但因为设定了 “你是一个翻译官”,Agent 可能会试图在回答的同时进行翻译,或者在回复格式上符合翻译官的身份。</li>
- </ul>
- <h3 id="2_2">2 长期记忆<a class="headerlink" href="#2_2" title="Permanent link">¶</a></h3>
- <p>对于需要长期运行和可靠记忆的应用,推荐使用数据库进行持久化。详见后面阶段LangGraph部分。</p>
- <h2 id="indexes">七、Indexes<a class="headerlink" href="#indexes" title="Permanent link">¶</a></h2>
- <p>Indexes组件的目的是让LangChain具备处理文档处理的能力,包括:文档加载、检索等。注意,这里的文档不局限于txt、pdf等文本类内容,还涵盖email、区块链、视频等内容。</p>
- <p>Indexes组件主要包含类型:</p>
- <ul>
- <li>文档加载器</li>
- <li>文本分割器</li>
- <li>VectorStores</li>
- <li>检索器</li>
- </ul>
- <h3 id="1_1">1 文档加载器<a class="headerlink" href="#1_1" title="Permanent link">¶</a></h3>
- <blockquote>
- <p><a href="https://python.langchain.com/v0.2/docs/introduction/">https://python.langchain.com/v0.2/docs/introduction/</a></p>
- </blockquote>
- <p>文档加载器主要基于<code>Unstructured</code> 包,<code>Unstructured</code> 是一个python包,可以把各种类型的文件转换成文本。文档加载器使用起来很简单,只需要引入相应的loader工具。</p>
- <p>LangChain支持的文档加载器 (部分):</p>
- <p><img alt="image-20250705100227413" src="assets/image-20250705100227413.png"></p>
- <p>示例代码:</p>
- <blockquote>
- <p>需要安装的包:</p>
- <p>pip install unstructured</p>
- <p>pip install langchain-unstructured</p>
- </blockquote>
- <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>
- <span class="c1"># 创建 UnstructuredLoader 对象</span>
- <span class="n">loader</span> <span class="o">=</span> <span class="n">UnstructuredLoader</span><span class="p">(</span><span class="s1">'./data/衣服属性.txt'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf8'</span><span class="p">)</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'docs--></span><span class="si">{</span><span class="n">docs</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'len--></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">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'第一行数据--></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">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'*'</span> <span class="o">*</span> <span class="mi">100</span><span class="p">)</span>
- <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>
- <span class="c1"># 创建 TextLoader 对象</span>
- <span class="n">loader</span> <span class="o">=</span> <span class="n">TextLoader</span><span class="p">(</span><span class="s1">'./data/衣服属性.txt'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf8'</span><span class="p">)</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'docs--></span><span class="si">{</span><span class="n">docs</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'len--></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">'</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'第一行数据--></span><span class="si">{}</span><span class="s1">'</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">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]))</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003010445727" src="assets/image-20251003010445727.png"></p>
- <h3 id="2_3">2 文档分割器<a class="headerlink" href="#2_3" title="Permanent link">¶</a></h3>
- <p>由于模型对输入的字符长度有限制,我们在碰到很长的文本时,需要把文本分割成多个小的文本片段。</p>
- <p>文本分割最简单的方式是按照字符长度进行分割,但是这会带来很多问题,比如说如果文本是一段代码,一个函数被分割到两段之后就成了没有意义的字符,所以整体的原则是把语义相关的文本片段放在一起。</p>
- <p>LangChain中最基本的文本分割器是<code>CharacterTextSplitter</code> ,它按照指定的分隔符(默认“\n\n”)进行分割,并且考虑文本片段的最大长度。我们看个例子:</p>
- <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>
- <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>
- <span class="c1"># 创建分词器 separator参数指的是分割的分隔符,chunk_size指的是分割出来的每个块的大小,chunk_overlap指的是每个块之间重叠的大小</span>
- <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">" "</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>
- <span class="c1"># 一句话分割</span>
- <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">"a b c d e f"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result1---></span><span class="si">{</span><span class="n">result1</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 多句话分割</span>
- <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">"a b c d e f"</span><span class="p">,</span> <span class="s2">"e f g h"</span><span class="p">])</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result2---></span><span class="si">{</span><span class="n">result2</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 多句话分割</span>
- <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">"a b c d e f"</span><span class="p">,</span> <span class="n">metadata</span><span class="o">=</span><span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="s2">"1"</span><span class="p">})])</span>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result3---></span><span class="si">{</span><span class="n">result3</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003011030583" src="assets/image-20251003011030583.png"></p>
- <hr>
- <p>除了CharacterTextSplitter分割器,LangChain还支持其他文档分割器 (部分):</p>
- <table>
- <thead>
- <tr>
- <th>分割器名称</th>
- <th>功能描述</th>
- <th>类型</th>
- <th>工业场景应用</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td>CharacterTextSplitter</td>
- <td>简单按指定分隔符(如换行、逗号)直接分割。</td>
- <td>基础字符解析</td>
- <td>简单字符串或 CSV 数据处理,如传感器数据日志。</td>
- </tr>
- <tr>
- <td>RecursiveCharacterTextSplitter</td>
- <td>递归按字符分割,先尝试自然边界(如段落、句子),太大则继续细分。</td>
- <td>通用字符解析</td>
- <td>通用文本处理,如日志、报告、PDF 文档分割,便于 RAG 检索。</td>
- </tr>
- <tr>
- <td>TokenTextSplitter</td>
- <td>按 token(词元)分割,支持 LLM token 计数。</td>
- <td>Token 基于解析</td>
- <td>LLM 输入优化,如处理 API 响应或长查询,控制 token 限制。</td>
- </tr>
- <tr>
- <td>SentenceTextSplitter</td>
- <td>按句子边界分割,使用 NLP 识别句子(包括标点)。</td>
- <td>语义解析</td>
- <td>自然语言文本,如文章或对话分析,保持句子完整。</td>
- </tr>
- <tr>
- <td>SpacyTextSplitter</td>
- <td>使用 SpaCy NLP 库按句子或实体分割(需安装 SpaCy)。</td>
- <td>语义解析</td>
- <td>高级 NLP 场景,如实体提取或生物医学文本。</td>
- </tr>
- <tr>
- <td>NLTKTextSplitter</td>
- <td>使用 NLTK 库按句子或词分割(需安装 NLTK)。</td>
- <td>语义解析</td>
- <td>文本研究或分析,如时间序列数据描述。</td>
- </tr>
- <tr>
- <td>MarkdownHeaderTextSplitter</td>
- <td>按 Markdown 结构(如标题、列表)智能分割。</td>
- <td>结构化解析</td>
- <td>Markdown 文档分割,保留语义结构,用于知识库构建。</td>
- </tr>
- <tr>
- <td>HTMLSplitter</td>
- <td>按 HTML 标签(如 、)分割网页内容。</td>
- <td>结构化解析</td>
- <td>网页数据爬取,如在线技术文档或新闻提取。</td>
- </tr>
- <tr>
- <td>LatexTextSplitter</td>
- <td>按 LaTeX 结构(如章节、公式)分割。</td>
- <td>结构化解析</td>
- <td>学术论文或数学文档处理。</td>
- </tr>
- <tr>
- <td>PythonCodeTextSplitter</td>
- <td>按 Python 代码结构(如函数、类)分割。</td>
- <td>代码解析</td>
- <td>源代码文件分析,如脚本调试或代码库管理。</td>
- </tr>
- </tbody>
- </table>
- <p>下面就几个重要的分割器进行讲解。</p>
- <ul>
- <li>递归字符文本分割器(RecursiveCharacterTextSplitter)</li>
- </ul>
- <blockquote>
- <p>递归字符文本分割器是一种更智能的分割方法,它尝试在特定分隔符处分割文本,以保持更好的语义完整性。 特点:</p>
- <ul>
- <li>尝试在自然断点处分割文本</li>
- <li>比简单的字符分割更能保持语义完整性</li>
- <li>适用于结构化程度较高的文本,如 Markdown、HTML 等</li>
- </ul>
- <p>运行流程:</p>
- <ul>
- <li>首先尝试使用第一个分隔符(如 "\n\n")分割文本</li>
- <li>如果分割后的块仍然过大,则使用下一个分隔符继续分割</li>
- <li>重复此过程,直到达到指定的 chunk_size 或用完所有分隔符</li>
- </ul>
- <p>示例代码</p>
- <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>
- <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">RecursiveCharacterTextSplitter</span><span class="p">(</span>
- <span class="n">chunk_size</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="c1"># 每个块最多 100 个字符</span>
- <span class="n">chunk_overlap</span><span class="o">=</span><span class="mi">6</span><span class="p">,</span> <span class="c1"># 相邻分块会共享 20 个字符</span>
- <span class="n">length_function</span><span class="o">=</span><span class="nb">len</span><span class="p">,</span> <span class="c1"># 用字符数来衡量长度</span>
- <span class="n">separators</span><span class="o">=</span><span class="p">[</span><span class="s2">"</span><span class="se">\n\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">" "</span><span class="p">,</span> <span class="s2">""</span><span class="p">]</span> <span class="c1"># 会优先尝试按 \n\n 分段,如果太长,再按 \n → 空格 → 逐字符切分。</span>
- <span class="p">)</span>
- <span class="n">text</span> <span class="o">=</span> <span class="s2">"""</span>
- <span class="s2">人工智能正在快速发展,尤其是大语言模型的应用,正在改变人类的工作方式。</span>
- <span class="s2">它们可以帮助人们进行写作、代码生成、甚至是科研探索。</span>
- <span class="s2">相比之下,新能源的发展同样重要。</span>
- <span class="s2">电动车和太阳能正在逐渐替代传统能源,减少碳排放,对全球环境保护至关重要。</span>
- <span class="s2">"""</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果</p>
- <p><img alt="1768393012466" src="assets/1768393012466.png"></p>
- </blockquote>
- <ul>
- <li>语义文档分割器(SemanticChunker)</li>
- </ul>
- <blockquote>
- <p>语义文档分割器使用语义理解来分割文本,这是一种更高级的分割方法。 特点:</p>
- <ul>
- <li>基于语义相似性分割文本</li>
- <li>能够更好地保持语义完整性</li>
- <li>计算成本较高,处理大量文本时可能效率较低</li>
- <li>适用于需要高度语义理解的场景</li>
- </ul>
- <p>示例代码</p>
- <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>
- <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>
- <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">"mxbai-embed-large"</span><span class="p">)</span>
- <span class="n">text_splitter</span> <span class="o">=</span> <span class="n">SemanticChunker</span><span class="p">(</span>
- <span class="n">embeddings</span><span class="o">=</span><span class="n">embed</span><span class="p">,</span>
- <span class="n">breakpoint_threshold_type</span><span class="o">=</span><span class="s1">'percentile'</span><span class="p">,</span>
- <span class="c1"># 更低的百分位会更“积极”地切分(数值越小 => 切得越多)</span>
- <span class="n">breakpoint_threshold_amount</span><span class="o">=</span><span class="mf">70.0</span><span class="p">,</span>
- <span class="c1"># 句子拆分正则为同时识别中/英文终结符</span>
- <span class="n">sentence_split_regex</span><span class="o">=</span><span class="sa">r</span><span class="s1">'(?<=[。!?.!?])\s*'</span><span class="p">,</span>
- <span class="c1"># 每个切分后片段(chunk)至少要有多少个字符</span>
- <span class="n">min_chunk_size</span><span class="o">=</span><span class="mi">10</span>
- <span class="p">)</span>
- <span class="n">text</span> <span class="o">=</span> <span class="s2">"""</span>
- <span class="s2">人工智能正在快速发展,尤其是大语言模型的应用,正在改变人类的工作方式。</span>
- <span class="s2">它们可以帮助人们进行写作、代码生成、甚至是科研探索。</span>
- <span class="s2">相比之下,新能源的发展同样重要。</span>
- <span class="s2">电动车和太阳能正在逐渐替代传统能源,减少碳排放,对全球环境保护至关重要。</span>
- <span class="s2">"""</span>
- <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>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"------ 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"> ------"</span><span class="p">)</span>
- <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>
- <span class="nb">print</span><span class="p">()</span>
- </code></pre></div>
- <p>运行结果</p>
- <p><img alt="image-20251003095433705" src="assets/image-20251003095433705.png"></p>
- </blockquote>
- <ul>
- <li>MarkdownHeaderTextSplitter(Markdown文档切割器)</li>
- </ul>
- <blockquote>
- <p>适用于Markdown文档,按照标题进行拆分</p>
- <p>示例代码</p>
- <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>
- <span class="n">headers_to_split_on</span> <span class="o">=</span> <span class="p">[</span>
- <span class="p">(</span><span class="s2">"#"</span><span class="p">,</span> <span class="s2">"Header 1"</span><span class="p">),</span>
- <span class="p">(</span><span class="s2">"##"</span><span class="p">,</span> <span class="s2">"Header 2"</span><span class="p">),</span>
- <span class="p">(</span><span class="s2">"###"</span><span class="p">,</span> <span class="s2">"Header 3"</span><span class="p">),</span>
- <span class="p">]</span>
- <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>
- <span class="n">markdown_text</span> <span class="o">=</span> <span class="s2">"# 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"</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="n">docs</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果</p>
- <p><img alt="image-20251003100510115" src="assets/image-20251003100510115.png"></p>
- </blockquote>
- <p>其他拓展知识可以参考:<a href="https://blog.csdn.net/qq_28540861/article/details/149161419">https://blog.csdn.net/qq_28540861/article/details/149161419</a></p>
- <h3 id="3-vectorstores">3 VectorStores<a class="headerlink" href="#3-vectorstores" title="Permanent link">¶</a></h3>
- <p>VectorStores是一种特殊类型的数据库,它的作用是存储由嵌入创建的向量,提供相似查询等功能。</p>
- <p>LangChain支持的VectorStore有<a href="https://python.langchain.com/docs/integrations/vectorstores/">https://python.langchain.com/docs/integrations/vectorstores/</a>,常见的如下:</p>
- <p><img alt="image-20250705114738060" src="assets/image-20250705114738060.png"></p>
- <blockquote>
- <p>我们使用其中一个<code>Chroma</code> 组件作为例子:</p>
- <p>pip install chromadb</p>
- <p>pip install langchain-chroma</p>
- </blockquote>
- <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>
- <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>
- <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>
- <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>
- <span class="c1"># 1.加载文档</span>
- <span class="c1"># 创建 TextLoader 对象</span>
- <span class="n">loader</span> <span class="o">=</span> <span class="n">TextLoader</span><span class="p">(</span><span class="s1">'./data/pku.txt'</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">)</span>
- <span class="c1"># 加载文档</span>
- <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>
- <span class="c1"># print(f'docs-->{docs}')</span>
- <span class="c1"># 2.将文档进行分块</span>
- <span class="c1"># 创建 CharacterTextSplitter 对象</span>
- <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">"</span><span class="se">\n\n</span><span class="s2">"</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>
- <span class="c1"># 分块</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'split_docs--></span><span class="si">{</span><span class="n">split_docs</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- <span class="c1"># 3.将分割后的文档存储到向量数据库中</span>
- <span class="c1"># 加载embedding模型</span>
- <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">"mxbai-embed-large"</span><span class="p">)</span>
- <span class="c1"># 创建向量数据库,需要指定 存储的文档和向量模型名称以及持久化目录</span>
- <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>
- <span class="n">embedding</span><span class="o">=</span><span class="n">embedding</span><span class="p">,</span>
- <span class="n">persist_directory</span><span class="o">=</span><span class="s1">'./chroma_db'</span><span class="p">)</span>
- <span class="c1"># 假如你的向量数据库已经存在,那么可以直接加载</span>
- <span class="c1"># chromadaDB = Chroma(persist_directory='./chroma_db', embedding_function=embedding)</span>
- <span class="c1"># 4.使用向量数据库进行查询</span>
- <span class="n">query</span> <span class="o">=</span> <span class="s2">"1937年北京大学发生了什么?"</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result--></span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003101141993" src="assets/image-20251003101141993.png"></p>
- <h3 id="4_1">4 检索器<a class="headerlink" href="#4_1" title="Permanent link">¶</a></h3>
- <h4 id="41-langchain">4.1 LangChain的检索器定义<a class="headerlink" href="#41-langchain" title="Permanent link">¶</a></h4>
- <p>检索器是 LangChain 中负责信息检索的模块,通常与 索引(Indexes) 模块(如向量存储、嵌入模型)结合使用。它的核心功能是:</p>
- <ul>
- <li>输入:接收用户查询(通常是文本)。</li>
- <li>处理:根据查询从数据源中检索相关内容。</li>
- <li>输出:返回一组相关文档或文本片段(通常是 Document 对象列表)。</li>
- </ul>
- <p>检索器在以下场景中扮演关键角色:</p>
- <ul>
- <li>问答系统:从文档或知识库中检索答案的上下文。</li>
- <li>语义搜索:根据查询的语义返回相关结果。</li>
- <li>上下文增强:为语言模型提供外部知识,解决其知识局限。</li>
- </ul>
- <h4 id="42">4.2 检索器的工作原理<a class="headerlink" href="#42" title="Permanent link">¶</a></h4>
- <p>检索器通常与 向量存储(Vector Stores) 配合,通过嵌入模型(Embedding Models)将查询和文档转为向量,基于相似性进行检索。工作流程可以分为以下步骤:</p>
- <ul>
- <li>查询嵌入:将用户查询通过嵌入模型(如 OpenAIEmbeddings)转为向量表示</li>
- <li>相似性搜索:在向量存储中查找与查询向量最相似的文档向量。</li>
- <li>文档返回:返回匹配的文档(包含内容、元数据等)。</li>
- <li>后处理(可选):对检索结果进行排序、过滤或重新排名。</li>
- </ul>
- <p>检索器的核心依赖:</p>
- <ul>
- <li>嵌入模型:将文本转为向量(如 OpenAIEmbeddings, HuggingFaceEmbeddings)。</li>
- <li>向量存储:存储文档向量(如 Chroma、FAISS、Pinecone)。</li>
- <li>相似性度量:如余弦相似度、欧几里得距离</li>
- </ul>
- <h4 id="43">4.3 检索器类型<a class="headerlink" href="#43" title="Permanent link">¶</a></h4>
- <p>langchain支持很多检索器<a href="https://python.langchain.com/docs/integrations/retrievers/">https://python.langchain.com/docs/integrations/retrievers/</a>,部分如下:</p>
- <p><img alt="image-20250705114709874" src="assets/image-20250705114709874-17594578225791.png"></p>
- <p>此处我们讲解VectorStoreRetriever。</p>
- <p>在 LangChain 中,as_retriever() 方法的 search_type 参数决定了向量检索的具体算法和行为。</p>
- <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>
- <span class="n">search_type</span><span class="o">=</span><span class="s2">"similarity"</span><span class="p">,</span> <span class="c1"># 可选 "similarity"|"mmr"|"similarity_score_threshold"</span>
- <span class="n">search_kwargs</span><span class="o">=</span><span class="p">{</span>
- <span class="s2">"k"</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="c1"># 返回结果数量</span>
- <span class="s2">"score_threshold"</span><span class="p">:</span> <span class="mf">0.7</span><span class="p">,</span> <span class="c1"># 仅当search_type="similarity_score_threshold"时有效,低于阈值的都丢弃。</span>
- <span class="s2">"filter"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"source"</span><span class="p">:</span> <span class="s2">"重要文档.pdf"</span><span class="p">},</span> <span class="c1"># 元数据过滤,只会检索满足条件的文档。</span>
- <span class="s2">"lambda_mult"</span><span class="p">:</span> <span class="mf">0.25</span> <span class="c1"># 仅MMR搜索有效(控制多样性):接近 0 则更强调和查询的相关性;接近 1 则更强调结果之间的差异性</span>
- <span class="p">}</span>
- <span class="p">)</span>
- </code></pre></div>
- <p>以下是三种搜索类型的对比:</p>
- <p><img alt="image-20250714160215042" src="assets/image-20250714160215042-17594581318012.png"></p>
- <p>示例代码:</p>
- <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>
- <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>
- <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">"mxbai-embed-large"</span><span class="p">)</span>
- <span class="c1"># 向量数据库已经存在,那么可以直接加载</span>
- <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">'./chroma_db'</span><span class="p">,</span> <span class="n">embedding_function</span><span class="o">=</span><span class="n">embedding</span><span class="p">)</span>
- <span class="c1"># 使用向量数据库进行查询</span>
- <span class="n">query</span> <span class="o">=</span> <span class="s2">"1937年北京大学发生了什么?"</span>
- <span class="c1"># result = chromadaDB.similarity_search(query, k=2)</span>
- <span class="c1"># 使用 as_retriever 方法返回 Retriever 对象,然后调用 invoke 方法进行查询</span>
- <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">"k"</span><span class="p">:</span><span class="mi">2</span><span class="p">})</span>
- <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>
- <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'result--></span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="image-20251003102843558" src="assets/image-20251003102843558.png"></p>
- <p><strong>拓展:</strong></p>
- <p><code>vectordb.as_retriever()</code> 和 <code>vectordb.similarity_search()</code> 都是用于从向量数据库中检索相关文档的方法,它们有什么异同:</p>
- <ul>
- <li>
- <p>相同</p>
- <ul>
- <li>核心功能:两者都基于向量相似度(如余弦相似度)从向量数据库中检索与查询最相关的文档。</li>
- <li>底层技术:通常使用相同的嵌入模型和相似度计算方式(如 FAISS、Chroma、Pinecone 等)。</li>
- </ul>
- </li>
- <li>
- <p>不同</p>
- <p><img alt="image-20250705114109276" src="assets/image-20250705114109276.png"></p>
- </li>
- </ul>
- <h4 id="44">4.4 拓展<a class="headerlink" href="#44" title="Permanent link">¶</a></h4>
- <p>其他几种常用的检索器介绍如下。</p>
- <ul>
- <li>TFIDFRetriever</li>
- </ul>
- <blockquote>
- <p>功能:基于 TF-IDF(词频-逆文档频率)的检索器。 </p>
- <p>特点:</p>
- <ul>
- <li>使用 TF-IDF 向量表示文档和查询。</li>
- <li>适合快速构建原型。</li>
- <li>不支持语义搜索。</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>文本搜索</li>
- <li>关键词提取</li>
- </ul>
- <p><strong>补充:理解 TF 和 IDF</strong></p>
- <p>为了理解后面的 BM25,可以先把 TF-IDF 拆成两个部分来看:</p>
- <ul>
- <li><strong>TF(Term Frequency,词频)</strong>:回答“这个词在当前文档中出现得多不多?”</li>
- <li><strong>IDF(Inverse Document Frequency,逆文档频率)</strong>:回答“这个词在整个知识库中是否稀有?”</li>
- </ul>
- <p>常见公式如下:</p>
- <div class="highlight"><pre><span></span><code>TF(t,d) = 词 t 在文档 d 中出现次数 / 文档 d 总词数
- IDF(t) = log(N / df(t))
- </code></pre></div>
- <ul>
- <li><code>N</code>:知识库文档总数。</li>
- <li><code>df(t)</code>:包含词 <code>t</code> 的文档数量。</li>
- </ul>
- <p>一个词越普遍,<code>df(t)</code> 越大,IDF 越小;一个词越稀有,<code>df(t)</code> 越小,IDF 越大。</p>
- <p>例如,知识库有 10 篇文档。当前 100 词的文章中,“asyncio”出现 4 次,整个知识库只有 2 篇包含它:</p>
- <div class="highlight"><pre><span></span><code>TF = 4 / 100 = 0.04
- IDF = ln(10 / 2) = ln(5) ≈ 1.609
- TF-IDF = 0.04 × 1.609 ≈ 0.064
- </code></pre></div>
- <p>如果“使用”出现在全部 10 篇文档中,则 <code>IDF = ln(10 / 10) = 0</code>。即使它在某篇文章里出现很多次,最终 TF-IDF 权重也会很低,因为它缺乏区分主题的能力。</p>
- <p>所以,TF-IDF 的核心思想是:<strong>一个词在当前文档中越常见,并且在整个知识库中越稀有,它越能代表当前文档的主题。</strong> BM25 正是在这个思想上继续加入了长度归一化和词频饱和控制。</p>
- <p>示例代码:</p>
- <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>
- <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>
- <span class="n">docs</span> <span class="o">=</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">"量子计算是一种基于量子力学的计算范式。"</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">"人工智能是模拟人类智能的技术。"</span><span class="p">)</span>
- <span class="p">]</span>
- <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>
- <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>
- <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">"量子计算"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img src="assets/image-20251003104151768.png" alt="image-20251003104151768" style="zoom:80%;"></p>
- </blockquote>
- <ul>
- <li>BM25Retriever</li>
- </ul>
- <blockquote>
- <p>BM25算法:BM25 是对 TF-IDF 的改进版本,在 TF-IDF 基础上做了归一化(防止长文档优势)与饱和控制(防止词频无限增长)。</p>
- <p><img src="assets/image-20251003105157106.png" alt="image-20251003105157106" style="zoom: 60%;"></p>
- <p><img src="assets/image-20251006090343544.png" alt="image-20251006090343544" style="zoom:67%;"></p>
- <p>功能:基于 BM25 算法的关键词检索器,适合基于词频的搜索。</p>
- <p>特点:</p>
- <ul>
- <li>不依赖嵌入模型,使用词频和逆文档频率(TF-IDF)计算相关性。</li>
- <li>适合关键词匹配场景,计算成本低。</li>
- <li>不支持语义搜索,效果依赖文本的字面匹配。</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>传统搜索场景。</li>
- <li>关键词驱动的问答。</li>
- </ul>
- <p>环境依赖:</p>
- <p>pip install rank_bm25</p>
- <p>示例代码:</p>
- <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>
- <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>
- <span class="n">docs</span> <span class="o">=</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">"量子计算是一种基于量子力学的计算范式。"</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">"人工智能是模拟人类智能的技术。"</span><span class="p">)</span>
- <span class="p">]</span>
- <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>
- <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>
- <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">"量子计算"</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img src="assets/image-20251003104151768.png" alt="image-20251003104151768" style="zoom:80%;"></p>
- </blockquote>
- <ul>
- <li>MultiQueryRetriever</li>
- </ul>
- <blockquote>
- <p>功能:它借助 LLM 自动生成多个语义等价的改写查询,把用户的问题扩展成多个角度,然后对每个改写进行检索,最后合并结果,以提高召回率。 </p>
- <p>特点:</p>
- <ul>
- <li>使用语言模型生成查询的多种表达方式</li>
- <li>从向量存储中检索所有变体的结果并合并</li>
- <li>提高召回率,适合复杂查询</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>查询表达不明确或需要覆盖多种语义</li>
- <li>提高检索的全面性
- </li>
- </ul>
- </blockquote>
- <ul>
- <li>EnsembleRetriever</li>
- </ul>
- <blockquote>
- <p>功能:结合多种检索器(如 BM25 和向量存储),融合结果。</p>
- <p>特点:</p>
- <ul>
- <li>结合关键词搜索和语义搜索的优点</li>
- <li>支持加权融合,调整不同检索器的权重</li>
- <li>提高召回率和精准度</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>需要综合关键词和语义的搜索</li>
- <li>复杂查询场景
- </li>
- </ul>
- </blockquote>
- <ul>
- <li>ContextualCompressionRetriever</li>
- </ul>
- <blockquote>
- <p>功能:对检索结果进行压缩,提取最相关的内容 </p>
- <p>特点:</p>
- <ul>
- <li>使用语言模型对检索到的文档进行重新排序或精炼</li>
- <li>减少无关内容,提高结果质量</li>
- <li>增加计算开销,但提升精准度</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>文档内容冗长,需要提取关键信息</li>
- <li>提高问答系统的答案质量
- </li>
- </ul>
- </blockquote>
- <ul>
- <li>Custom Retriever</li>
- </ul>
- <blockquote>
- <p>功能:开发者可以自定义检索逻辑,适配特定数据源或算法 </p>
- <p>特点:</p>
- <ul>
- <li>继承 BaseRetriever 类,实现 get_relevant_documents 方法</li>
- <li>支持任意数据源(如数据库、API)</li>
- </ul>
- <p>适用场景:</p>
- <ul>
- <li>特定领域的数据源(如内部数据库)</li>
- <li>自定义检索算法
- </li>
- </ul>
- </blockquote>
- <h2 id="agents">八、Agents<a class="headerlink" href="#agents" title="Permanent link">¶</a></h2>
- <h3 id="1-agent">1 Agent 概念<a class="headerlink" href="#1-agent" title="Permanent link">¶</a></h3>
- <p>Agent(智能体)是一种能够感知环境、进行决策和执行动作的智能实体。不同于传统的人工智能,Agent 具备通过主动思考、调用工具去逐步完成给定目标的能力。</p>
- <p>为什么要调用工具?</p>
- <ul>
- <li>因为大模型虽然非常强大,但是也具备一定的局限性,比如不能回答实时信息、处理数学逻辑问题仍然非常的初级等等。因此,可以借助第三方工具来辅助大模型的应用。</li>
- </ul>
- <p>从大模型的角度来看,<strong>Agent其实就是基于大模型的语义理解和推理能力,让大模型拥有解决复杂问题时的任务规划能力,并调用外部工具来执行各种任务,利用向量数据库保留“记忆”的一个智能体</strong>。</p>
- <blockquote>
- <p>Agent = 大模型 + 任务规划(Planning) + 使用外部工具执行任务(Tools&Action) + 记忆(Memory)</p>
- <p>把Agent比作一个人的话,<strong>他应该有大脑(语义理解、存储记忆、推理规划、专业知识)、五官(接收文本、视觉输入、听觉输入等)、四肢(使用工具完成各种具体任务)等主要部件</strong></p>
- </blockquote>
- <hr>
- <p><strong>工作流程概述:</strong></p>
- <ul>
- <li>用户提出任务。</li>
- <li>Agent 启动: 将用户输入与预设的“提示词模板”结合,并结合当前的“上下文”和“变量”,形成一个完整的输入发送给大模型。</li>
- <li>大模型思考与决策 (循环):<ul>
- <li>大模型接收输入后,根据其内置的逻辑和提示词的指导,进行“思考”。</li>
- <li>它会判断完成当前任务是需要继续使用工具来获取更多信息/执行操作,还是已经可以直接生成最终答案。</li>
- <li>如果需要工具: 大模型会根据任务需求和对工具的描述,选择合适的工具,并生成执行该工具所需的输入参数。这些参数通常会从上下文或变量中提取。</li>
- <li>工具执行: 选定的工具被调用,执行其功能。</li>
- <li>结果反馈: 工具执行的结果会返回给 Agent,并被用来更新“上下文”和“变量”。</li>
- <li>循环: Agent 将更新后的“上下文”、“变量”以及工具执行结果再次反馈给大模型,大模型继续进行新一轮的“思考-行动”循环,直到任务完成。</li>
- <li>如果直接回答: 当大模型判断任务已完成,或无需额外工具即可回答时,它会生成最终的答案。</li>
- </ul>
- </li>
- <li>用户输出: 最终答案被呈现给用户。</li>
- </ul>
- <h3 id="2-agent">2 Agent关键组成部分<a class="headerlink" href="#2-agent" title="Permanent link">¶</a></h3>
- <p><img alt="image-20250705115745718" src="assets/image-20250705115745718.png"></p>
- <ul>
- <li>
- <p>任务规划(Planning)</p>
- <p>Agent需要提前将一项复杂任务拆解为多个更小、更易于处理的子任务,从而实现对复杂任务的高效处理</p>
- </li>
- <li>
- <p>长短期记忆(Memory)</p>
- <p>聊天上下文,长期保留和回忆信息</p>
- </li>
- <li>
- <p>工具&执行(Tools&Action)</p>
- <p>根据拆分好的子任务,调用外部提供好的专业API解决专业问题,完成一个个具体的子任务,并把处理结果返回给大模型</p>
- </li>
- </ul>
- <h3 id="3-langchainagent">3 langchain实现Agent<a class="headerlink" href="#3-langchainagent" title="Permanent link">¶</a></h3>
- <p>LangChain 提供了不同类型的代理(主要罗列一下三种):</p>
- <ul>
- <li>
- <p><strong>Zero-shot ReAct Description</strong></p>
- <ul>
- <li>
- <p>基于 <strong>ReAct 框架</strong>(推理 + 行动),仅依赖工具的 <strong>描述</strong> 来决定调用哪个工具。</p>
- </li>
- <li>
- <p>特点:无需额外示例(zero-shot),但 <strong>不具备记忆能力</strong>,每次推理都独立进行。</p>
- </li>
- <li>
- <p>使用场景:简单任务,工具选择完全靠工具描述即可。</p>
- </li>
- </ul>
- </li>
- <li>
- <p><strong>Structured Chat Zero-shot ReAct Description</strong></p>
- <ul>
- <li>
- <p>同样基于 <strong>ReAct 框架</strong>,但可以处理 <strong>结构化输入</strong>,即支持带多个参数的工具(类似函数调用)。</p>
- </li>
- <li>
- <p>特点:不仅能像第一种代理那样根据描述选择工具,还能正确组织并传递复杂参数。</p>
- </li>
- <li>
- <p>使用场景:调用接口类工具、需要多参数输入的任务。</p>
- </li>
- </ul>
- </li>
- <li>
- <p><strong>Conversational ReAct Description</strong></p>
- <ul>
- <li>
- <p>在 ReAct 框架基础上,增强了 <strong>对话记忆能力</strong>。</p>
- </li>
- <li>
- <p>特点:能根据上下文对话历史来做出工具选择和回应,更适合持续性对话场景。</p>
- </li>
- <li>
- <p>使用场景:多轮对话,用户可能引用之前的内容或需要长期上下文跟踪。</p>
- </li>
- </ul>
- </li>
- </ul>
- <hr>
- <p>LangChain 中集成了很多工具,可以通过下面的方式进行查询:</p>
- <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>
- <span class="n">results</span> <span class="o">=</span> <span class="n">get_all_tool_names</span><span class="p">()</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">results</span><span class="p">)</span>
- </code></pre></div>
- <p>运行结果:</p>
- <div class="highlight"><pre><span></span><code>['sleep', 'wolfram-alpha', 'google-search', 'google-search-results-json', 'searx-search-results-json', 'bing-search', 'metaphor-search', 'ddg-search', 'google-books', 'google-lens', 'google-serper', 'google-scholar', 'google-finance', 'google-trends', 'google-jobs', 'google-serper-results-json', 'searchapi', 'searchapi-results-json', 'serpapi', 'dalle-image-generator', 'twilio', 'searx-search', 'merriam-webster', 'wikipedia', 'arxiv', 'golden-query', 'pubmed', 'human', 'awslambda', 'stackexchange', 'sceneXplain', 'graphql', 'openweathermap-api', 'dataforseo-api-search', 'dataforseo-api-search-json', 'eleven_labs_text2speech', 'google_cloud_texttospeech', 'read_file', 'reddit_search', 'news-api', 'tmdb-api', 'podcast-api', 'memorize', 'llm-math', 'open-meteo-api', 'requests', 'requests_get', 'requests_post', 'requests_patch', 'requests_put', 'requests_delete', 'terminal']
- </code></pre></div>
- <hr>
- <p>接下来,通过一个示例来学习Agent的基本使用。</p>
- <ul>
- <li>问题1:计算一下300的25%是多少?</li>
- <li>问题2:请帮我介绍一下故宫</li>
- </ul>
- <p>示例代码:</p>
- <blockquote>
- <p>需要提前安装 wikipedia</p>
- <p>pip install wikipedia</p>
- </blockquote>
- <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="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>
- <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>
- <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>
- <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>
- <span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
- <span class="c1"># 实例化模型</span>
- <span class="n">model</span> <span class="o">=</span> <span class="n">ChatOpenAI</span><span class="p">(</span>
- <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">'base_url'</span><span class="p">,</span><span class="s1">'https://dashscope.aliyuncs.com/compatible-mode/v1'</span><span class="p">),</span>
- <span class="n">model</span><span class="o">=</span><span class="s1">'qwen-plus'</span><span class="p">,</span>
- <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">'api_key'</span><span class="p">,</span><span class="s1">'sk-XXXXXXXX'</span><span class="p">),</span>
- <span class="n">max_tokens</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
- <span class="n">temperature</span><span class="o">=</span><span class="mi">0</span>
- <span class="p">)</span>
- <span class="c1"># Create the agent</span>
- <span class="n">memory</span> <span class="o">=</span> <span class="n">MemorySaver</span><span class="p">()</span>
- <span class="n">tools</span> <span class="o">=</span> <span class="n">load_tools</span><span class="p">([</span><span class="s1">'wikipedia'</span><span class="p">,</span> <span class="s1">'llm-math'</span><span class="p">],</span> <span class="n">llm</span><span class="o">=</span><span class="n">model</span><span class="p">)</span>
- <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>
- <span class="c1"># Use the agent</span>
- <span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"configurable"</span><span class="p">:</span> <span class="p">{</span><span class="s2">"thread_id"</span><span class="p">:</span> <span class="s2">"abc123"</span><span class="p">}}</span>
- <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>
- <span class="p">{</span><span class="s2">"messages"</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">"计算一下300的25%是多少?"</span><span class="p">)]},</span> <span class="n">config</span>
- <span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">chunk</span><span class="p">)</span>
- <span class="nb">print</span><span class="p">(</span><span class="s2">"----"</span><span class="p">)</span>
- <span class="c1"># for chunk in agent_executor.stream(</span>
- <span class="c1"># {"messages": [HumanMessage(content="大熊猫是哪个国家的国宝?")]}, config</span>
- <span class="c1"># ):</span>
- <span class="c1"># print(chunk)</span>
- <span class="c1"># print("----")</span>
- </code></pre></div>
- <p>运行结果:</p>
- <p><img alt="1768397211211" src="assets/1768397211211.png"></p>
- <blockquote>
- <p>参考官网 <a href="https://python.langchain.com/docs/how_to/custom_tools/">https://python.langchain.com/docs/how_to/custom_tools/</a></p>
- </blockquote>
- <h2 id="langchain">九、LangChain使用场景<a class="headerlink" href="#langchain" title="Permanent link">¶</a></h2>
- <ul>
- <li>个人助手</li>
- <li>基于文档的问答系统</li>
- <li>聊天机器人</li>
- <li>Tabular数据查询</li>
- <li>API交互</li>
- <li>信息提取</li>
- <li>文档总结</li>
- </ul>
- <h2 id="_3">十、本节小结<a class="headerlink" href="#_3" title="Permanent link">¶</a></h2>
- <p>本章主要介绍了LangChain的基本组件及使用方式。</p>
- <h2 id="_4">十一、本节作业<a class="headerlink" href="#_4" title="Permanent link">¶</a></h2>
- <h3 id="1-1">1 作业1<a class="headerlink" href="#1-1" title="Permanent link">¶</a></h3>
- <ul>
- <li>题目1:什么是LangChain?请解释其核心组件和设计思想。</li>
- <li>题目2:解释LangChain中的链(Chain)概念,并介绍主要的链类型。</li>
- <li>题目3:解释LangChain中的Prompts概念,并介绍主要类型。</li>
- <li>题目4:实现LangChain中的output_parsers的具体使用方式</li>
- </ul>
- <h3 id="2-2">2 作业2<a class="headerlink" href="#2-2" title="Permanent link">¶</a></h3>
- <ul>
- <li>题目1:什么是Memory组件?请解释LangChain中不同类型的记忆机制。</li>
- <li>题目2:解释LangChain中的提示工程及其最佳实践。</li>
- <li>题目3:LangChain的Document Loaders?请介绍其功能和主要类型。</li>
- <li>题目4 :什么是LangChain的代理(Agent)?请说明其工作原理和应用。</li>
- </ul>
-
- </article>
- </div>
-
-
- <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
- </div>
-
- </main>
-
- <footer class="md-footer">
-
- <div class="md-footer-meta md-typeset">
- <div class="md-footer-meta__inner md-grid">
- <div class="md-copyright">
-
- <div class="md-copyright__highlight">
- © EnterpriseKB-RAG 2026. Internal knowledge base demo site.
- </div>
-
-
- Made with
- <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
- Material for MkDocs
- </a>
-
- </div>
-
- </div>
- </div>
- </footer>
-
- </div>
- <div class="md-dialog" data-md-component="dialog">
- <div class="md-dialog__inner md-typeset"></div>
- </div>
-
-
-
-
- <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>
-
-
- <script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
-
- <script src="../javascripts/extra.js"></script>
-
- <script src="../javascripts/mathjax.js"></script>
-
- <!-- <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>-->
-
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
-
-
- </body>
- </html>
|