AI 智能体或智能 AI 系统在 2024 年有了显著的发展,它使我们能够构建能够推理、分析、交互并自动采取行动的生成式 AI 系统。智能 AI 的核心思想是构建完全自主的系统,能够在最少的人工干预下理解和管理复杂的工作流程和任务。智能系统可以掌握细微的概念,设定并追求目标,通过任务进行推理,并根据不断变化的条件调整其行动。这些系统可以由单个智能体或多个智能体组成。
我们可以使用各种框架来构建智能 AI 系统,包括 CrewAI、LangChain、LangGraph、AutoGen 等等。使用这些框架可以让我们轻松开发复杂的工作流程。需要记住的是,智能体基本上是一个或多个大语言模型,它们可以访问一组工具,并根据特定的基于提示的指令来回答用户问题。
我们从 Wikipedia 中选取一部分文档来构建用于检索和搜索的向量数据库。我们已经从 Wikipedia 中提取了这些文档并将它们存储在一个存档文件中。
Open AI 嵌入模型:LangChain 使我们能够访问 Open AI 嵌入模型,包括最新的模型:一个较小且高效的 text-embedding-3-small 模型和一个更大且功能更强大的 text-embedding-3-large 模型。我们需要一个嵌入模型,以便在将文档块存储到向量数据库之前将其转换为嵌入向量。
fromlangchain_core.promptsimportChatPromptTemplate fromlangchain_core.pydantic_v1importBaseModel, Field fromlangchain_openaiimportChatOpenAI
classGradeDocuments(BaseModel): """Binary score for relevance check on retrieved documents.""" binary_score: str = Field( description="Documents are relevant to the question, 'yes' or 'no'" )
SYS_PROMPT ="""You are an expert grader assessing relevance of a retrieved document to a user question. Follow these instructions for grading: - If the document contains keyword(s) or semantic meaning related to the question, grade it as relevant. - Your grade should be either 'yes' or 'no' to indicate whether the document is relevant to the question or not."""
prompt ="""You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If no context is present or if you don't know the answer, just say that you don't know the answer. Do not make up the answer unless it is there in the provided context. Give a detailed answer and to the point answer with regard to the question. Question: {question} Context: {context} Answer: """ prompt_template = ChatPromptTemplate.from_template(prompt)
SYS_PROMPT ="""Act as a question re-writer and perform the following task: - Convert the following input question to a better version that is optimized for web search. - When re-writing, look at the input question and try to reason about the underlying semantic intent / meaning. """ re_write_prompt = ChatPromptTemplate.from_messages( [ ("system", SYS_PROMPT), ("human","""Here is the initial question: {question} Formulate an improved question. """, ), ] )
classGraphState(TypedDict): """ Represents the state of our graph. Attributes: question: question generation: LLM response generation web_search_needed: flag of whether to add web search - yes or no documents: list of context documents """ question: str generation: str web_search_needed: str documents: List[str]
从向量数据库检索的函数(Retrieve function for retrieval from Vector DB):这个函数用于通过我们之前构建的检索器从向量数据库中获取相关的上下文文档。记住,由于它将成为智能体图中的一个节点,之后我们将从图状态中获取用户问题,然后将其传递给检索器,以从向量数据库中获取相关的上下文文档。
defretrieve(state): """ Retrieve documents Args: state (dict): The current graph state Returns: state (dict): New key added to state, documents - that contains retrieved context documents """ print("---RETRIEVAL FROM VECTOR DB---") question = state["question"] # Retrieval documents = similarity_threshold_retriever.invoke(question) return{"documents": documents,"question": question}
defgrade_documents(state): """ Determines whether the retrieved documents are relevant to the question by using an LLM Grader. If any document are not relevant to question or documents are empty - Web Search needs to be done If all documents are relevant to question - Web Search is not needed Helps filtering out irrelevant documents Args: state (dict): The current graph state Returns: state (dict): Updates documents key with only filtered relevant documents """ print("---CHECK DOCUMENT RELEVANCE TO QUESTION---") question = state["question"] documents = state["documents"] # Score each doc filtered_docs = [] web_search_needed ="No" ifdocuments: fordindocuments: score = doc_grader.invoke( {"question": question,"document": d.page_content} ) grade = score.binary_score ifgrade =="yes": print("---GRADE: DOCUMENT RELEVANT---") filtered_docs.append(d) else: print("---GRADE: DOCUMENT NOT RELEVANT---") web_search_needed ="Yes" continue else: print("---NO DOCUMENTS RETRIEVED---") web_search_needed ="Yes" return{"documents": filtered_docs,"question": question, "web_search_needed": web_search_needed}
defrewrite_query(state): """ Rewrite the query to produce a better question. Args: state (dict): The current graph state Returns: state (dict): Updates question key with a re-phrased or re-written question """ print("---REWRITE QUERY---") question = state["question"] documents = state["documents"] # Re-write question better_question = question_rewriter.invoke({"question": question}) return{"documents": documents,"question": better_question}
网络搜索(Web Search):这个函数用于使用网络搜索工具针对给定的查询在网络上进行搜索,并从网络中检索一些信息,这些信息可以在我们的 RAG 系统中用作额外的上下文文档。正如前面所讨论的,我们将在系统中使用 Tavily Search API 工具。这个函数还会更新状态图,特别是上下文文档列表,添加从网络上为重新表述的用户查询检索到的新文档。
fromlangchain.schemaimportDocument
defweb_search(state): """ Web search based on the re-written question. Args: state (dict): The current graph state Returns: state (dict): Updates documents key with appended web results """ print("---WEB SEARCH---") question = state["question"] documents = state["documents"] # Web search docs = tv_search.invoke(question) web_results ="\n\n".join([d["content"]fordindocs]) web_results = Document(page_content=web_results) documents.append(web_results) return{"documents": documents,"question": question}
defgenerate_answer(state): """ Generate answer from context document using LLM Args: state (dict): The current graph state Returns: state (dict): New key added to state, generation, that contains LLM generation """ print("---GENERATE ANSWER---") question = state["question"] documents = state["documents"] # RAG generation generation = qa_rag_chain.invoke({"context": documents,"question": question}) return{"documents": documents,"question": question, "generation": generation}
决定生成(Decide to Generate):这个函数用作条件函数,从智能体图状态中检查web_search_needed标志,并决定是进行网络搜索还是生成响应。它将返回要调用的函数名称。如果需要进行网络搜索,系统将返回rewrite_query字符串,促使我们的智能 RAG 系统遵循查询重写、搜索和响应生成的流程。如果不需要进行网络搜索,该函数将返回generate_answer字符串,使我们的 RAG 系统进入从给定上下文文档和查询生成响应的常规流程。你将在我们智能体图的条件节点中使用这个函数,根据两种可能的路径将流程路由到正确的函数。
defdecide_to_generate(state): """ Determines whether to generate an answer, or re-generate a question. Args: state (dict): The current graph state Returns: str: Binary decision for next node to call """ print("---ASSESS GRADED DOCUMENTS---") web_search_needed = state["web_search_needed"] ifweb_search_needed =="Yes": # All documents have been filtered check_relevance # We will re-generate a new query print("---DECISION: SOME or ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, REWRITE QUERY---") return"rewrite_query" else: # We have relevant documents, so generate answer print("---DECISION: GENERATE RESPONSE---") return"generate_answer"
query ="what is the capital of India?" response = agentic_rag.invoke({"question": query})
输出如下:
---RETRIEVAL FROM VECTOR DB--- ---CHECK DOCUMENT RELEVANCE TO QUESTION--- ---GRADE: DOCUMENT RELEVANT--- ---GRADE: DOCUMENT NOT RELEVANT--- ---GRADE: DOCUMENT NOT RELEVANT--- ---ASSESS GRADED DOCUMENTS--- ---DECISION: SOME or ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, REWRITE QUERY--- ---REWRITE QUERY--- ---WEB SEARCH--- ---GENERATE ANSWER—
The capital city of India is New Delhi. It is a union territory within the larger metropolitan area of Delhi and is situatedinthe north-central part of the country on the west bank of the Yamuna River. New Delhi was formally dedicated as the capitalin1931 and has a population of about 9.4 million people.
场景二:查询 2024 年欧冠冠军
query ="who won the champions league in 2024?" response = agentic_rag.invoke({"question": query})
输出:
---RETRIEVAL FROM VECTOR DB--- ---CHECK DOCUMENT RELEVANCE TO QUESTION--- ---GRADE: DOCUMENT NOT RELEVANT--- ---ASSESS GRADED DOCUMENTS--- ---DECISION: SOME or ALL DOCUMENTS ARE NOT RELEVANT TO QUESTION, REWRITE QUERY--- ---REWRITE QUERY--- ---WEB SEARCH--- ---GENERATE ANSWER---
The winner of the 2024 UEFA Champions League was Real Madrid. They secured victoryinthe final against Borussia Dortmund with goals from Dani Carvajal and Vinicius Junior.
场景三:查询关于印度的信息
query ="Tell me about India" response = agentic_rag.invoke({"question": query})
India is a country locatedinAsia, specifically at the center of South Asia. It is the seventh largest countryinthe world by area and the largestin South Asia. . . . . . .
India has a rich and diversehistorythat spans thousands of years, encompassing various languages, cultures, periods, and dynasties. The civilization beganinthe Indus Valley, . . . . . .
如果你想深入学习如何构建这样的智能 AI 系统,可以参加 GenAI Pinnacle Program。在这里,你将通过与生成式 AI 专家的一对一指导、超过 200 小时的强化学习的高级课程以及对 26 多种 GenAI 工具和库的掌握,彻底革新你的 AI 学习和开发之旅。提升你的技能,成为 AI 领域的领导者。
希望本文能为你在 RAG 系统和 AI 智能体的探索中提供有价值的参考,让我们一起期待在人工智能领域不断创新和突破,构建更智能、更高效的系统,为各个行业带来变革性的影响 。无论是企业应用场景,还是学术研究方向,对这些技术的深入理解和应用都将为我们打开新的大门,创造更多可能。