Bạn đã sử dụng Google hoặc Perplexity.ai chưa? Bạn có thắc mắc làm thế nào họ có thể hiển thị kết quả tìm kiếm mới nhất và bao gồm các liên kết đến các bài viết trực tuyến không? Chà, trong hướng dẫn này, bạn sẽ học cách tự mình tạo ra một hệ thống như vậy. Bạn sẽ tìm hiểu cách tạo một hệ thống có thể tạo đề xuất dựa trên liên kết của các bài viết mà bạn thêm vào ngân hàng kiến thức đang phát triển của nó.
Điều kiện tiên quyết
Bạn sẽ cần những thứ sau:
- Node.js 18 trở lên
- Tài khoản Upstash
- Tài khoản OpenAI
- Tài khoản Fly.io
Ngăn xếp công nghệ
Các bước
Để hoàn thành hướng dẫn này và triển khai hệ thống đề xuất bài viết của riêng bạn, bạn cần làm theo các bước sau:
- Tạo mã thông báo OpenAI
- Tạo chỉ mục vectơ Upstash
- Thiết lập dự án
- Khởi tạo ứng dụng khách API OpenAI
- Tạo ứng dụng khách nhúng API OpenAI
- Tạo ứng dụng khách Vector Upstash
- Tạo Điểm cuối API ngữ cảnh
- Tạo Điểm cuối API trò chuyện
- Triển khai để Fly.io
- Tài liệu tham khảo
- Kết luận
Tạo mã thông báo OpenAI
Bằng cách sử dụng API OpenAI, bạn có thể lấy các phần nhúng vectơ của bài viết và tạo phản hồi chatbot bằng AI. Mọi yêu cầu đối với API OpenAI đều yêu cầu mã thông báo ủy quyền. Để nhận mã thông báo, hãy điều hướng đến Khóa API trong tài khoản OpenAI của bạn và nhấp vào Tạo khóa bí mật mới nút. Sao chép và lưu trữ an toàn mã thông báo này để sử dụng sau dưới dạng OPENAI_API_KEY biến môi trường.
Tạo chỉ mục vectơ Upstash
Khi bạn đã tạo tài khoản Upstash và đăng nhập, hãy chuyển đến tab Vector và nhấp vào Tạo chỉ mục để bắt đầu tạo chỉ mục vector.

Nhập tên chỉ mục bạn chọn (giả sử article ) và đặt kích thước vectơ là 1536.

Bây giờ, hãy cuộn xuống cho đến phần Kết nối và nhấp vào .env nút. Sao chép nội dung và lưu nó ở nơi an toàn để sử dụng thêm trong ứng dụng của bạn.

Thiết lập dự án
Để thiết lập, chỉ cần sao chép kho ứng dụng và làm theo hướng dẫn này để tìm hiểu mọi thứ có trong đó. Để sao chép dự án, hãy chạy lệnh sau trong terminal:
# Clone the project
git clone https://github.com/rishi-raj-jain/article-recommendation-system
cd article-recommendation-system
# Install the dependencies
pnpm install
Khi bạn đã sao chép kho lưu trữ, hãy tạo .env tập tin. Bạn sẽ thêm các khóa bí mật thu được trong các phần trên.
.env tập tin phải chứa các khóa sau:
# .env
# OpenAI API Key
OPENAI_API_KEY="sk-..."
# Upstash Vector Keys
UPSTASH_VECTOR_REST_URL="https://...-us1-vector.upstash.io"
UPSTASH_VECTOR_REST_TOKEN="...=" Khi đã xong, quá trình thiết lập cấu hình của bạn đã hoàn tất. Bây giờ, bạn có thể xem ứng dụng đang hoạt động bằng cách thực hiện lệnh sau trong thiết bị đầu cuối của mình và truy cập localhost:3000.
pnpm run build && pnpm run start Hãy theo dõi để hiểu các phần liên quan của mã cho phép bạn xây dựng thành công hệ thống đề xuất bài viết của riêng mình.
Khởi tạo ứng dụng khách API OpenAI
Với openai gói, bạn có thể tiết kiệm thời gian và tương tác với OpenAI REST API chỉ trong vài dòng mã. Với đoạn mã sau, chúng tôi đã khởi tạo thư viện Ứng dụng khách API OpenAI để sử dụng thêm nhằm tạo phản hồi hoàn thành cuộc trò chuyện.
// File: app/lib/openai/completion.server.ts
import OpenAI from 'openai'
// Instantiate class to generate text completion using the OpenAI API
export default new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
Lưu ý:Bằng cách thêm .server.ts đối với một tệp trong Remix, bạn có thể đảm bảo rằng mã của nó bị buộc loại bỏ của gói phía máy khách.
Tạo ứng dụng khách nhúng API OpenAI
Với @langchain/openai gói, bạn có thể sử dụng OpenAIEmbeddings lớp để tạo các vectơ nhúng của một văn bản nhất định. Khi được kết hợp với bất kỳ Cửa hàng Vector LangChain nào, lớp OpenAIEmbeddings sẽ giúp bạn tránh khỏi quá trình tạo và chèn từng vectơ nhúng của riêng bạn. Với đoạn mã sau, chúng tôi đã khởi tạo lớp OpenAIEmbeddings để sử dụng thêm nhằm tạo các phần nhúng vectơ bên trong.
// File: app/lib/openai/embedding.server.ts
import { OpenAIEmbeddings } from '@langchain/openai'
// Instantiate class to generate embeddings using the OpenAI API
export default new OpenAIEmbeddings({
modelName: 'text-embedding-3-small',
openAIApiKey: process.env.OPENAI_API_KEY,
}) Tạo ứng dụng khách Upstash Vector
Sử dụng @upstash/vector và @langchain/community/vectorstores/upstash gói, bạn có thể tạo một ứng dụng khách không kết nối trong ứng dụng Remix của mình, cho phép bạn lưu trữ, xóa và truy vấn các phần nhúng vectơ từ chỉ mục Upstash Vector.
// File: app/lib/upstash/vectorStore.server.ts
import embeddings from '~/lib/openai/embedding.server'
import { Index as UpstashIndex } from '@upstash/vector'
import { UpstashVectorStore } from '@langchain/community/vectorstores/upstash'
// Instantiate the Upstash Vector Index
const index = new UpstashIndex({
url: process.env.UPSTASH_VECTOR_REST_URL as string,
token: process.env.UPSTASH_VECTOR_REST_TOKEN as string,
})
// Instantiate the Upstash Vector Store that'll create and save embeddings
export default new UpstashVectorStore(embeddings, { index }) Tạo Điểm cuối API ngữ cảnh
Khi chạy ứng dụng Remix, bạn sẽ thấy một hộp văn bản chấp nhận nhiều URL bài viết làm đầu vào. Những bài viết đó sẽ được bổ sung vào kiến thức của chatbot để tạo ra phản hồi được cá nhân hóa trong các tìm kiếm của người dùng trong tương lai. Trong phần này, bạn sẽ tìm hiểu cách điểm cuối ngữ cảnh (app/routes/api_.context.tsx ) được thiết lập để chấp nhận nhiều URL bài viết đó, tìm nạp nội dung của chúng, tạo các phần nhúng vectơ của chúng và lưu trữ chúng vào Chỉ mục Vector Upstash một cách linh hoạt.
// File: app/routes/api_.context.tsx
import { Document } from 'langchain/document'
import { ActionFunctionArgs } from '@remix-run/node'
import vectorServer from '~/lib/vector/vectorStore.server'
import { CheerioWebBaseLoader } from 'langchain/document_loaders/web/cheerio'
export const action = async ({ request }: ActionFunctionArgs) => {
const formData = await request.formData()
// Check if any article link are present in the form submission
const articlesToEmbed = formData.get('articles') as string
if (articlesToEmbed) {
// Create the documents to be added to the Upstash Vector Store
const documents: any[] = []
await Promise.all(
articlesToEmbed.split(',').map(async (link) => {
// Use the link to render in the search results
// Parse the link using Cheerio
const loader = new CheerioWebBaseLoader(link.trim())
const scraper = await loader.scrape()
// Get the content of title tag to render in the search results
const name = scraper('title').html()
// Get the page content as string
const pageContent = scraper.text()
// Create metadata object to be inserted in the vector store
const metadata = { link, name }
documents.push(new Document({ pageContent, metadata }))
}),
)
// Creating embeddings from the provided documents along with metadata
// and add them to Upstash database
await vectorServer.addDocuments(documents.filter(Boolean))
}
}
Trong Hành động phối lại ở trên, dữ liệu biểu mẫu có trong yêu cầu POST tới điểm cuối ngữ cảnh (/api/context ) được phân tích cú pháp. Hơn nữa, có một vòng lặp trên tập hợp các liên kết bài viết được phân tách bằng dấu phẩy (,) thực hiện như sau:
- Tạo một
pageContentbiến khi nội dung văn bản được tìm nạp từ trang web của bài viết - Tạo một
namebiến làm tiêu đề trang web của bài viết - Tạo Tài liệu LangChain với nội dung văn bản, tài liệu tham khảo và tên bài viết (
new Document({ pageContent, metadata })) - Thêm từng tài liệu vào
documentstoàn cục mảng
Cuối cùng, tất cả các tài liệu được lưu trữ trong documents toàn cục mảng được chèn vào Chỉ mục Vector Upstash. Dưới lớp vỏ bọc, các phần nhúng vectơ cho mỗi tài liệu được tạo bằng cách sử dụng pageContent của nó tài sản.
Tạo Điểm cuối API trò chuyện
Trong phần này, bạn sẽ tìm hiểu cách điểm cuối api trò chuyện (app/routes/api_.chat.tsx ) được thiết lập để tạo các phản hồi giống như công cụ tìm kiếm chứa các đề xuất cho các bài viết có liên quan đến tìm kiếm của người dùng. Các bài viết liên quan đến tìm kiếm được tìm thấy bằng cách tìm các vectơ top-K gần nhất từ một chỉ mục vectơ nhất định. Hơn nữa, tiêu đề và liên kết từ siêu dữ liệu của vectơ được chuyển vào API OpenAI dưới dạng ngữ cảnh. Điều này cho phép chatbot bao gồm các bài viết dưới dạng liên kết bên ngoài kết hợp với việc phản hồi tìm kiếm của người dùng. Để đơn giản hóa mọi thứ, chúng tôi sẽ chia phần này thành các phần khác:
Tìm các vectơ nhúng có liên quan bằng cách sử dụng tìm kiếm tương tự
Việc xem lại toàn bộ ngân hàng kiến thức các bài báo cho mỗi lần tìm kiếm của người dùng là một hoạt động tốn kém. Để giới hạn nó trong 3 bài viết hàng đầu (nếu) có liên quan cao đến tìm kiếm của người dùng, hãy truy vấn tập hợp vectơ hiện có trong Chỉ mục vectơ Upstash của bạn. Hơn nữa, hãy lọc để giữ lại các vectơ có phần nhúng có điểm tương đồng ít nhất 70% với phần nhúng vectơ trong tìm kiếm của người dùng.
// File: app/routes/api_.chat.tsx
import vectorServer from '~/lib/upstash/vectorStore.server'
import type { ActionFunctionArgs } from '@remix-run/node'
export const action = async ({ request }: ActionFunctionArgs) => {
// Set of messages between user and chatbot
const { messages = [] } = await request.json()
// Get the latest question stored in the last message of the chat array
const searchQuery = messages[messages.length - 1].content
// Perform Similarity Search using the Upstash Vector Store
const queryResult = await vectorServer.similaritySearchWithScore(searchQuery, 3)
// Filter the records with confidence score > 70% and
// set the metadata as response to render search results
const results = queryResult.filter((i) => i[1] >= 0.7).map((i) => i[0].metadata)
// Proceed to create a response
} Tạo bối cảnh hệ thống và hướng dẫn cho Chatbot
Bây giờ bạn đã có được tập hợp các vectơ có mức độ liên quan cao, bạn muốn chatbot biết và tham khảo các bài viết được liên kết trước khi nó phản hồi tìm kiếm của người dùng. Để làm được điều đó với gpt-3.5-turbo của OpenAI mô hình, tạo một đối tượng tin nhắn với thuộc tính vai trò là system và thuộc tính nội dung chứa các hướng dẫn sau:
- Chatbot sẽ phản hồi giống như Google
- Chatbot phải đảm bảo rằng phản hồi ở định dạng đánh dấu
- Phản hồi của chatbot phải có siêu liên kết đến bài viết
- Chatbot không chỉ bao gồm các tài liệu tham khảo cho các bài viết
// File: app/routes/api_.train.tsx
import { OpenAIStream, StreamingTextResponse } from 'ai'
import completionServer from '~/lib/openai/completion.server'
export const action = async ({ request }: ActionFunctionArgs) => {
// ...
// Now use OpenAI Text Completion with relevant articles as context
const completionResponse = await completionServer.chat.completions.create({
stream: true,
model: 'gpt-3.5-turbo',
messages: [
{
// create a system content message to be added as
// the open ai text completion will supply it as the context with the API
role: 'system',
content: `Behave like a Google. You have the knowledge of the following articles: ${JSON.stringify(results)}. Each response should be in 100% markdown compatible format and should have hyperlinks in it. Be precise. Do add some general text in the response related to the query.`,
},
// also, pass the whole conversation!
...messages,
],
})
// Convert the response into a friendly text-stream
const stream = OpenAIStream(completionResponse)
// Respond with the stream
return new StreamingTextResponse(stream)
}
Với mã ở trên, bạn có thể truyền trực tuyến các kết quả từ OpenAI có nhận biết ngữ cảnh, đề xuất các bài viết có liên quan đến tìm kiếm của người dùng.
Đó là rất nhiều học hỏi! Bây giờ bạn đã hoàn tất ✨
Triển khai lên Fly.io
Kho lưu trữ đi kèm với thiết lập sẵn có cho Fly.io, đặc biệt liên quan đến:
- Tệp Docker
- fly.toml
- .dockerignore
Sau khi có tài khoản Fly.io, bạn có thể tạo ứng dụng trong Fly.io bằng cách thực hiện lệnh sau trong thiết bị đầu cuối của mình ở thư mục gốc:
# Create an app based on the baked-in configuration in your account
# This will result only in the change of app name in existing fly.toml
fly launch và triển khai lên Fly.io thực thi lệnh sau trong thiết bị đầu cuối của bạn:
# Deploy the app based on the configuration created above
fly deploy Tài liệu tham khảo
Để biết thêm thông tin chi tiết, hãy khám phá các tài liệu tham khảo được sử dụng trong hướng dẫn này.
- Kho lưu trữ GitHub
- Tích hợp cửa hàng Vector Upstash với LangChain
- Hướng dẫn hệ thống trong API hoàn thành trò chuyện của OpenAI
- Tải dữ liệu từ các trang web bằng Cheerio trong LangChain
- Tạo giao diện người dùng trò chuyện AI trong ứng dụng React
Kết luận
Trong hướng dẫn này, bạn đã học cách xây dựng hệ thống đề xuất bài viết bằng cách sử dụng Vector Embeddings và API hoàn thành OpenAI với ngữ cảnh hệ thống được tạo động. Với Upstash Vector và LangChain, bạn có khả năng lưu trữ vectơ trong một chỉ mục, thực hiện các truy vấn tìm kiếm vectơ top-K và tạo ngữ cảnh phù hợp cho mỗi tìm kiếm của người dùng, tất cả chỉ trong vài dòng mã.
Nếu bạn có bất kỳ câu hỏi hoặc nhận xét nào, vui lòng liên hệ với tôi trên GitHub.