Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

ประวัติการแชทที่คงอยู่ด้วย LangChain &Upstash Redis

LangChain มอบอินเทอร์เฟซที่เรียบง่ายเพื่อดำเนินการสนทนาระหว่างมนุษย์กับ AI สามารถกำหนดค่าให้ใช้ 01 ได้อย่างง่ายดาย ทำให้คุณสามารถจัดเก็บประวัติการสนทนาไว้ในหน่วยความจำได้ สิ่งนี้อาจน่าพอใจสำหรับกรณีการใช้งานบางกรณี แต่แอปของคุณอาจต้องมีประวัติการแชทคงอยู่ในระยะยาว โชคดีที่การเปลี่ยนสิ่งนี้เป็นอินสแตนซ์ Upstash Redis ก็ทำได้ง่ายพอๆ กัน

LangChain นำเสนอการบูรณาการที่หลากหลายสำหรับ Redis รวมถึง 16 , 28 และอัพสแตช เรดิส เนื่องจากไคลเอ็นต์ Upstash Redis ทำงานผ่าน REST คุณจึงใช้ไคลเอ็นต์นี้เพื่อสร้างแอปพลิเคชันที่พร้อมใช้งาน Edge ซึ่งสามารถนำไปใช้กับ Vercel, Cloudflare Workers หรือสภาพแวดล้อมแบบไร้เซิร์ฟเวอร์อื่นๆ ได้ เราจะใช้มันเพื่อสร้างแอปแชทง่ายๆ ที่มีหน่วยความจำที่คงอยู่ตลอดเซสชัน

คุณสามารถค้นหาซอร์สโค้ดแบบเต็มสำหรับการสาธิตนี้ได้ที่นี่

ข้อกำหนดเบื้องต้น

  • ฐานข้อมูล Upstash Redis
  • คีย์ OpenAI API

เริ่มต้นใช้งาน

การสร้างโครงการ

เราจะสร้างแอป Next.js พื้นฐานโดยใช้ Vercel AI SDK เพื่อสาธิตวิธีใช้ LangChain กับ Upstash Redis ในการเริ่มต้น ให้สร้างแอป Next.js ใหม่:

npx create-next-app@latest

การดำเนินการนี้จะขอให้คุณเลือกตัวเลือกโครงการบางส่วน สำหรับแอปส่วนใหญ่ ค่าเริ่มต้นจะทำงานได้ดี เพื่อวัตถุประสงค์ของการสาธิตนี้ อย่าลืมเปิดใช้งาน TypeScript และ 31 ไดเร็กทอรี

การติดตั้งการอ้างอิง

เมื่อสร้างแอปแล้ว คุณจะต้องติดตั้งการอ้างอิงบางส่วน:

npm install ai langchain openai @upstash/redis

แม้ว่าจะไม่ได้กำหนดไว้อย่างเคร่งครัด แต่ Vercel AI SDK จะทำให้การสตรีมการตอบสนองจาก OpenAI ไปยังฟรอนต์เอนด์ Next.js ของเราง่ายขึ้น เราจะต้องใช้ 47 เท่านั้น เพื่อสร้างไคลเอนต์ Redis—LangChain จะดูแลส่วนที่เหลือ

การตั้งค่าตัวแปรสภาพแวดล้อม

สุดท้ายนี้ เราจะต้องมีตัวแปรสภาพแวดล้อมต่อไปนี้จากข้อกำหนดเบื้องต้นก่อนหน้านี้ อย่าลืมตั้งชื่อให้ตรงตามที่อธิบายไว้ที่นี่ เพราะไม่เช่นนั้นระบบจะไม่อ่านอัตโนมัติ! คุณสามารถเพิ่มสิ่งเหล่านี้ลงใน 51 ไฟล์ในรูทของโปรเจ็กต์ใหม่ของคุณ:

UPSTASH_REDIS_REST_URL="https://********.upstash.io"
UPSTASH_REDIS_REST_TOKEN="********"
OPENAI_API_KEY="sk-********"

การสร้างไคลเอนต์แชทพื้นฐาน

คุณจะสังเกตเห็นว่า Next.js ได้สร้างไฟล์จำนวนหนึ่งให้เรา เราจะทำงานกับไฟล์บางไฟล์ใน 68 เท่านั้น directory เพื่อให้คุณสามารถลบทุกอย่างที่อยู่ใน 79 ในปัจจุบันได้ และ 84 .

ในการเริ่มต้น เราจะสร้าง 91 พื้นฐาน เพื่อจัดเก็บแอปของเรา:

import type { PropsWithChildren } from "react";
 
export default function RootLayout({ children }: PropsWithChildren) {
 return (
 <html lang="en">
 <body>{children}</body>
 </html>
 );
}

ต่อไป เราจะต้องมีแบบฟอร์มพื้นฐานพร้อมอินพุตเพื่อรับข้อความจากผู้ใช้ สามารถเพิ่มลงใน 101 ของเราได้ :

export default function Home() {
 return (
 <main>
 <form>
 <input placeholder="Enter a message..." />
 <button type="submit">Send</button>
 </form>
 </main>
 );
}

ประวัติการแชทที่คงอยู่ด้วย LangChain &Upstash Redis

Vercel AI SDK ส่งออก hook ที่มีประโยชน์ที่เรียกว่า 110 ซึ่งทำให้การสร้างอินเทอร์เฟซผู้ใช้ทั่วไปสำหรับแอปแชทของเราเป็นเรื่องง่ายมาก จัดการข้อความแชทแบบสตรีมและจัดการสถานะของอินพุตแชทของเรา หากต้องการใช้ hook เราต้องบอก React ว่านี่คือส่วนประกอบของไคลเอ็นต์โดยเพิ่ม 123 คำสั่งที่ด้านบนของไฟล์ของเรา จากนั้น เราสามารถทำลายคุณสมบัติบางส่วนจาก 133 ได้ ตะขอ:

  • 147 คืออาร์เรย์ของข้อความที่ส่งและรับ
  • 151 คือค่าปัจจุบันของช่องป้อนข้อมูล
  • 166 เป็นฟังก์ชันที่อัพเดตค่าอินพุต
  • 177 เป็นฟังก์ชันที่ส่งข้อความไปยังปลายทางของเรา
"use client";
 
import { useChat } from "ai/react";
 
export default function Home() {
 const { messages, input, handleInputChange, handleSubmit } = useChat();
 
 return (
 <main>
 <form onSubmit={handleSubmit}>
 <input
 value={input}
 onChange={handleInputChange}
 placeholder="Enter a message..."
 />
 <button type="submit">Send</button>
 </form>
 </main>
 );
}

ภายใน 186 hook จะเพิ่ม 199 โดยอัตโนมัติ เป็น 209 เมื่อ 212 ถูกเรียก ซึ่งทำให้เกิดการเรนเดอร์ใหม่ ดังนั้นเราจึงไม่ต้องกังวลกับการอัปเดต UI ด้วยตนเอง นอกจากนี้ยังจะล้างช่องป้อนข้อมูลและทริกเกอร์การเรียก API ไปยังตำแหน่งข้อมูลที่ระบุ โดยค่าเริ่มต้น นี่คือ 226 .

สุดท้ายนี้ มาแสดงผล 236 กัน เหนือแบบฟอร์มของเรา:

<main>
 <section>
 {messages.map((message) => (
 <p key={message.id}>{message.content}</p>
 ))}
 </section>
 
 {/* snip */}
</main>

การสร้างจุดสิ้นสุด API

เราสามารถเริ่มต้นด้วยการสร้าง 248 ไฟล์เพื่อเก็บปลายทางของเรา Next.js ใช้การกำหนดเส้นทางตามไฟล์สำหรับตำแหน่งข้อมูล API และหน้าต่างๆ ด้วยเหตุนี้โครงสร้างโฟลเดอร์สำหรับไฟล์ใหม่นี้จึงตรงกับตำแหน่งข้อมูลเริ่มต้น 250 จากเมื่อก่อน

เนื่องจากเราใช้ Upstash Redis ตำแหน่งข้อมูลของเราจึงเข้ากันได้กับ Edge เราสามารถระบุสิ่งนี้ได้โดยส่งออก 269 จากจุดสิ้นสุดของเรา ในตัวปลายทางเอง เราสามารถดึงข้อมูล 275 ได้ ฟิลด์ที่ 288 เบ็ดมีประชากรสำหรับเรา สิ่งนี้ทำให้เราสามารถส่งข้อความล่าสุดไปยัง LangChain:

import { type NextRequest } from "next/server";
 
import { LangChainStream, StreamingTextResponse } from "ai";
 
export const runtime = "edge";
 
export async function POST(req: NextRequest) {
 const { messages } = await req.json();
 const { stream, handlers } = LangChainStream();
 
 const latestMessage = messages[messages.length - 1];
 
 return new StreamingTextResponse(stream);
}

ชอบ 291 จากเมื่อก่อน 305 ยังส่งคืนคุณสมบัติบางอย่างที่เราสามารถทำลายโครงสร้างได้

  • 319 คือ 328 ซึ่งในที่สุดจะประกอบไปด้วยผลลัพธ์ของกระบวนการ LangChain
  • 336 เป็นออบเจ็กต์ที่มีฟังก์ชันเรียกกลับ LLM ที่สามารถส่งผ่านไปยัง LangChain ได้

ก่อนที่เราจะสามารถประยุกต์ห่วงโซ่ได้ เราจะต้องนำเข้าคลาสเพิ่มเติมสองสามคลาสก่อน:

import { Redis } from "@upstash/redis";
import { ConversationChain } from "langchain/chains";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { BufferMemory } from "langchain/memory";
import { UpstashRedisChatMessageHistory } from "langchain/stores/message/upstash_redis";

ตอนนี้เราสามารถสร้างไคลเอนต์ Redis และตั้งค่าหน่วยความจำสำหรับเครือข่ายของเราได้แล้ว ที่นี่ เราสร้าง 342 ที่เราสามารถเรียกแทนตัวโมเดลได้นั่นเอง เป็นห่วงโซ่แบบกำหนดเองที่อำนวยความสะดวกในการสนทนาระหว่างมนุษย์กับ AI เราสามารถส่งผ่าน 354 ที่กำหนดเองได้ นำไปใช้กับห่วงโซ่ซึ่งจะใช้ในการจัดเก็บและเรียกค้นข้อความ ในกรณีนี้ เรากำลังใช้ 364 ด้วย 373 เพื่อจัดเก็บข้อความใน Upstash Redis:

// snip
const latestMessage = messages[messages.length - 1];
 
const memory = new BufferMemory({
 chatHistory: new UpstashRedisChatMessageHistory({
 sessionId: new Date().toLocaleDateString(),
 client: Redis.fromEnv(),
 }),
});
 
const model = new ChatOpenAI({
 modelName: "gpt-3.5-turbo",
 streaming: true,
});
 
const chain = new ConversationChain({ llm: model, memory });
// snip

เราสร้างไคลเอนต์ Redis ใหม่โดยใช้ 384 คลาสที่สำรวจจาก 392 . โดยให้วิธีการโหลดตัวแปรสภาพแวดล้อมโดยอัตโนมัติอย่างสะดวกสบาย ซึ่งสะท้อนพฤติกรรมของ 400 . ตราบใดที่คุณตั้งชื่อตัวแปรสภาพแวดล้อมของคุณอย่างถูกต้อง คุณไม่จำเป็นต้องส่งอาร์กิวเมนต์เพิ่มเติมใดๆ ในคลาสเหล่านี้

ในแอปของคุณ คุณอาจต้องการใช้ ID ผู้ใช้หรือตัวระบุที่ไม่ซ้ำกันอื่นๆ สำหรับ 412 เพื่อให้แน่ใจว่าข้อความจะไม่ถูกแชร์ระหว่างผู้ใช้ แต่เราจะใช้วันที่ปัจจุบันเพื่อการสาธิตนี้ 427 มีตัวเลือกการกำหนดค่าเพิ่มเติม เช่น 430 เพื่อกำหนดอายุการใช้งานของแคช

สิ่งสำคัญคือต้องเปิดใช้งาน 440 บนโมเดล เนื่องจากจะทำให้เราใช้ 453 ที่ถูกทำลายแล้วได้ object จาก before ไปป์ผลลัพธ์ของ chain ไปที่ 464 . ในที่สุด เราก็สามารถเรียกลูกโซ่ ส่งข้อความล่าสุดและ 474 ได้ วัตถุ:

// snip
const chain = new ConversationChain({ llm: model, memory });
 
chain.call({
 input: latestMessage.content,
 callbacks: [handlers],
});
 
return new StreamingTextResponse(stream);
// snip

482ของเรา วัตถุจากก่อนหน้านี้ถูกใช้เป็นพรอมต์สำหรับ LLM เรายังผ่าน 497 คัดค้านลูกโซ่ซึ่งจะใช้ในการไพพ์ผลลัพธ์ไปที่ 500 .

บทสรุป

แค่นั้นแหละ! ตอนนี้คุณสามารถเรียกใช้แอปของคุณด้วย 519 และเริ่มแชทกับ AI ของคุณ การตอบกลับจะถูกสตรีมกลับไปยังไคลเอนต์ที่เราสร้างไว้ก่อนหน้านี้โดยอัตโนมัติ และประวัติการสนทนาจะถูกจัดเก็บไว้ใน Upstash Redis

ประวัติการแชทที่คงอยู่ด้วย LangChain &Upstash Redis

ประวัติการแชทที่คงอยู่ด้วย LangChain &Upstash Redis