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>
);
}

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ซึ่งในที่สุดจะประกอบไปด้วยผลลัพธ์ของกระบวนการ LangChain336รหัส> เป็นออบเจ็กต์ที่มีฟังก์ชันเรียกกลับ 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

