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

Update prompt and delete unnecessary stacks #241

Merged
merged 1 commit into from
Oct 22, 2024
Merged
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
103 changes: 0 additions & 103 deletions cdk/examples/generative_ai_rag/lambda/index.py

This file was deleted.

158 changes: 87 additions & 71 deletions cdk/examples/generative_ai_rag/web-app/pages/rag_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,80 +37,94 @@ def invoke_bedrock_stream(client: Any, system_prompt: str, user_prompt: str) ->
"messages": [{"role": "user", "content": user_prompt}]
})

try:
response = client.invoke_model_with_response_stream(
body=body,
modelId=MODEL_ID,
accept='application/json',
contentType='application/json'
)
for event in response.get('body'):
chunk = json.loads(event['chunk']['bytes'])
if chunk['type'] == 'content_block_delta':
if chunk['delta']['type'] == 'text_delta':
yield chunk['delta']['text']
elif chunk['type'] == 'content_block_stop':
break
except Exception as e:
st.error(f"Error invoking Bedrock model: {e}")
yield ""
with st.spinner("Generating response...."):
try:
response = client.invoke_model_with_response_stream(
body=body,
modelId=MODEL_ID,
accept='application/json',
contentType='application/json'
)
for event in response.get('body'):
chunk = json.loads(event['chunk']['bytes'])
if chunk['type'] == 'content_block_delta':
if chunk['delta']['type'] == 'text_delta':
yield chunk['delta']['text']
elif chunk['type'] == 'content_block_stop':
break
except Exception as e:
st.error(f"Error invoking Bedrock model: {e}")
yield ""

def get_prompt_template(retrieved_passages: List[str]) -> str:
"""Return the improved prompt template for the AI assistant with response formatting."""
return f"""
You are an AI assistant answering questions about AWS re:Invent 2024 session information and general queries.
You are an AI assistant answering questions about AWS re:Invent 2024 session information and general queries.
Your task is to analyze the user's question, categorize it, and provide an appropriate response.
Every session information includes the following fields:
- Title
- Session Code
- Description
- Session Type
- Topic
- Areas of Interest
- Level
- Target Roles
- Venue
- Date and Time
- Prerequisites
- Key Points

First, analyze the user's question and categorize it into one of the following:
1. General question
2. re:Invent session recommendation question
3. re:Invent session information question

Then, based on your analysis, prepare a response following these guidelines:

1. For general questions:
- Ignore the content in the retrieved passages.
- Provide a direct answer to the question based on your general knowledge.
- Do not include any uncertain information or speculation.
- If the question is outside your knowledge base, politely state that you don't have that information.

2. For re:Invent session recommendation questions:
- Use the information from the retrieved passages to recommend sessions.
- Prioritize recommendations based on:
a) Exact matches in the "Related AWS Services" field (highest priority)
b) Relevance in the "Related AWS Services", "Description" and "Title" fields
c) Relevance to the "Topic" and "Areas of Interest"
- Must to include "Description", "Time" and "Venue" information for recommended sessions.

3. For re:Invent session information questions:
- Use the information from the retrieved passages to provide detailed session information.
- Focus on the following aspects:
- Description
- Areas of Interest
- Session Type
- Prerequisites
- Key Points
- Related AWS Services
- Provide accurate Venue and Date/Time information when asked about schedules and locations.
- If the search results lack a clear answer, explicitly state the inability to find exact information.

General guidelines:
- Provide concise answers with all relevant information.
- Address the core question directly without unnecessary preamble or conclusion.
- Always base your answers on the provided data and refrain from offering uncertain information.
- Verify user assertions against search results; don't assume user statements are factual.

1. GENERAL
- This question type is for general questions that are not related to re:Invent sessions.

2. REINVENT_INFORMATION
- This question type is for questions requesting information about specific sessions
- This question type is for questions requesting information about sessions held at certain venue and times

3. REINVENT_RECOMMENDATION
- This question type is for session recommendation questions for specific topics or interests

Second, analyze the user's question and provide a response based on the question type.

1. GENERAL
- Ignore the content in the retrieved passages.
- Provide a direct answer to the question based on your general knowledge.
- Do not include any uncertain information or speculation.
- If the question is outside your knowledge base, politely state that you don't have that information.

2. REINVENT_INFORMATION
- Think step-by-step before providing an answer.
- Use the information from the retrieved passages to answer the question.
- Extract all fields data from each information and use it to generate an answer.
- Prioritize recommendations based on:
a) Relevance in the "Related AWS Services", "Description" and "Title" fields
b) Relevance to the "Topic" and "Areas of Interest"
- When a specific date is mentioned, only recommend sessions occurring on that exact date.

3. REINVENT_RECOMMENDATION
- Think step-by-step before providing an answer.
- Use the information from the retrieved passages to answer the question.
- Extract all fields data from each information and use it to generate an answer.
- Analyze each condition of the question one by one, with particular emphasis on matching the exact date and time, and venue.
- When a specific date or venue is mentioned, only recommend sessions occurring on that exact date and venue.

Here are the retrieved passages:

{retrieved_passages}

IMPORTANT:
Your final response should only contain the actual answer to the user's question.
Do not include any explanation of your thought process, categorization, or analysis in the final response.
If retrieved passages are empty and question type is not GENERAL, respond with "Sorry. I couldn't find any related information."
- Always base your answers on the provided data and refrain from offering uncertain information.
- Your final response should only contain the actual answer to the user's question.
- Do not include any explanation of your thought process, categorization, or analysis in the final response.
- If retrieved passages are empty and question type is not GENERAL, respond with "Sorry. I couldn't find any related information."
- Do not modify fields data in the retrieved passages.
- If all conditions are not met, recommend similar sessions and be sure to explain the reason.

CRITICAL RESPONSE FORMAT:
You MUST format your entire response EXACTLY as follows, with no exceptions:
- You MUST format your entire response EXACTLY as follows, with no exceptions:

[QUESTION_TYPE]
GENERAL or REINVENT_RECOMMENDATION or REINVENT_INFORMATION
Expand All @@ -119,20 +133,28 @@ def get_prompt_template(retrieved_passages: List[str]) -> str:
Your complete answer here, with no text outside these tags.
[/RESPONSE]

IMPORTANT RULES:
IMPORTANT RESPONSE FORMAT RULES:
1. ALWAYS include both [QUESTION_TYPE] and [RESPONSE] tags.
2. [QUESTION_TYPE] must contain ONLY ONE of the three specified types, nothing else.
3. [RESPONSE] must contain your COMPLETE answer and nothing else.
4. DO NOT include ANY text outside of these tags.
5. If you cannot provide an answer, still use the tags and put your "Sorry" message inside the [RESPONSE] tags.
5. If you cannot provide an answer, still use the tags and put your "Sorry. I couldn't answer that question." message inside the [RESPONSE] tags.
6. Never use [GENERAL], [REINVENT_RECOMMENDATION], or [REINVENT_INFORMATION] as standalone tags.

EXAMPLE OF CORRECT FORMAT:
[QUESTION_TYPE]
GENERAL
REINVENT_RECOMMENDATION
[/QUESTION_TYPE]
[RESPONSE]
This is where your complete answer would go, with no other text outside these tags.
Based on your question, I recommend the following session:

1. Responsible generative AI tabletop: Governance and oversight [REPEAT]
- Session Code: GHJ208-R1
- Session Type: Gamified learning
- Venue: Mandalay Bay
- Date and Time: Wednesday, Dec 04, 12:00 p.m.
- This session offers a gamified learning experience where participants engage in a tabletop exercise simulating board-level decision-making for generative AI initiatives in a fictional organization. ... (blah, blah) ...
2. ... (More sessions) ...
[/RESPONSE]

Failure to follow this format exactly will result in an error. Double-check your response before submitting.
Expand All @@ -149,7 +171,7 @@ def retrieve_from_knowledge_base(client: Any, knowledge_base_id: str, prompt: st
},
retrievalConfiguration={
'vectorSearchConfiguration': {
'numberOfResults': 10
'numberOfResults': 20
}
}
)
Expand Down Expand Up @@ -185,8 +207,6 @@ def main():
retrieved_passages = [result['content']['text'] for result in retrieved_results]
formatted_passages = "\n\n".join(f"Passage {i+1}:\n{passage}" for i, passage in enumerate(retrieved_passages))

print(formatted_passages)

# Initialize variables to store the full response and the content after the [RESPONSE] tag
full_response = ""
response_content = ""
Expand Down Expand Up @@ -224,14 +244,10 @@ def main():
question_type = question_type_match.group(1).strip() if question_type_match else "UNKNOWN"
final_response = response_match.group(1).strip() if response_match else "I apologize. There was an issue generating an appropriate response."

print(full_response)
print(question_type)
print(final_response)

message_placeholder.markdown(final_response)

st.session_state.messages.append({"role": "assistant", "content": final_response})

# Display citations only for non-general questions
if question_type not in ["GENERAL", "UNKNOWN"]:
with st.expander("Data Sources"):
Expand Down
20 changes: 5 additions & 15 deletions cdk/examples/other_stack/bedrock_agent_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ def __init__(

super().__init__(scope, id, **kwargs)

# create dynamodb table
self.bookmark_table = dynamodb.Table(
self,
"ReinventBookmarkTable",
table_name="reinvent-bookmark",
partition_key=dynamodb.Attribute(name="sessionCode",
type=dynamodb.AttributeType.STRING),
billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST,
removal_policy=RemovalPolicy.DESTROY,
)

# create S3 bucket
self.bucket = s3.Bucket(
self,
Expand All @@ -57,10 +46,11 @@ def __init__(
self.knowledge_base_data_source = bedrock.S3DataSource(self, 'KnowledgeBaseDataSource',
bucket=self.bucket,
knowledge_base=self.knowledge_base,
data_source_name='ReinventSessionInformationText',
chunking_strategy= bedrock.ChunkingStrategy.fixed_size(
max_tokens= 512,
overlap_percentage= 20
data_source_name='ReinventSessionInformationText',
chunking_strategy= bedrock.ChunkingStrategy.hierarchical(
overlap_tokens=60,
max_parent_token_size=1500,
max_child_token_size=300
)
)

Expand Down
Loading