Repository navigation
Expand file tree
/
Copy pathlambda_function.py
More file actions
119 lines (102 loc) · 3.3 KB
/
Copy pathlambda_function.py
File metadata and controls
119 lines (102 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import json
import os
import boto3
from botocore.exceptions import ClientError
bedrock_agent_runtime = boto3.client("bedrock-agent-runtime")
KNOWLEDGE_BASE_ID = os.environ["KNOWLEDGE_BASE_ID"]
MODEL_ARN = os.environ["MODEL_ARN"]
def build_system_prompt():
return (
"You are a helpful assistant that answers employee questions "
"using the provided context from the knowledge base. "
"If the answer is not in the documents, say you don't know."
)
def lambda_handler(event, context):
# Handle CORS preflight
method = (
event.get("httpMethod")
or event.get("requestContext", {}).get("http", {}).get("method")
)
if method == "OPTIONS":
return {
"statusCode": 200,
"headers": _cors_headers(),
"body": ""
}
try:
body = event.get("body")
if isinstance(body, str):
body = json.loads(body or "{}")
query = body.get("query") or body.get("question")
session_id = body.get("sessionId")
if not query:
return _response(
400,
{"error": "query (or question) field is required"}
)
user_prompt = f"{build_system_prompt()}\n\nQuestion:\n{query}\n\nAnswer:"
request_params = {
"input": {"text": user_prompt},
"retrieveAndGenerateConfiguration": {
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": KNOWLEDGE_BASE_ID,
"modelArn": MODEL_ARN,
"retrievalConfiguration": {
"vectorSearchConfiguration": {
"numberOfResults": 5
}
},
},
},
}
if session_id:
request_params["sessionId"] = session_id
resp = bedrock_agent_runtime.retrieve_and_generate(**request_params)
answer = resp["output"]["text"]
citations = resp.get("citations", [])
new_session_id = resp.get("sessionId")
return _response(
200,
{
"answer": answer,
"sessionId": new_session_id,
"citations": citations,
},
)
except ClientError as e:
return _response(
500,
{
"error": "AWS error",
"code": e.response["Error"]["Code"],
"message": e.response["Error"]["Message"],
},
)
except Exception as e:
return _response(
500,
{
"error": "Internal server error",
"message": str(e),
},
)
def _cors_headers():
return {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": (
"Content-Type,Authorization,X-Amz-Date,X-Api-Key,"
"X-Amz-Security-Token"
),
"Access-Control-Allow-Methods": "POST,OPTIONS",
"Access-Control-Max-Age": "3600",
}
def _response(status_code, body_dict):
return {
"statusCode": status_code,
"headers": {
"Content-Type": "application/json",
**_cors_headers(),
},
"body": json.dumps(body_dict, indent=2),
}