Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: added llm sample #126

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions usecases/llm/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export OPENAI_API_KEY="xxxxxx"
export PINECONE_API_KEY="xxxxxx"
export PINE_ENV="xxxxxx"
export AWS_ACCESS_KEY="xxxxxx"
export AWS_SECRET_KEY="xxxxxx"
export AWS_BUCKET_NAME="xxxxxx"
export AWS_REGION_S3="xxxxxx"
export PG_DB="xxxxxx"
export PG_HOST="xxxxxx"
export PG_USER="xxxxxx"
export PG_PASSWORD="xxxxxx"
export DOZER_APP_ID="xxxxxx"
export DOZER_TOKEN="xxxxxx"
17 changes: 17 additions & 0 deletions usecases/llm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Use the official Python 3.9 image as the base image
FROM python:3.9

# Set the working directory within the container
WORKDIR /usr/src/app

# Copy the requirements.txt file into the container
COPY requirements.txt .

# Install dependencies from requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Copy your application files into the container
COPY . .

EXPOSE 8000
CMD ["python", "-m", "chainlit", "run", "app.py", "--port" ,"8000"]
21 changes: 21 additions & 0 deletions usecases/llm/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Mrunmay Shelar

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
12 changes: 12 additions & 0 deletions usecases/llm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Hyper-personalized chatbots using LLMs, Dozer and Vector Databases for Banking and Finance

In this example, we will be using Dozer along with Chainlit, Langchain and Pinecone.

### Pre-requisites

1. Pinecone account
2. OpenAI API key
3. Python 3.9/ Docker

### Setup

254 changes: 254 additions & 0 deletions usecases/llm/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
import chainlit as cl
import os
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.schema import HumanMessage
from time import sleep
## For Vector DB
import pinecone
import uuid
from langchain.vectorstores import Pinecone
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
from langchain.chains import RetrievalQA
from langchain.agents import Tool
#from langchain import PromptTemplate, HuggingFaceHub, LLMChain
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.agents import initialize_agent
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQAWithSourcesChain
from langchain.prompts.chat import ChatPromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate
from chainlit import user_session
import os
from pydozer.api import ApiClient
from langchain.agents import ConversationalChatAgent, AgentExecutor
import re
import json

def show_json(obj):
display(json.loads(obj.model_dump_json()))


def wait_on_run(run, thread):
while run.status == "queued" or run.status == "in_progress":
run = client.beta.threads.runs.retrieve(
thread_id=thread.id,
run_id=run.id,
)
sleep(0.5)
return run
### Dozer
from openai import OpenAI
client = OpenAI()
DOZER_CLOUD_HOST = "data.getdozer.io:443"

def get_api_client(app_id=None, token=None):
return ApiClient("financial_profile", url=DOZER_CLOUD_HOST, app_id=app_id,
secure=True, token=token) if app_id else ApiClient("financial_profile", url="localhost:80")


customer_client = get_api_client(app_id=os.environ.get("DOZER_APP_ID"), token=os.environ.get("DOZER_TOKEN"))

def getCustomerData(input):
data = customer_client.query({"$filter": {"id":input}})
rec = data.records[0].record
id = rec.values[0].int_value
name = rec.values[1].string_value
income = rec.values[2].int_value
age = rec.values[3].int_value
dependents = rec.values[4].int_value
address = rec.values[5].string_value
prob = rec.values[6].float_value
credit_amt = rec.values[7].int_value
repay_status = rec.values[8].float_value
util_ratio = rec.values[9].float_value


return [id,name,income,age,dependents, address, prob,credit_amt,repay_status,util_ratio ]



#user_env = user_session.get(".env")
OPEN_API_KEY = os.environ.get("OPENAI_API_KEY")
PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")
PINECONE_ENV = os.environ.get("PINE_ENV")
# platform.openai.com
model_name = 'text-embedding-ada-002'



# find ENV (cloud region) next to API key in console
index_name = 'langchain-retrieval-agent'
pinecone.init(
api_key=PINECONE_API_KEY,
environment=PINECONE_ENV
)


#embeddings = OpenAIEmbeddings()


text_field = "Answer"
index = pinecone.Index('langchain-retrieval-agent')

file = client.files.create(
file=open("/home/mrunmay/Desktop/Dozer/dozer-samples/usecases/llm/data/BankFAQs.csv", "rb"),
purpose='assistants'
)

# switch back to normal index for langchain
#index = pinecone.Index(index_name)


def customerProfile(input):
data = getCustomerData(int(input))
id = data[0]
name1 = data[1]
income = data[2]
age= data[3]
dependents= data[4]
address= data[5]
prob = data[6]
credit_amt= data[7]
repay_status= data[8]
util_ratio= data[9]

profile = {
"id": id,
"name": name1,
"age": age,
"income": income,
"dependents": dependents,
"address": address,
"prob": prob,
"credit_amt": credit_amt,
"repay_status": repay_status,
"util_ratio": util_ratio


}
return json.dumps(profile)

tools = [
{
"type": "function",
"function": {
"name": "customerProfile",
"description": "Useful when you need customer data to decide eligibility for a particular credit card. Use to check the probability of default and available balance to use it for eligibility",
"parameters": {
"type": "object",
"properties": {
"id": {"type": "number"}

},
"required": ["id"]

}},


},
{
"type": "code_interpreter",
}
]
assistant = client.beta.assistants.create(
name="Bank Assistant",
instructions="You are a bank chat bot. Help the client with all their banking needs. Calculate if the client is eligible for a credit card or not depending upon their customer profile",
tools=tools,
model="gpt-4-1106-preview",
file_ids=[file.id]

)


def setName(userName):
global name
name = userName




global res
@cl.on_chat_start

async def start():
intro = "Hi there, I am an assistant for Bank A. I am here to assist you with all your banking needs! Please enter your id: "

res = await cl.AskUserMessage(content=intro,timeout=200,raise_on_timeout=True).send()
global id
id = int(res['content'])
greeting = f"Hi {res['content']}. What brings you here?"
await cl.Message(content=greeting).send()
setName(res['content'])
# global credit
# credit = getCredit(int(res['content']))
global customerinfo
customerinfo = customerProfile(int(res['content']) )


#print(customerinfo)
thread = client.beta.threads.create()
cl.user_session.set("chain", thread)



@cl.on_message
async def main(text_rep: str):
thread = cl.user_session.get("chain")

#print(text_rep.content)
#print(thread.id, thread)
message = client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content=f"{text_rep.content}"
)
run = client.beta.threads.runs.create(
thread_id=thread.id,
assistant_id=assistant.id,
model="gpt-4-1106-preview",
instructions=f"Please help the user according to his ID: {id} ",
tools = tools,

)

wait_on_run(run, thread)
if run.status == "requires_action":

tool_id = run.required_action.submit_tool_outputs.tool_calls
run = client.beta.threads.runs.submit_tool_outputs(
thread_id=thread.id,
run_id=run.id,
tool_outputs=[
{
"tool_id": tool_id[0].id,
"output": customerinfo,
}
]

)




wait_on_run(run, thread)



messages = client.beta.threads.messages.list(
thread_id=thread.id
)
obj_string = str(messages)
pattern = re.compile(
r"ThreadMessage\(id='(?P<id>[^']*)', assistant_id='(?P<assistant_id>[^']*)', content=\[MessageContentText\(text=Text\((annotations=\[.*?\], )?value=\"(?P<content>.*?)\"\), type='(?P<message_content_text_type>[^']*)'\)\], created_at=(?P<created_at>\d+), file_ids=\[(?P<file_ids>.*?)\], metadata=\{(?P<metadata>.*?)\}, object='(?P<object>[^']*)', role='(?P<role>[^']*)', run_id='(?P<run_id>[^']*)', thread_id='(?P<thread_id>[^']*)'\)"
)
matches = pattern.finditer(obj_string)
for match in matches:
text_rep = match.group('content').replace('\\n', '\n').replace('\\"', '"')


#print(content)
await cl.Message(
content=text_rep ,
).send()
31 changes: 31 additions & 0 deletions usecases/llm/chainlit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Welcome to GoldenGate Bank ! 🏦💵

Hi there, Customer ! 👋 We're excited to have you on board. GoldenGate Bank has been serving customers since 1970 . With a commitment to excellence, we have grown into a reputable financial institution, providing a wide range of services to meet your banking needs.

# Our Services 🎄🎄🎁

At 'GoldenGate Bank', we offer a comprehensive range of banking services to cater to your financial requirements. Our services include:

**Savings Accounts**: Choose from a variety of savings accounts with competitive interest rates and personalized features.
**Current Accounts**: Our current accounts are designed to support businesses and individuals with seamless transaction capabilities.
**Fixed Deposits**: Benefit from attractive interest rates and flexible tenure options with our fixed deposit accounts.

# Credit Cards 💳💳

Experience the convenience and benefits of GoldenGate Bridge credit cards, tailored to suit your lifestyle and spending habits. We offer the following credit cards:

1. **Rewards Card** 📦🎁
Earn reward points on every purchase.
Eligibility: Minimum monthly income of $X,XX and a credit score of [Credit Score Requirement].

2. **Travel Card** ✈️🧳
Enjoy exclusive travel perks and offers.
Eligibility: Minimum monthly income of $X,XX and a credit score of [Credit Score Requirement].

3. **Cashback Card** 💵💵
Get cashback on eligible purchases.
Eligibility: Minimum monthly income of $X,XX and a credit score of [Credit Score Requirement].

4. **Premium Card** 💰💲
Access premium benefits, including airport lounge access and concierge services.
Eligibility: Minimum monthly income of $X,XXX and a credit score of [Credit Score Requirement].
Binary file added usecases/llm/data/BankFAQs.xlsx
Binary file not shown.
13 changes: 13 additions & 0 deletions usecases/llm/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '4.25'

services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/usr/src/app
env_file:
- .env
ports:
- '8000:8000'
Loading