diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5e394b6ca..9e794dbc1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,7 +6,6 @@ /comps/guardrails/ liang1.lv@intel.com /comps/asr/ sihan.chen@intel.com /comps/intent_detection/ liang1.lv@intel.com -/comps/knowledgegraphs/ xuhui.ren@intel.com /comps/cores/ liang1.lv@intel.com /comps/dataprep/ xinyu.ye@intel.com /comps/embeddings/ xuhui.ren@intel.com diff --git a/.github/workflows/docker/compose/knowledgegraphs-compose-cd.yaml b/.github/workflows/docker/compose/knowledgegraphs-compose-cd.yaml deleted file mode 100644 index bfd47fda0..000000000 --- a/.github/workflows/docker/compose/knowledgegraphs-compose-cd.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -# this file should be run in the root of the repo -services: - knowledge_graphs: - build: - dockerfile: comps/knowledgegraphs/langchain/Dockerfile - image: ${REGISTRY:-opea}/knowledge_graphs:${TAG:-latest} diff --git a/.github/workflows/manual-docker-publish.yml b/.github/workflows/manual-docker-publish.yml index 748cae8e9..19024b6c5 100644 --- a/.github/workflows/manual-docker-publish.yml +++ b/.github/workflows/manual-docker-publish.yml @@ -7,7 +7,7 @@ on: inputs: services: default: "" - description: "List of services to test [agent,asr,chathistory,dataprep,embeddings,guardrails,knowledgegraphs,llms,lvms,nginx,prompt_registry,ragas,reranks,retrievers,tts,vectorstores,web_retrievers]" + description: "List of services to test [agent,asr,chathistory,dataprep,embeddings,guardrails,llms,lvms,nginx,prompt_registry,ragas,reranks,retrievers,tts,vectorstores,web_retrievers]" required: false type: string images: diff --git a/.github/workflows/manual-docker-scan.yml b/.github/workflows/manual-docker-scan.yml index c10999645..9a9f4ce9d 100644 --- a/.github/workflows/manual-docker-scan.yml +++ b/.github/workflows/manual-docker-scan.yml @@ -7,7 +7,7 @@ on: inputs: services: default: "asr" - description: "List of services to test [agent_langchain,asr,chathistory_mongo,dataprep_milvus...]" #,embeddings,guardrails,knowledgegraphs,llms,lvms,prompt_registry,ragas,reranks,retrievers,tts,vectorstores,web_retrievers]" + description: "List of services to test [agent_langchain,asr,chathistory_mongo,dataprep_milvus...]" #,embeddings,guardrails,llms,lvms,prompt_registry,ragas,reranks,retrievers,tts,vectorstores,web_retrievers]" required: false type: string images: diff --git a/comps/knowledgegraphs/langchain/Dockerfile b/comps/knowledgegraphs/langchain/Dockerfile deleted file mode 100644 index 9a6a85d00..000000000 --- a/comps/knowledgegraphs/langchain/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -FROM python:3.11-slim - -ARG ARCH="cpu" # Set this to "cpu" or "gpu" - -RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \ - libgl1-mesa-glx \ - libjemalloc-dev - -RUN useradd -m -s /bin/bash user && \ - mkdir -p /home/user && \ - chown -R user /home/user/ - -COPY comps /home/user/comps - -USER user - -RUN pip install --no-cache-dir --upgrade pip && \ -if [ ${ARCH} = "cpu" ]; then \ - pip install --no-cache-dir --extra-index-url https://download.pytorch.org/whl/cpu -r /home/user/comps/knowledgegraphs/langchain/requirements.txt; \ - else \ - pip install --no-cache-dir -r /home/user/comps/knowledgegraphs/langchain/requirements.txt; \ - fi - -ENV PYTHONPATH=$PYTHONPATH:/home/user - -WORKDIR /home/user/comps/knowledgegraphs/langchain - -ENTRYPOINT ["python", "knowledge_graph.py"] diff --git a/comps/knowledgegraphs/langchain/README.md b/comps/knowledgegraphs/langchain/README.md deleted file mode 100644 index a56dc0308..000000000 --- a/comps/knowledgegraphs/langchain/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# Knowledge Graph Microservice - -This microservice, designed for efficiently handling and retrieving informantion from knowledge graph. The microservice integrates text retriever, knowledge graph quick search and LLM agent, which can be combined to enhance question answering. - -The service contains three modes: - -- "cypher": Query knowledge graph directly with cypher -- "rag": Apply similarity search on embeddings of knowledge graph -- "query": An LLM agent will automatically choose tools (RAG or CypherChain) to enhance the question answering - -Here is the overall workflow: - -![Workflow](doc/workflow.png) - -A prerequisite for using this microservice is that users must have a knowledge gragh database already running, and currently we have support [Neo4J](https://neo4j.com/) for quick deployment. Users need to set the graph service's endpoint into an environment variable and microservie utilizes it for data injestion and retrieve. If user want to use "rag" and "query" mode, still need a LLM text generation service (etc., TGI, vLLM and Ray) already running. - -Overall, this microservice provides efficient support for applications related with graph dataset, especially for answering multi-part questions, or any other conditions including comples relationship between entities. - -## 🚀1. Start Microservice with Docker - -### 1.1 Setup Environment Variables - -```bash -export NEO4J_ENDPOINT="neo4j://${your_ip}:7687" -export NEO4J_USERNAME="neo4j" -export NEO4J_PASSWORD=${define_a_password} -export HUGGINGFACEHUB_API_TOKEN=${your_huggingface_api_token} -export LLM_ENDPOINT="http://${your_ip}:8080" -export LLM_MODEL="meta-llama/Llama-2-7b-hf" -export AGENT_LLM="HuggingFaceH4/zephyr-7b-beta" -``` - -### 1.2 Start Neo4j Service - -```bash -docker pull neo4j - -docker run --rm \ - --publish=7474:7474 --publish=7687:7687 \ - --env NEO4J_AUTH=$NEO4J_USER/$NEO4J_PASSWORD \ - --volume=$PWD/neo4j_data:"/data" \ - --env='NEO4JLABS_PLUGINS=["apoc"]' \ - neo4j -``` - -### 1.3 Start LLM Service for "rag"/"query" mode - -You can start any LLM microserve, here we take TGI as an example. - -```bash -docker run -p 8080:80 \ - -v $PWD/llm_data:/data --runtime=habana \ - -e HABANA_VISIBLE_DEVICES=all \ - -e OMPI_MCA_btl_vader_single_copy_mechanism=none \ - -e HUGGING_FACE_HUB_TOKEN=$HUGGINGFACEHUB_API_TOKEN \ - --cap-add=sys_nice \ - --ipc=host \ - ghcr.io/huggingface/tgi-gaudi:2.0.0 \ - --model-id $LLM_MODEL \ - --max-input-tokens 1024 \ - --max-total-tokens 2048 -``` - -Verify LLM service. - -```bash -curl $LLM_ENDPOINT/generate \ - -X POST \ - -d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":32}}' \ - -H 'Content-Type: application/json' -``` - -### 1.4 Start Microservice - -```bash -cd ../../../ -docker build -t opea/knowledge_graphs:latest \ - --build-arg https_proxy=$https_proxy \ - --build-arg http_proxy=$http_proxy \ - -f comps/knowledgegraphs/langchain/Dockerfile . - -docker run --rm \ - --name="knowledge-graph-server" \ - -p 8060:8060 \ - --ipc=host \ - -e http_proxy=$http_proxy \ - -e https_proxy=$https_proxy \ - -e NEO4J_ENDPOINT=$NEO4J_ENDPOINT \ - -e NEO4J_USERNAME=$NEO4J_USERNAME \ - -e NEO4J_PASSWORD=$NEO4J_PASSWORD \ - -e HUGGINGFACEHUB_API_TOKEN=$HUGGINGFACEHUB_API_TOKEN \ - -e LLM_ENDPOINT=$LLM_ENDPOINT \ - opea/knowledge_graphs:latest -``` - -## 🚀2. Consume Knowledge Graph Service - -### 2.1 Cypher mode - -```bash -curl http://${your_ip}:8060/v1/graphs \ - -X POST \ - -d "{\"text\":\"MATCH (t:Task {status:'open'}) RETURN count(*)\",\"strtype\":\"cypher\"}" \ - -H 'Content-Type: application/json' -``` - -Example output: -![Cypher Output](doc/output_cypher.png) - -### 2.2 Rag mode - -```bash -curl http://${your_ip}:8060/v1/graphs \ - -X POST \ - -d "{\"text\":\"How many open tickets there are?\",\"strtype\":\"rag\", \"max_new_tokens\":128}" \ - -H 'Content-Type: application/json' -``` - -Example output: -![Cypher Output](doc/output_rag.png) - -### 2.3 Query mode - -First example: - -```bash -curl http://${your_ip}:8060/v1/graphs \ - -X POST \ - -d "{\"text\":\"Which tasks have optimization in their description?\",\"strtype\":\"query\"}" \ - -H 'Content-Type: application/json' -``` - -Example output: -![Cypher Output](doc/output_query1.png) - -Second example: - -```bash -curl http://${your_ip}:8060/v1/graphs \ - -X POST \ - -d "{\"text\":\"Which team is assigned to maintain PaymentService?\",\"strtype\":\"query\"}" \ - -H 'Content-Type: application/json' -``` - -Example output: -![Cypher Output](doc/output_query2.png) diff --git a/comps/knowledgegraphs/langchain/__init__.py b/comps/knowledgegraphs/langchain/__init__.py deleted file mode 100755 index 916f3a44b..000000000 --- a/comps/knowledgegraphs/langchain/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 diff --git a/comps/knowledgegraphs/langchain/build_docker.sh b/comps/knowledgegraphs/langchain/build_docker.sh deleted file mode 100644 index 8cd45ce62..000000000 --- a/comps/knowledgegraphs/langchain/build_docker.sh +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -docker build -t opea/knowledge_graphs:latest \ - --build-arg https_proxy=$https_proxy \ - --build-arg http_proxy=$http_proxy \ - -f comps/knowledgegraphs/langchain/docker/Dockerfile . diff --git a/comps/knowledgegraphs/langchain/data/microservices.json b/comps/knowledgegraphs/langchain/data/microservices.json deleted file mode 100644 index 7a042b073..000000000 --- a/comps/knowledgegraphs/langchain/data/microservices.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "query": "MERGE (catalog:Microservice {name: 'CatalogService', technology: 'Java'}) MERGE (order:Microservice {name: 'OrderService', technology: 'Python'}) MERGE (user:Microservice {name: 'UserService', technology: 'Go'}) MERGE (payment:Microservice {name: 'PaymentService', technology: 'Node.js'}) MERGE (inventory:Microservice {name: 'InventoryService', technology: 'Java'}) MERGE (shipping:Microservice {name: 'ShippingService', technology: 'Python'}) MERGE (review:Microservice {name: 'ReviewService', technology: 'Go'}) MERGE (recommendation:Microservice {name: 'RecommendationService', technology: 'Node.js'}) MERGE (auth:Microservice {name: 'AuthService', technology: 'Node.js'}) MERGE (db:Microservice {name: 'Database', technology: 'SQL'}) MERGE (cache:Microservice {name: 'Cache', technology: 'In-memory'}) MERGE (mq:Microservice {name: 'MessageQueue', technology: 'Pub-Sub'}) MERGE (api:Microservice {name: 'ExternalAPI', technology: 'REST'}) MERGE (bugFixCatalog:Task {name: 'BugFix', description: 'Address and resolve a critical bug impacting the CatalogService, affecting the user interface and experience, and hampering the overall performance and responsiveness of the service.', status: 'open'}) MERGE (featureAddOrder:Task {name: 'FeatureAdd', description: 'Implement a new feature in OrderService to facilitate bulk orders, ensuring the features seamless integration with existing functionalities and maintaining the overall stability and performance of the service.', status: 'in progress'}) MERGE (refactorUser:Task {name: 'Refactor', description: 'Refactor the UserService codebase to enhance its readability, maintainability, and scalability, focusing primarily on modularization and optimization of existing functionalities.', status: 'completed'}) MERGE (optimizePayment:Task {name: 'Optimize', description: 'Optimize PaymentService by refining the transaction processing logic, reducing the service’s latency, and improving its reliability and efficiency in handling transactions.', status: 'open'}) MERGE (updateInventory:Task {name: 'Update', description: 'Update InventoryService to include real-time stock updates, ensuring accurate reflection of the inventory levels and aiding in the efficient management of stock.', status: 'in progress'}) MERGE (enhanceShipping:Task {name: 'Enhance', description: 'Enhance the ShippingService by integrating a new shipping partner API, thereby expanding the shipping options available to the customers and improving the overall delivery experience.', status: 'completed'}) MERGE (reviewFix:Task {name: 'ReviewFix', description: 'Rectify a recurring issue in ReviewService affecting the retrieval of user reviews, by refining the service’s logic and improving its efficiency in handling and displaying user reviews.', status: 'open'}) MERGE (recommendationFeature:Task {name: 'RecommendationFeature', description: 'Add a new feature to RecommendationService to provide more personalized and accurate product recommendations to the users, leveraging user behavior and preference data.', status: 'in progress'}) MERGE (optimizeAuth:Task {name: 'Optimize', description: 'Enhance AuthService’s performance and security by optimizing the authentication mechanisms and implementing additional security measures to safeguard user information.', status: 'open'}) MERGE (newTask:Task {name: 'ImproveSecurity', description: 'Enhance the security of microservices by implementing advanced encryption and securing endpoints.', status: 'open'}) MERGE (teamA:Team {name: 'TeamA'}) MERGE (teamB:Team {name: 'TeamB'}) MERGE (teamC:Team {name: 'TeamC'}) MERGE (teamD:Team {name: 'TeamD'}) MERGE (alice:Person {name: 'Alice'}) MERGE (bob:Person {name: 'Bob'}) MERGE (charlie:Person {name: 'Charlie'}) MERGE (diana:Person {name: 'Diana'}) MERGE (eva:Person {name: 'Eva'}) MERGE (frank:Person {name: 'Frank'}) MERGE (catalog)-[:DEPENDS_ON]->(db) MERGE (order)-[:DEPENDS_ON]->(db) MERGE (user)-[:DEPENDS_ON]->(db) MERGE (payment)-[:DEPENDS_ON]->(db) MERGE (inventory)-[:DEPENDS_ON]->(db) MERGE (shipping)-[:DEPENDS_ON]->(mq) MERGE (review)-[:DEPENDS_ON]->(cache) MERGE (recommendation)-[:DEPENDS_ON]->(api) MERGE (auth)-[:DEPENDS_ON]->(db) MERGE (order)-[:DEPENDS_ON]->(inventory) MERGE (order)-[:DEPENDS_ON]->(shipping) MERGE (order)-[:DEPENDS_ON]->(payment) MERGE (catalog)-[:DEPENDS_ON]->(review) MERGE (catalog)-[:DEPENDS_ON]->(recommendation) MERGE (user)-[:DEPENDS_ON]->(auth) MERGE (payment)-[:DEPENDS_ON]->(auth) MERGE (shipping)-[:DEPENDS_ON]->(auth) MERGE (catalog)-[:MAINTAINED_BY]->(teamA) MERGE (order)-[:MAINTAINED_BY]->(teamB) MERGE (user)-[:MAINTAINED_BY]->(teamC) MERGE (payment)-[:MAINTAINED_BY]->(teamD) MERGE (inventory)-[:MAINTAINED_BY]->(teamA) MERGE (shipping)-[:MAINTAINED_BY]->(teamB) MERGE (review)-[:MAINTAINED_BY]->(teamC) MERGE (recommendation)-[:MAINTAINED_BY]->(teamD) MERGE (auth)-[:MAINTAINED_BY]->(teamA) MERGE (bugFixCatalog)-[:ASSIGNED_TO]->(teamA) MERGE (featureAddOrder)-[:ASSIGNED_TO]->(teamB) MERGE (refactorUser)-[:ASSIGNED_TO]->(teamC) MERGE (optimizePayment)-[:ASSIGNED_TO]->(teamD) MERGE (updateInventory)-[:ASSIGNED_TO]->(teamA) MERGE (enhanceShipping)-[:ASSIGNED_TO]->(teamB) MERGE (reviewFix)-[:ASSIGNED_TO]->(teamC) MERGE (recommendationFeature)-[:ASSIGNED_TO]->(teamD) MERGE (optimizeAuth)-[:ASSIGNED_TO]->(teamA) MERGE (bugFixCatalog)-[:LINKED_TO]->(catalog) MERGE (featureAddOrder)-[:LINKED_TO]->(order) MERGE (refactorUser)-[:LINKED_TO]->(user) MERGE (optimizePayment)-[:LINKED_TO]->(payment) MERGE (updateInventory)-[:LINKED_TO]->(inventory) MERGE (enhanceShipping)-[:LINKED_TO]->(shipping) MERGE (reviewFix)-[:LINKED_TO]->(review) MERGE (recommendationFeature)-[:LINKED_TO]->(recommendation) MERGE (optimizeAuth)-[:LINKED_TO]->(auth) MERGE (alice)-[:PART_OF]->(teamA) MERGE (bob)-[:PART_OF]->(teamB) MERGE (charlie)-[:PART_OF]->(teamC) MERGE (diana)-[:PART_OF]->(teamD) MERGE (eva)-[:PART_OF]->(teamA) MERGE (frank)-[:PART_OF]->(teamB) MERGE (newTask)-[:LINKED_TO]->(auth) MERGE (newTask)-[:ASSIGNED_TO]->(teamA)" -} diff --git a/comps/knowledgegraphs/langchain/doc/output_cypher.png b/comps/knowledgegraphs/langchain/doc/output_cypher.png deleted file mode 100644 index c77f54611..000000000 Binary files a/comps/knowledgegraphs/langchain/doc/output_cypher.png and /dev/null differ diff --git a/comps/knowledgegraphs/langchain/doc/output_query1.png b/comps/knowledgegraphs/langchain/doc/output_query1.png deleted file mode 100644 index cc470e1a5..000000000 Binary files a/comps/knowledgegraphs/langchain/doc/output_query1.png and /dev/null differ diff --git a/comps/knowledgegraphs/langchain/doc/output_query2.png b/comps/knowledgegraphs/langchain/doc/output_query2.png deleted file mode 100644 index af9e3dae9..000000000 Binary files a/comps/knowledgegraphs/langchain/doc/output_query2.png and /dev/null differ diff --git a/comps/knowledgegraphs/langchain/doc/output_rag.png b/comps/knowledgegraphs/langchain/doc/output_rag.png deleted file mode 100644 index 25bb1e409..000000000 Binary files a/comps/knowledgegraphs/langchain/doc/output_rag.png and /dev/null differ diff --git a/comps/knowledgegraphs/langchain/doc/workflow.png b/comps/knowledgegraphs/langchain/doc/workflow.png deleted file mode 100644 index 770870708..000000000 Binary files a/comps/knowledgegraphs/langchain/doc/workflow.png and /dev/null differ diff --git a/comps/knowledgegraphs/langchain/ingest.py b/comps/knowledgegraphs/langchain/ingest.py deleted file mode 100755 index 7e7e1d8b3..000000000 --- a/comps/knowledgegraphs/langchain/ingest.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import json -import os - -from langchain_community.graphs import Neo4jGraph - -neo4j_endpoint = os.getenv("NEO4J_ENDPOINT", "neo4j://localhost:7687") -neo4j_username = os.getenv("NEO4J_USERNAME", "neo4j") -neo4j_password = os.getenv("NEO4J_PASSWORD", "neo4j") -graph = Neo4jGraph(url=neo4j_endpoint, username=neo4j_username, password=neo4j_password) - -# remove all nodes -graph.query("MATCH (n) DETACH DELETE n") - -# ingest -import_query = json.load(open("data/microservices.json", "r"))["query"] -graph.query(import_query) -print("Total nodes: ", graph.query("MATCH (n) RETURN count(n)")) -print("Total edges: ", graph.query("MATCH ()-->() RETURN count(*)")) diff --git a/comps/knowledgegraphs/langchain/knowledge_graph.py b/comps/knowledgegraphs/langchain/knowledge_graph.py deleted file mode 100755 index 3b5b2882e..000000000 --- a/comps/knowledgegraphs/langchain/knowledge_graph.py +++ /dev/null @@ -1,167 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import os -import pathlib -import sys - -cur_path = pathlib.Path(__file__).parent.resolve() -comps_path = os.path.join(cur_path, "../../../") -sys.path.append(comps_path) -import json - -import requests -from langchain import hub -from langchain.agents import AgentExecutor, Tool, load_tools -from langchain.agents.format_scratchpad import format_log_to_str -from langchain.agents.output_parsers import ReActJsonSingleInputOutputParser -from langchain.chains import GraphCypherQAChain, RetrievalQA -from langchain.tools.render import render_text_description -from langchain_community.chat_models.huggingface import ChatHuggingFace -from langchain_community.embeddings import HuggingFaceEmbeddings -from langchain_community.graphs import Neo4jGraph -from langchain_community.llms import HuggingFaceEndpoint -from langchain_community.vectorstores.neo4j_vector import Neo4jVector - -from comps import CustomLogger, GeneratedDoc, GraphDoc, ServiceType, opea_microservices, register_microservice - -logger = CustomLogger("knowledge_graph") -logflag = os.getenv("LOGFLAG", False) - - -def get_retriever(input, neo4j_endpoint, neo4j_username, neo4j_password, llm): - embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") - vector_index = Neo4jVector.from_existing_graph( - embeddings, - url=neo4j_endpoint, - username=neo4j_username, - password=neo4j_password, - index_name=input.rag_index_name, - node_label=input.rag_node_label, - text_node_properties=input.rag_text_node_properties, - embedding_node_property=input.rag_embedding_node_property, - ) - vector_qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=vector_index.as_retriever()) - return vector_qa - - -def get_cypherchain(graph, cypher_llm, qa_llm): - graph.refresh_schema() - cypher_chain = GraphCypherQAChain.from_llm(cypher_llm=cypher_llm, qa_llm=qa_llm, graph=graph, verbose=True) - return cypher_chain - - -def get_agent(vector_qa, cypher_chain, llm_repo_id): - # define two tools - tools = [ - Tool( - name="Tasks", - func=vector_qa.invoke, - description="""Useful when you need to answer questions about descriptions of tasks. - Not useful for counting the number of tasks. - Use full question as input. - """, - ), - Tool( - name="Graph", - func=cypher_chain.invoke, - description="""Useful when you need to answer questions about microservices, - their dependencies or assigned people. Also useful for any sort of - aggregation like counting the number of tasks, etc. - Use full question as input. - """, - ), - ] - - # setup ReAct style prompt - prompt = hub.pull("hwchase17/react-json") - prompt = prompt.partial( - tools=render_text_description(tools), - tool_names=", ".join([t.name for t in tools]), - ) - - # define chat model - llm = HuggingFaceEndpoint(repo_id=llm_repo_id, max_new_tokens=512) - chat_model = ChatHuggingFace(llm=llm) - chat_model_with_stop = chat_model.bind(stop=["\nObservation"]) - - # define agent - agent = ( - { - "input": lambda x: x["input"], - "agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]), - } - | prompt - | chat_model_with_stop - | ReActJsonSingleInputOutputParser() - ) - - # instantiate AgentExecutor - agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) - return agent_executor - - -@register_microservice( - name="opea_service@knowledge_graph", - endpoint="/v1/graphs", - host="0.0.0.0", - port=8060, -) -def graph_query(input: GraphDoc) -> GeneratedDoc: - if logflag: - logger.info(input) - - ## Connect to Neo4j - neo4j_endpoint = os.getenv("NEO4J_ENDPOINT", "neo4j://localhost:7687") - neo4j_username = os.getenv("NEO4J_USERNAME", "neo4j") - neo4j_password = os.getenv("NEO4J_PASSWORD", "neo4j") - graph = Neo4jGraph(url=neo4j_endpoint, username=neo4j_username, password=neo4j_password) - - ## keep for multiple tests, will remove later - graph.query("MATCH (n) DETACH DELETE n") - import_query = json.load(open("data/microservices.json", "r"))["query"] - graph.query(import_query) - - ## get tool flag - flag_agent = True if input.strtype == "query" else False - flag_rag = True if input.strtype in ["query", "rag"] else False - - ## define LLM - if flag_agent or flag_rag: - llm_endpoint = os.getenv("LLM_ENDPOINT", "http://localhost:8080") - llm = HuggingFaceEndpoint( - endpoint_url=llm_endpoint, - timeout=600, - max_new_tokens=input.max_new_tokens, - ) - - ## define a retriever - if flag_rag: - vector_qa = get_retriever(input, neo4j_endpoint, neo4j_username, neo4j_password, llm) - - ## define an agent - if flag_agent: - llm_repo_id = os.getenv("AGENT_LLM", "HuggingFaceH4/zephyr-7b-beta") - cypher_chain = get_cypherchain(graph, llm, llm) # define a cypher generator - agent_executor = get_agent(vector_qa, cypher_chain, llm_repo_id) - - ## process input query - if input.strtype == "cypher": - result_dicts = graph.query(input.text) - result = "" - for result_dict in result_dicts: - for key in result_dict: - result += str(key) + ": " + str(result_dict[key]) - elif input.strtype == "rag": - result = vector_qa.invoke(input.text)["result"] - elif input.strtype == "query": - result = agent_executor.invoke({"input": input.text})["output"] - else: - result = "Please specify strtype as one of cypher, rag, query." - if logflag: - logger.info(result) - return GeneratedDoc(text=result, prompt=input.text) - - -if __name__ == "__main__": - opea_microservices["opea_service@knowledge_graph"].start() diff --git a/comps/knowledgegraphs/langchain/requirements.txt b/comps/knowledgegraphs/langchain/requirements.txt deleted file mode 100644 index 39b351530..000000000 --- a/comps/knowledgegraphs/langchain/requirements.txt +++ /dev/null @@ -1,25 +0,0 @@ -beautifulsoup4 -docarray -docarray[full] -easyocr -fastapi -huggingface_hub -langchain -langchain_community==0.2.5 -langchain_openai -langchainhub -neo4j -numpy -opentelemetry-api -opentelemetry-exporter-otlp -opentelemetry-sdk -pandas -Pillow -prometheus-fastapi-instrumentator -pymupdf -python-docx -redis -sentence-transformers -shortuuid -tiktoken -uvicorn diff --git a/comps/knowledgegraphs/langchain/test.py b/comps/knowledgegraphs/langchain/test.py deleted file mode 100644 index 72fefc144..000000000 --- a/comps/knowledgegraphs/langchain/test.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2024 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import json -import os -import timeit - -import pandas as pd -import requests - - -def test_text(ip_addr="localhost", batch_size=1): - proxies = {"http": ""} - url = "http://localhost:8060/v1/graphs" - - # payload = {"text":"MATCH (t:Task {status:'open'}) RETURN count(*)","strtype":"cypher"} - content = {"text": "MATCH (t:Task {status:'open'}) RETURN count(*)"} - payload = {"input": json.dumps(content)} - - try: - resp = requests.post(url=url, data=payload, proxies=proxies) - print(resp.text) - resp.raise_for_status() # Raise an exception for unsuccessful HTTP status codes - print("Request successful!") - except requests.exceptions.RequestException as e: - print("An error occurred:", e) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--batch_size", type=int, default=1, help="Batch size for testing") - parser.add_argument("--ip_addr", type=str, default="localhost", help="IP address of the server") - - args = parser.parse_args() - test_text(ip_addr=args.ip_addr, batch_size=args.batch_size)