Trong bài viết này, chúng tôi muốn chỉ cho bạn cách kết hợp hai công nghệ ( và ) và tạo một LangChain Anthropic trợ lý cá nhân hỗ trợ tìm kiếm. Ngày càng có nhiều sản phẩm AI được tạo ra bởi những người tham gia Cơ hội tiếp theo dành cho các nhà phát triển là cuộc thi hackathon chung của chúng tôi với , nơi mỗi người tham gia có cơ hội tạo của riêng họ bằng cách sử dụng công nghệ mới nhất từ . Ở đây chúng ta sẽ nói về một ứng dụng của AI đang ngày càng trở nên quan trọng hơn: . hackathons của chúng tôi. Google Cloud Vertex AI ứng dụng AI Google Cloud công cụ tìm kiếm Nó là gì? Trợ lý cá nhân hỗ trợ tìm kiếm là trợ lý kỹ thuật số sử dụng để giúp người dùng thực hiện các tác vụ như Những trợ lý này sử dụng các thuật toán tìm kiếm để thu thập và phân tích dữ liệu từ nhiều nguồn khác nhau, trình bày dữ liệu đó cho người dùng theo cách hữu ích và ngắn gọn. công nghệ công cụ tìm kiếm tìm thông tin, đặt chỗ, đặt lời nhắc và gửi tin nhắn. Các ví dụ nổi bật về trợ lý cá nhân hỗ trợ tìm kiếm là , , và . Những trợ lý này sử dụng hiệu quả khả năng tìm kiếm của họ để cung cấp thông tin chính xác và có liên quan, hoàn thành các nhiệm vụ và cải thiện phản hồi của họ khi họ tương tác với người dùng. Google Assistant Siri Alexa Cortana Giới thiệu Claude của Anthropic Anthropic là một tổ chức nghiên cứu tập trung vào phát triển các hệ thống AI tiên tiến. Sáng tạo mới nhất của họ, Claude, là một trợ lý AI thế hệ tiếp theo được thiết kế để trở nên hữu ích, trung thực và vô hại. Mô hình tiên tiến này đảm bảo độ tin cậy và khả năng dự đoán cao trong các nhiệm vụ khác nhau. Các tính năng chính của Claude bao gồm: Khả năng đàm thoại và xử lý văn bản linh hoạt Duy trì sự an toàn và quyền riêng tư của người dùng là ưu tiên hàng đầu của nó Các trường hợp sử dụng chính của Claude là: tóm tắt Tìm kiếm Viết sáng tạo và hợp tác hỏi đáp hỗ trợ mã hóa Những tính năng này làm cho Claude trở thành một công cụ AI lý tưởng cho nhiều ứng dụng, trao quyền cho người dùng trên các lĩnh vực khác nhau. Giới thiệu về LangChain LangChain là một công cụ linh hoạt để xây dựng các ứng dụng mô hình ngôn ngữ đầu cuối. Nó cung cấp một khung mạnh mẽ giúp đơn giản hóa quá trình tạo, quản lý và triển khai các Mô hình học ngôn ngữ (LLM). LLM là các mô hình AI tiên tiến được thiết kế để hiểu, tạo và thao tác với văn bản giống con người bằng nhiều ngôn ngữ và tác vụ khác nhau. Các tính năng chính của LangChain bao gồm: Quản lý hiệu quả lời nhắc cho LLM Khả năng tạo chuỗi nhiệm vụ cho quy trình công việc phức tạp Thêm trạng thái vào AI, cho phép nó ghi nhớ thông tin từ các tương tác trước đó Những khả năng này làm cho LangChain trở thành một nền tảng mạnh mẽ và thân thiện với người dùng để khai thác tiềm năng của các mô hình ngôn ngữ trong các ứng dụng đa dạng. điều kiện tiên quyết Kiến thức cơ bản về Python Kiến thức cơ bản về Typecipt và/hoặc React Truy cập vào API Claude của Anthropic Truy cập vào API tìm kiếm trên web của SerpApi Đề cương Khởi tạo dự án Xây dựng Front-End cho Ứng dụng trợ lý AI với Claude và LangCHain Viết tệp dự án Thử nghiệm ứng dụng trợ lý AI Cuộc thảo luận Khởi tạo dự án app.py (Điểm vào ứng dụng Flask) 🐍 : Để bắt đầu, hãy đảm bảo rằng bạn đã cài đặt Flask trong môi trường của mình. Bạn có thể làm điều này bằng cách sử dụng : Cài đặt Flask pip pip install Flask : Tạo một thư mục mới cho dự án của bạn và điều hướng đến nó: Tạo một thư mục mới mkdir claude-langchain cd claude-langchain : Sử dụng môi trường ảo khi làm việc với các dự án Python là một cách thực hành tốt. Bạn có thể tạo một cái bằng hoặc bất kỳ công cụ nào khác mà bạn chọn: Thiết lập môi trường ảo (tùy chọn) venv python -m venv venv source venv/bin/activate (Linux/Mac) venv\Scripts\activate (Windows) tệp : Tạo tệp để viết mã ứng dụng Flask của bạn: Tạo main.py main.py touch app.py # Linux/Mac echo.>app.py # Windows : Mở tệp trong trình chỉnh sửa mã yêu thích của bạn và thêm mã sau: Viết mã ứng dụng Flask của bạn main.py from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == '__main__': app.run() : Lưu tệp và chạy lệnh sau trong dấu nhắc lệnh/thiết bị đầu cuối của bạn: Chạy ứng dụng Flask main.py python main.py : Mở trình duyệt web ưa thích của bạn và điều hướng đến . Bạn sẽ thấy "Xin chào, Thế giới!" hiển thị trên trang web. Mở trình duyệt của bạn http://127.0.0.1:5000/ Và thế là xong! Bạn đã khởi tạo thành công một dự án Flask và tạo một ứng dụng đơn giản. .env 🌏 : Để dễ dàng quản lý các biến môi trường bằng tệp , chúng tôi sẽ sử dụng gói . Đồng thời, hãy cài đặt . Cài đặt cả hai gói bằng : Cài đặt python-dotenv và langchain .env python-dotenv langchain pip pip install python-dotenv langchain tệp : Tạo tệp trong thư mục gốc của dự án của bạn: Tạo .env .env touch .env # Linux/Mac echo.>.env # Windows : Mở tệp trong trình chỉnh sửa mã yêu thích của bạn và thêm biến môi trường của bạn. Mỗi biến phải nằm trên một dòng mới, ở định dạng KEY=VALUE: Thêm biến môi trường .env ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxx SERPAPI_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Xin lưu ý rằng bạn cần có cả khóa API cho mô hình và dịch vụ tìm kiếm trên web của . Claude của Anthropic SerpAPI : Sửa đổi tệp của bạn để tải các biến môi trường từ tệp bằng cách sử dụng . Cập nhật của bạn như sau: Tải các biến môi trường main.py .env python-dotenv main.py import os from flask import Flask from dotenv import load_dotenv load_dotenv() app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' if __name__ == '__main__': app.run() tệp trong kiểm soát phiên bản: Điều quan trọng là không chia sẻ thông tin nhạy cảm như khóa bí mật trong kiểm soát phiên bản. Nếu bạn đang sử dụng Git, hãy thêm dòng sau vào tệp của bạn (tạo một tệp nếu bạn không có): Bỏ qua .env .gitignore .env Bây giờ, dự án Flask của bạn được thiết lập để sử dụng các biến môi trường từ tệp . Bạn có thể thêm nhiều biến hơn nếu cần và truy cập chúng bằng cách sử dụng . Hãy nhớ giữ tệp ở chế độ riêng tư và không bao giờ chuyển nó sang kiểm soát phiên bản. .env os.environ.get('KEY') .env Xây dựng Front-End cho Ứng dụng trợ lý AI với Claude và LangChain Hướng dẫn này được thiết kế cho người dùng trung cấp có hiểu biết cơ bản về Node.js, npm, React và Typescript. Chúng tôi sẽ sử dụng một ngăn xếp bao gồm các công nghệ này, cùng với Tailwind CSS để tạo kiểu. Ngăn xếp này được chọn vì tính mạnh mẽ, tính linh hoạt và sự hỗ trợ mạnh mẽ của cộng đồng đối với các công nghệ này. Ngoài ra, chúng tôi sẽ tích hợp mô hình Claude của Anthropic và LangChain, hai công nghệ AI mạnh mẽ sẽ cho phép ứng dụng của chúng tôi tạo ra phản hồi văn bản chính xác, giống con người. Cài đặt Node.js và NPM Tải xuống trình cài đặt Node.js cho hệ điều hành của bạn từ . trang web chính thức Làm theo lời nhắc cài đặt để cài đặt Node.js và npm. Phiên bản LTS (Hỗ trợ dài hạn) được khuyến nghị cho hầu hết người dùng. Sau khi cài đặt, hãy xác minh cài đặt bằng cách kiểm tra các phiên bản của Node.js và npm từ thiết bị đầu cuối của bạn: nút -v npm -v Thiết lập môi trường dự án Cài đặt Tạo ứng dụng React là một tiện ích dòng lệnh hỗ trợ chúng ta tạo một ứng dụng React.js mới. Chúng tôi sẽ cài đặt nó trên toàn cầu thông qua npm: Create React App (CRA) npm install -g create-react-app Tạo một dự án React mới với Typescript Chúng tôi sẽ sử dụng CRA với mẫu Bản mô tả để tạo một dự án mới có tên . ai-assistant-claude npx create-react-app ai-assistant-claude --template typescript Lệnh này tạo một thư mục mới có tên trong thư mục hiện tại của chúng ta, chứa một ứng dụng React mới có hỗ trợ Typescript. ai-assistant-claude Tích hợp TailwindCSS Cài đặt TailwindCSS Các bước tiếp theo trong hướng dẫn này dựa trên . Tham khảo các tài liệu này để biết thêm hướng dẫn cập nhật. tài liệu CSS chính thức của Tailwind Chúng ta sẽ bắt đầu bằng cách cài đặt TailwindCSS và khởi tạo thư viện trong dự án của mình: npm install -D tailwindcss npx tailwindcss init Định cấu hình đường dẫn mẫu Tiếp theo, chúng tôi định cấu hình đường dẫn mẫu của mình bằng cách thêm chúng vào tệp . Dấu biểu thị các dòng bạn sẽ thêm: tailwind.config.js ++ /** @type {import('tailwindcss').Config} */ module.exports = { -- content: [], ++ content: [ ++ "./src/**/*.{js,jsx,ts,tsx}", ++ ], theme: { extend: {}, }, plugins: [], } Thêm Chỉ thị Tailwind Cuối cùng, chúng ta sẽ thêm các lệnh cho từng lớp của Tailwind vào tệp của mình: @tailwind ./src/index.css @tailwind base; @tailwind components; @tailwind utilities; Và Voila! Tailwind CSS hiện đã được tích hợp vào dự án của chúng tôi. Cài đặt thư viện cần thiết Trước khi chúng ta chuyển sang phần viết mã, hãy hoàn tất việc chuẩn bị của chúng ta bằng cách cài đặt các thư viện cần thiết như , , và . fontawesome react-markdown axios react-hook-form Cài đặt FontAwesome cho các biểu tượng npm i --save @fortawesome/fontawesome-svg-core npm install --save @fortawesome/free-solid-svg-icons npm install --save @fortawesome/react-fontawesome Cài đặt React Markdown để hiển thị nội dung Markdown npm install --save react-markdown Sau khi hoàn thành các bước này, dự án của bạn đã được thiết lập với tất cả các công cụ và thư viện cần thiết. Tiếp theo, chúng ta sẽ bắt đầu xây dựng ứng dụng trợ lý AI sử dụng Claude API và LangChain của Anthropic để tạo phản hồi văn bản chính xác và giống con người. Xử lý sự cố Nếu bạn gặp phải bất kỳ sự cố nào trong quá trình cài đặt hoặc thiết lập, đây là một vài giải pháp phổ biến: Đối với các sự cố liên quan đến Node.js hoặc npm, hãy thử cài đặt lại chúng hoặc xem tài liệu chính thức và . của Node.js npm Nếu bạn gặp sự cố với Tạo ứng dụng React, hãy tham khảo để được hỗ trợ. tài liệu CRA Đối với các sự cố CSS của Tailwind, hãy tham khảo . tài liệu CSS của Tailwind Đối với bất kỳ sự cố nào khác, hãy tham khảo tài liệu của các thư viện tương ứng hoặc đăng sự cố của bạn lên StackOverflow hoặc kho lưu trữ GitHub có liên quan. Viết tệp dự án Trong phần này, chúng ta sẽ quay lại ứng dụng Flask mà chúng ta đã khởi tạo trước đó và thêm các điểm cuối mới, chẳng hạn như và . Các tính năng này sẽ đóng vai trò là điểm cuối cho các tính năng trò chuyện nâng cao và trò chuyện đơn giản của chúng tôi (tính năng trò chuyện nâng cao được cung cấp bởi kết quả tìm kiếm của Google). /ask /search Hãy bắt đầu với việc nhập các mô-đun cần thiết của chúng tôi: from flask import Flask, jsonify, request from dotenv import load_dotenv from langchain.chat_models import ChatAnthropic from langchain.chains import ConversationChain from langchain.agents import Tool from langchain.agents import AgentType from langchain.utilities import SerpAPIWrapper from langchain.agents import initialize_agent from langchain.memory import ConversationBufferMemory from langchain.prompts.chat import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) load_dotenv() app = Flask(__name__) Phần trên nhập tất cả các gói cần thiết và khởi tạo ứng dụng Flask của chúng tôi. Phát triển phần phụ trợ Tạo các điểm cuối cơ bản Chúng tôi sẽ bắt đầu bằng cách tạo một điểm cuối cơ bản ( ) để kiểm tra xem máy chủ của chúng tôi có chạy chính xác không: / @app.route('/') def hello_world(): return 'Hello, World!' Bằng cách truy cập URL gốc, chúng tôi sẽ nhận được phản hồi "Xin chào, Thế giới!", Cho biết rằng máy chủ của chúng tôi đang chạy như mong đợi. Tạo /ask Điểm cuối Điểm cuối này xử lý tin nhắn cho tính năng trò chuyện cơ bản của ứng dụng của chúng tôi. Nó đọc dữ liệu JSON từ yêu cầu, xử lý thông báo và tạo phản hồi bằng cách sử dụng mô hình Claude và LangChain của Anthropic. @app.route('/ask', methods=['POST']) def ask_assistant(): # The code for /ask endpoint goes here Trích xuất tin nhắn từ yêu cầu Trước tiên, chúng tôi cần kiểm tra xem có dữ liệu nào được cung cấp hay không và trích xuất các thông báo từ dữ liệu đó. data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") Tạo phản hồi Đoạn mã sau tạo phản hồi trò chuyện bằng cách sử dụng mô hình của LangChain và để cấu trúc cuộc trò chuyện của chúng ta. Lịch sử hội thoại được lưu trữ bằng . ChatAnthropic() ChatPromptTemplate ConversationBufferMemory llm = ChatAnthropic() input = "" message_list = [] for message in messages: if message['role'] == 'user': message_list.append( HumanMessagePromptTemplate.from_template(message['content']) ) input = message['content'] elif message['role'] == 'assistant': message_list.append( AIMessagePromptTemplate.from_template(message['content']) ) # Adding SystemMessagePromptTemplate at the beginning of the message_list message_list.insert(0, SystemMessagePromptTemplate.from_template( "The following is a friendly conversation between a human and an AI. The AI is talkative and " "provides lots of specific details from its context. The AI will respond with plain string, replace new lines with \\n which can be easily parsed and stored into JSON, and will try to keep the responses condensed, in as few lines as possible." )) message_list.insert(1, MessagesPlaceholder(variable_name="history")) message_list.insert(-1, HumanMessagePromptTemplate.from_template("{input}")) prompt = ChatPromptTemplate.from_messages(message_list) memory = ConversationBufferMemory(return_messages=True) conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm) result = conversation.predict(input=input) Gửi phản hồi Sau khi tạo phản hồi, chúng tôi thay thế các dòng mới trong kết quả và trả về dưới dạng đối tượng JSON. print(result) return jsonify({"status": "success", "message": result}) Tạo /search Endpoint Điểm cuối tương tự như nhưng bao gồm chức năng tìm kiếm để cung cấp các câu trả lời chi tiết hơn. Chúng tôi sử dụng để thêm tính năng này. /search /ask SerpAPIWrapper @app.route('/search', methods=['POST']) def search_with_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() # Get the last message with 'user' role user_messages = [msg for msg in messages if msg['role'] == 'user'] last_user_message = user_messages[-1] if user_messages else None # If there is no user message, return an error response if not last_user_message: return jsonify({"error": "No user message found"}), 400 input = last_user_message['content'] search = SerpAPIWrapper() tools = [ Tool( name = "Current Search", func=search.run, description="useful for when you need to answer questions about current events or the current state of the world" ), ] chat_history = MessagesPlaceholder(variable_name="chat_history") memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent_chain = initialize_agent( tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True, memory=memory, agent_kwargs = { "memory_prompts": [chat_history], "input_variables": ["input", "agent_scratchpad", "chat_history"] } ) result = agent_chain.run(input=input) print(result) return jsonify({"status": "success", "message": result}) Chạy ứng dụng Flask Cuối cùng, chúng tôi thêm bản soạn sẵn tiêu chuẩn để chạy ứng dụng Flask của mình. if __name__ == '__main__': app.run() Kiểm tra phần phụ trợ Nếu mọi thứ suôn sẻ, đây là mã phụ trợ cuối cùng của chúng tôi. from flask import Flask, jsonify, request from dotenv import load_dotenv from langchain.chat_models import ChatAnthropic from langchain.chains import ConversationChain from langchain.agents import Tool from langchain.agents import AgentType from langchain.utilities import SerpAPIWrapper from langchain.agents import initialize_agent from langchain.memory import ConversationBufferMemory from langchain.prompts.chat import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, AIMessagePromptTemplate, HumanMessagePromptTemplate, ) load_dotenv() app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, World!' @app.route('/ask', methods=['POST']) def ask_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() input = "" message_list = [] for message in messages: if message['role'] == 'user': message_list.append( HumanMessagePromptTemplate.from_template(message['content']) ) input = message['content'] elif message['role'] == 'assistant': message_list.append( AIMessagePromptTemplate.from_template(message['content']) ) # Adding SystemMessagePromptTemplate at the beginning of the message_list message_list.insert(0, SystemMessagePromptTemplate.from_template( "The following is a friendly conversation between a human and an AI. The AI is talkative and " "provides lots of specific details from its context. The AI will respond with plain string, replace new lines with \\n which can be easily parsed and stored into JSON, and will try to keep the responses condensed, in as few lines as possible." )) message_list.insert(1, MessagesPlaceholder(variable_name="history")) message_list.insert(-1, HumanMessagePromptTemplate.from_template("{input}")) prompt = ChatPromptTemplate.from_messages(message_list) memory = ConversationBufferMemory(return_messages=True) conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm) result = conversation.predict(input=input) print(result) return jsonify({"status": "success", "message": result}) @app.route('/search', methods=['POST']) def search_with_assistant(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 messages = data.get("message") llm = ChatAnthropic() # Get the last message with 'user' role user_messages = [msg for msg in messages if msg['role'] == 'user'] last_user_message = user_messages[-1] if user_messages else None # If there is no user message, return an error response if not last_user_message: return jsonify({"error": "No user message found"}), 400 input = last_user_message['content'] search = SerpAPIWrapper() tools = [ Tool( name = "Current Search", func=search.run, description="useful for when you need to answer questions about current events or the current state of the world" ), ] chat_history = MessagesPlaceholder(variable_name="chat_history") memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent_chain = initialize_agent( tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True, memory=memory, agent_kwargs = { "memory_prompts": [chat_history], "input_variables": ["input", "agent_scratchpad", "chat_history"] } ) result = agent_chain.run(input=input) print(result) return jsonify({"status": "success", "message": result}) if __name__ == '__main__': app.run() Bây giờ, hãy kiểm tra ứng dụng của chúng tôi. Chạy ứng dụng phụ trợ bằng lệnh này, đồng thời vui lòng đảm bảo rằng môi trường ảo của chúng tôi đã được kích hoạt. flask run Chúng tôi sẽ biết mọi thứ sẽ ổn nếu thiết bị đầu cuối của chúng tôi trả về đầu ra này. Nếu không có gì khó chịu, hãy kiểm tra hai điểm cuối của chúng tôi và . Để phân biệt giữa hai loại này, hãy gửi tải trọng tương tự cho từng loại. Mở phần mềm tài liệu và thử nghiệm API REST của bạn hoặc chỉ sử dụng cURL. Nhưng trong hướng dẫn này, tôi sẽ sử dụng . /ask /search Insomnia Trước tiên, hãy gọi điểm cuối với tải trọng sau. Giả sử tôi đã hỏi về phần tiếp theo của trò chơi điện tử " ". Mà nó sẽ trả lời sai. Điều này có thể được mong đợi vì mô hình đã bị cắt đào tạo vào cuối năm 2021, trong đó vẫn chưa có thông báo nào về phần tiếp theo. /ask The Legend of Zelda: Breath of the Wild Còn điểm cuối thì sao? Nếu bạn nhận thấy mã của chúng tôi từ trước đó, thì điểm cuối này được xử lý bằng một chuỗi phức tạp hơn, sử dụng Tác nhân. /search Bằng cách sử dụng Tác nhân, chúng tôi có thể trao cho AI nhiều quyền hơn trong việc ra quyết định, bằng cách cung cấp cho nó nhiều công cụ hơn là chỉ mô hình của chính nó, như chúng tôi đã chứng minh, có những sai sót riêng. Để minh họa cách thức hoạt động của endpoint, hãy gọi nó với cùng tải trọng như trước đây. /search Lần này, nó hoạt động tốt! Làm thế nào để nó hoạt động dưới mui xe? hãy nhìn vào đầu ra trong thiết bị đầu cuối của chúng tôi. Khá thú vị, lần này mô hình AI không trả lời ngay mà dường như đang “suy ngẫm” về những việc cần làm để trả lời. Nó quyết định trả lời sau khi đưa ra quan sát từ kết quả tìm kiếm trên web rằng "Dựa trên tìm kiếm tin tức, có vẻ như phần tiếp theo có tên The Legend of Zelda: Tears of the Kingdom đã được công bố". Vì vậy, theo logic đó, chúng ta có nên sử dụng điểm cuối không? vì nó chính xác hơn, và do đó, thông minh hơn? Không hẳn. Thông thường, trong ứng dụng dựa trên chatbot, bot phải giữ lại ngữ cảnh của các cuộc trò chuyện trước đó để có thể đưa ra phản hồi như thể nó 'nhớ' toàn bộ ngữ cảnh của cuộc trò chuyện. Hãy xem liệu endpoint có thể làm được điều đó không. /search /search Hãy kiểm tra xem điểm cuối có thể nhớ lại những gì chúng ta vừa hỏi không. /search Điều này xảy ra bởi vì mặc dù thư viện LangChain có tính năng chuỗi bộ nhớ có thể được sử dụng để lưu giữ các cuộc hội thoại trước đây, máy chủ web và dịch vụ API REST được xây dựng trên nó vốn không có trạng thái. Điều đó có nghĩa là, máy chủ web sẽ coi mỗi yêu cầu là một yêu cầu mới. Nhưng, chẳng phải chúng ta đã bao gồm các cuộc trò chuyện trước đó dưới dạng tải trọng sao? Đó là một câu hỏi hay. Hóa ra, chuỗi Đại lý được sử dụng trong LangChain hiện không hỗ trợ xử lý các lời nhắc tổng hợp, bao gồm cả yêu cầu và phản hồi của cả người dùng và AI. Chúng tôi chủ yếu sử dụng điều này để cung cấp các cuộc hội thoại ví dụ cho mô hình, tiếp tục điều chỉnh mô hình theo phản hồi mong muốn của chúng tôi. Mặt khác, Tác nhân hoạt động bằng cách nhận một hướng dẫn duy nhất và phát triển các chuỗi suy nghĩ xung quanh nó. Đó là lý do tại sao, bất kể cuộc trò chuyện của chúng tôi kéo dài bao lâu, đại lý sẽ chỉ trả lời yêu cầu mới nhất. Hãy kiểm tra điểm cuối của chúng tôi để nhận thấy sự khác biệt. /ask Lần này, nó đã trả lời bằng cách sử dụng các cuộc trò chuyện trước đây của chúng tôi dưới dạng ngữ cảnh bổ sung! Đến bây giờ, chúng tôi nhận ra rằng chúng tôi cần cả hai điểm cuối để xây dựng ứng dụng Trợ lý AI của mình. Nhưng làm thế nào để chúng ta kết hợp cả điểm cuối lỗi thời nhưng luôn ghi nhớ với điểm cuối hay quên nhưng kỹ lưỡng và cập nhật ? Tất nhiên là bằng cách xây dựng giao diện người dùng! /ask /search Phát triển Frontend Ứng dụng.tsx Hãy quay trở lại thư mục dự án . Trong dự án này, chúng tôi sẽ bắt đầu sửa đổi các thành phần React của mình, bắt đầu với tệp điểm đầu vào, . ai-assistant-claude App.tsx import React from 'react'; import logo from './logo.svg'; import './App.css'; import { ChatClient } from './ChatClient'; function App() { return ( <div> <ChatClient/> </div> ); } export default App; Trong đoạn mã trên, chúng tôi nhập thành phần , thành phần này sẽ được tạo trong bước tiếp theo. Sau đó, chúng tôi đưa thành phần vào trong thành phần . Điều này thiết lập cấu trúc cho ứng dụng trợ lý AI của chúng tôi bằng cách sử dụng các thành phần React. ChatClient <ChatClient/> <div> ChatClient.tsx import React, { useState } from 'react'; import { ChatInput } from './ChatInput'; import { ChatHistory } from './ChatHistory'; export interface Message { content: string; role: string; } export const ChatClient: React.FC = () => { const [messages, setMessages] = useState<Array<Message>>([]); const [isLoading, setIsLoading] = useState(false) const handleSimpleChat = (message: string) => { // Send the message and past chat history to the backend // Update messages state with the new message let newMessages = [...messages, { content: message, role: 'user' }] setMessages(newMessages); let postData = { message: newMessages } setIsLoading(true) fetch('/ask', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }) .then((response) => response.json()) .then((data) => { if (data.status === "success") { setMessages([...newMessages, { content: data.message, role: 'assistant' }]) } setIsLoading(false) console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); setIsLoading(false) }); }; const handleAdvancedChat = (message: string) => { // Trigger AI agent with Google Search functionality // Update messages state with the new message and AI response let newMessages = [...messages, { content: message, role: 'user' }] setMessages(newMessages); let postData = { message: newMessages } setIsLoading(true) fetch('/search', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(postData), }) .then((response) => response.json()) .then((data) => { if (data.status === "success") { setMessages([...newMessages, { content: data.message, role: 'assistant' }]) } console.log('Success:', data); setIsLoading(false) }) .catch((error) => { console.error('Error:', error); setIsLoading(false) }); }; return ( <div className="h-screen bg-gray-100 dark:bg-gray-900 flex items-center justify-center"> <div className='flex flex-col items-center gap-2'> <h1 className='text-white text-xl'>AI Assistant with Claude and LangChain</h1> <div className="w-full max-w-md h-[80vh] bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden flex flex-col"> <ChatHistory messages={messages} isLoading={isLoading} /> <ChatInput onSimpleChat={handleSimpleChat} onAdvancedChat={handleAdvancedChat} /> </div> </div> </div> ); }; Thành phần này đóng vai trò là giao diện người dùng chính cho trợ lý AI của chúng tôi. Như được hiển thị, nó kết hợp thành phần để hiển thị lịch sử hội thoại và thành phần để nhập văn bản. ChatHistory ChatInput Thành phần xử lý đầu vào từ thành phần , gửi yêu cầu đến phần phụ trợ bằng đầu vào này, sau đó hiển thị trạng thái tải. Nếu yêu cầu được xử lý thành công, thành phần này cũng sẽ hiển thị phản hồi nhận được từ phần phụ trợ. ChatInput ChatHistory.tsx import React from 'react'; import { ReactMarkdown } from 'react-markdown/lib/react-markdown'; import { Message } from './ChatClient'; interface ChatHistoryProps { messages: Array<Message>; isLoading: boolean } export const ChatHistory: React.FC<ChatHistoryProps> = ({ messages, isLoading }) => { return ( <div className="p-4 h-full overflow-y-auto"> {messages.map((message, index) => ( <div key={index} className={`mb-3 ${ message.role === 'user' ? 'text-right' : 'text-left' }`} > <ReactMarkdown className={`inline-block px-3 py-2 rounded-md ${ index % 2 === 0 ? 'bg-gray-300 dark:bg-gray-700' : 'bg-blue-200 dark:bg-blue-900' }`} > {message.content} </ReactMarkdown> </div> ))} {isLoading && ( <div className="mb-3 text-left"> <ReactMarkdown className="inline-block px-3 py-2 rounded-md bg-blue-200 dark:bg-blue-900 animate-pulse" > {/* Put your desired loading content here */} Thinking... </ReactMarkdown> </div> )} </div> ); }; May mắn thay, TailwindCSS cung cấp các lớp tiện ích tích hợp sẵn cho hoạt ảnh đơn giản, chẳng hạn như . Lớp này giúp chỉ ra rằng một yêu cầu đang chờ phản hồi. Trong thành phần này, chúng tôi cũng phân biệt vị trí của thông báo từ "người dùng" và "trợ lý". animate-pulse Trò chuyệnInput.tsx import React, { useState } from 'react'; interface ChatInputProps { onSimpleChat: (message: string) => void; onAdvancedChat: (message: string) => void; } export const ChatInput: React.FC<ChatInputProps> = ({ onSimpleChat, onAdvancedChat }) => { const [input, setInput] = useState(''); const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { setInput(event.target.value); }; const handleSubmit = (handler: (message: string) => void) => { handler(input); setInput(''); }; return ( <div className="flex p-4 border-t border-gray-200 dark:border-gray-700"> <input type="text" value={input} onChange={handleInputChange} placeholder="Type your message..." className="flex-grow px-3 py-2 rounded-md bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100 focus:outline-none" /> <button onClick={() => handleSubmit(onSimpleChat)} className="ml-2 px-4 py-2 font-semibold text-gray-600 bg-white dark:text-gray-400 dark:bg-gray-800 border border-gray-300 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none" > Ask </button> <button onClick={() => handleSubmit(onAdvancedChat)} className="ml-2 px-4 py-2 font-semibold text-white bg-blue-500 border border-blue-600 rounded-md hover:bg-blue-400 focus:outline-none" > Ask and Search </button> </div> ); }; Cuối cùng, chúng tôi đã thêm hai nút vào kiểu nhập văn bản của mình. Nút đầu tiên được sử dụng để gửi dữ liệu đầu vào đến điểm cuối , điểm cuối này sẽ xử lý dữ liệu đầu vào bằng mô hình AI mà không cần bất kỳ cải tiến bổ sung nào. /ask Điểm cuối này nhận biết ngữ cảnh. Nút thứ hai, được đặt tên một cách khéo léo là "Hỏi và Tìm kiếm", sẽ gửi thông tin đầu vào đến điểm cuối . Ngoài việc xử lý đầu vào thông qua mô hình AI, nút này cũng kích hoạt tìm kiếm trên web do AI điều khiển nếu tình huống yêu cầu. /search index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <!-- manifest.json provides metadata used when your web app is installed on a user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> -- <title>React App</title> ++ <title>Claude AI Assistant</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> </body> </html> Để hoàn thiện, chúng tôi cập nhật tiêu đề của ứng dụng trong trang bằng cách thay đổi nó từ " " thành " ". index.html React App Claude AI Assistant gói.json { "name": "ai-assistant-claude", "version": "0.1.0", "private": true, ++ "proxy": "http://localhost:5000", "dependencies": { Cuối cùng, chúng tôi thêm cấu hình proxy vào tệp và đặt thành . Điều này giúp chúng tôi bỏ qua các giới hạn CORS phát sinh từ việc sử dụng các cổng khác nhau. package.json http://localhost:5000 Thử nghiệm ứng dụng trợ lý AI Để bắt đầu thử nghiệm, trước tiên hãy đảm bảo rằng ứng dụng phụ trợ (claude-langchain) đang chạy. Tiếp theo, thay đổi thư mục thành ứng dụng giao diện người dùng (ai-assistant-claude) và khởi động ứng dụng bằng lệnh sau: npm start Ứng dụng có thể mất một chút thời gian để xây dựng. Khi đã sẵn sàng, nó sẽ tự động mở trong trình duyệt của bạn tại . localhost:3000 Hãy kiểm tra cả tính năng tìm kiếm và nhận biết ngữ cảnh! Trước tiên, hãy hỏi về một trò chơi điện tử khác vẫn chưa được công bố phát hành vào năm 2021 – phần tiếp theo của trò chơi Yakuza mới nhất của . Ngoài ra, chúng tôi sẽ hỏi liệu trò chơi này có nhân vật được yêu thích Kazuma Kiryu từ các trò chơi trước hay không. Để thực hiện việc này, hãy nhấp vào nút " ". SEGA Hỏi Cho vài giây suy nghĩ... Đáng ngạc nhiên, AI đã trả lời sai. Yakuza: Like a Dragon thực sự là trò chơi Yakuza mới nhất nhưng có sự tham gia của một nhân vật chính khác, Ichiban Kasuga. Hãy diễn đạt lại câu hỏi và sử dụng nút " " lần này. Hỏi và Tìm kiếm Giờ đây, AI mất nhiều thời gian hơn để quyết định xem nó có cần tìm kiếm trên web hay không. Sau khi xác định rằng tìm kiếm trên web là cần thiết và tìm thấy câu trả lời thỏa đáng, nó sẽ trả lại thông tin cho khách hàng/giao diện người dùng. Lần này, nó trả lại tiêu đề "Like a Dragon Gaiden: The Man Who Erased His Name", trong đó thực sự có Kazuma Kiryu là nhân vật chính. Hấp dẫn, phải không? Tác nhân, được cung cấp bởi Mô hình ngôn ngữ lớn, dự đoán những hành động nào là cần thiết với các tài nguyên có sẵn (tìm kiếm) và đưa ra câu trả lời thỏa đáng. LangChain giúp dễ dàng kết nối và "xâu chuỗi" mô hình, lời nhắc (hướng dẫn về mô hình) và các tính năng khác như tác nhân và công cụ. Phần kết luận Chúng tôi hy vọng bạn thích xây dựng ứng dụng này và tìm hiểu về những công nghệ này. Đối với những người muốn tìm hiểu sâu hơn, bạn có thể truy cập dự án đã hoàn thành cho và . phần đầu phần phụ trợ Và nếu bạn muốn xây dựng bằng những công nghệ mới nhất do các đối tác của chúng tôi hiện thực hóa, hãy tham gia cùng chúng tôi trong thử thách AI tiếp theo! *please see lablab.ai for all terms and conditions