Skip to content

Commit 70bcfa9

Browse files
committed
Code cleaning
2 utils libraries added. The standalone and mcp server exploit on utils libraries for less updates in testing.
1 parent fab40d2 commit 70bcfa9

File tree

5 files changed

+198
-317
lines changed

5 files changed

+198
-317
lines changed

src/client/mcp/rag/README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
**Version:** *Developer preview*
55

66
## Introduction
7-
This document describe how to re-use the configuration tested in the **AI Optimizer & Toolkit** an expose it as an MCP tool to a local **Claude Desktop** and how to setup as a remote MCP server. This early draft implementation utilizes the `stdio` and `sse` to interact between the agent dashboard, represented by the **Claude Desktop**, and the tool. Not always the parameters are exported at the moment, and only Ollama or OpenAI configuration are supported.
7+
This document describe how to re-use the configuration tested in the **AI Optimizer & Toolkit** an expose it as an MCP tool to a local **Claude Desktop** and how to setup as a remote MCP server. This early draft implementation utilizes the `stdio` and `sse` to interact between the agent dashboard, represented by the **Claude Desktop**, and the tool. Only Ollama or OpenAI configuration are currently supported.
88
Full support will come.
99

1010
## Pre-requisites.
@@ -103,17 +103,23 @@ This will impose the usage of `rag_tool` in any case.
103103

104104
In `rag_base_optimizer_config_mcp.py`:
105105

106+
* Update the absolute path of your `optimizer_settings.json`. Example:
107+
108+
```python
109+
rag.set_optimizer_settings_path("/Users/cdebari/Documents/GitHub/ai-optimizer-mcp-export/src/client/mcp/rag/optimizer_settings.json")
110+
```
111+
106112
* Substitute `Local` with `Remote client` line:
107113

108114
```python
109-
#mcp = FastMCP("research", port=8001) #Remote client
115+
#mcp = FastMCP("rag", port=8001) #Remote client
110116
mcp = FastMCP("rag") #Local
111117
```
112118

113119
* Substitute `stdio` with `sse` line of code:
114120
```python
115-
mcp.run(transport='stdio')
116-
#mcp.run(transport='sse')
121+
mcp.run(transport='stdio')
122+
#mcp.run(transport='sse')
117123
```
118124

119125
* Start MCP server in another shell with:
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from langchain_openai import ChatOpenAI
2+
from langchain_openai import OpenAIEmbeddings
3+
from langchain_huggingface import HuggingFaceEmbeddings
4+
from langchain_ollama import OllamaEmbeddings
5+
from langchain_ollama import OllamaLLM
6+
7+
from langchain_community.vectorstores.utils import DistanceStrategy
8+
9+
from langchain_community.vectorstores import oraclevs
10+
from langchain_community.vectorstores.oraclevs import OracleVS
11+
import oracledb
12+
13+
14+
def get_llm(data):
15+
llm={}
16+
llm_config = data["ll_model_config"][data["user_settings"]["ll_model"]["model"]]
17+
api=llm_config["api"]
18+
url=llm_config["url"]
19+
api_key=llm_config["api_key"]
20+
model=data["user_settings"]["ll_model"]["model"]
21+
print(f"CHAT_MODEL: {model} {api} {url} {api_key}")
22+
if api == "ChatOllama":
23+
# Initialize the LLM
24+
llm = OllamaLLM(
25+
model=model,
26+
base_url=url
27+
)
28+
elif api == "OpenAI":
29+
30+
llm=llm = ChatOpenAI(
31+
model=model,
32+
api_key=api_key
33+
)
34+
return llm
35+
36+
def get_embeddings(data):
37+
embeddings={}
38+
model=data["user_settings"]["rag"]["model"]
39+
api=data["embed_model_config"][model]["api"]
40+
url=data["embed_model_config"][model]["url"]
41+
api_key=data["embed_model_config"][model]["api_key"]
42+
print(f"EMBEDDINGS: {model} {api} {url} {api_key}")
43+
embeddings = {}
44+
if api=="OllamaEmbeddings":
45+
embeddings=OllamaEmbeddings(
46+
model=model,
47+
base_url=url)
48+
elif api == "OpenAIEmbeddings":
49+
print("BEFORE create embbedding")
50+
embeddings = OpenAIEmbeddings(
51+
model=model,
52+
api_key=api_key
53+
)
54+
print("AFTER create emebdding")
55+
return embeddings
56+
57+
def get_vectorstore(data,embeddings):
58+
59+
config=data["database_config"][data["user_settings"]["rag"]["database"]]
60+
61+
conn23c = oracledb.connect(user=config["user"],
62+
password=config["password"], dsn=config["dsn"])
63+
64+
print("DB Connection successful!")
65+
metric=data["user_settings"]["rag"]["distance_metric"]
66+
67+
dist_strategy=DistanceStrategy.COSINE
68+
if metric=="COSINE":
69+
dist_strategy=DistanceStrategy.COSINE
70+
elif metric == "EUCLIDEAN":
71+
dist_strategy=DistanceStrategy.EUCLIDEAN
72+
73+
print("1")
74+
a=data["user_settings"]["rag"]["vector_store"]
75+
print(f"{a}")
76+
print(f"BEFORE KNOWLEDGE BASE")
77+
print(embeddings)
78+
knowledge_base = OracleVS(conn23c, embeddings, data["user_settings"]["rag"]["vector_store"], dist_strategy)
79+
return knowledge_base
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
"""
2+
Copyright (c) 2024, 2025, Oracle and/or its affiliates.
3+
Licensed under the Universal Permissive License v1.0 as shown at http://oss.oracle.com/licenses/upl.
4+
"""
5+
from typing import List
6+
from mcp.server.fastmcp import FastMCP
7+
import os
8+
from dotenv import load_dotenv
9+
#from sentence_transformers import CrossEncoder
10+
#from langchain_community.embeddings import HuggingFaceEmbeddings
11+
from langchain_core.prompts import PromptTemplate
12+
from langchain_core.runnables import RunnablePassthrough
13+
from langchain_core.output_parsers import StrOutputParser
14+
import json
15+
import logging
16+
logging.basicConfig(level=logging.DEBUG)
17+
18+
from optimizer_utils import config
19+
20+
_optimizer_settings_path= ""
21+
22+
def set_optimizer_settings_path(path: str):
23+
global _optimizer_settings_path
24+
_optimizer_settings_path = path
25+
26+
def rag_tool_base(question: str) -> str:
27+
"""
28+
Use this tool to answer any question that may benefit from up-to-date or domain-specific information.
29+
30+
Args:
31+
question: the question for which are you looking for an answer
32+
33+
Returns:
34+
JSON string with answer
35+
"""
36+
with open(_optimizer_settings_path, "r") as file:
37+
data = json.load(file)
38+
try:
39+
40+
embeddings = config.get_embeddings(data)
41+
42+
print("Embedding successful!")
43+
knowledge_base = config.get_vectorstore(data,embeddings)
44+
print("DB Connection successful!")
45+
46+
print("knowledge_base successful!")
47+
user_question = question
48+
#result_chunks=knowledge_base.similarity_search(user_question, 5)
49+
50+
for d in data["prompts_config"]:
51+
if d["name"]==data["user_settings"]["prompts"]["sys"]:
52+
53+
rag_prompt=d["prompt"]
54+
55+
template = """DOCUMENTS: {context} \n"""+rag_prompt+"""\nQuestion: {question} """
56+
#template = """Answer the question based only on the following context:{context} Question: {question} """
57+
print(template)
58+
prompt = PromptTemplate.from_template(template)
59+
print("before retriever")
60+
print(data["user_settings"]["rag"]["top_k"])
61+
retriever = knowledge_base.as_retriever(search_kwargs={"k": data["user_settings"]["rag"]["top_k"]})
62+
print("after retriever")
63+
64+
65+
# Initialize the LLM
66+
llm = config.get_llm(data)
67+
68+
chain = (
69+
{"context": retriever, "question": RunnablePassthrough()}
70+
| prompt
71+
| llm
72+
| StrOutputParser()
73+
)
74+
print("pre-chain successful!")
75+
answer = chain.invoke(user_question)
76+
77+
#print(f"Results provided for question: {question}")
78+
#print(f"{answer}")
79+
except Exception as e:
80+
print(e)
81+
print("Connection failed!")
82+
answer=""
83+
84+
return f"{answer}"

0 commit comments

Comments
 (0)