{"id":25010018,"url":"https://github.com/kyopark2014/simple-chatbot-using-llm-based-on-amazon-bedrock","last_synced_at":"2025-04-12T19:33:44.284Z","repository":{"id":181711467,"uuid":"667182516","full_name":"kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock","owner":"kyopark2014","description":"It shows a simple chatbot based on bedrock LLM where Question/Answering and Summerization of a document  are provided based on LangChain.","archived":false,"fork":false,"pushed_at":"2023-11-27T14:14:12.000Z","size":1228,"stargazers_count":11,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-26T13:45:56.233Z","etag":null,"topics":["bedrock","chatbot","large-language-models"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kyopark2014.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-16T23:00:53.000Z","updated_at":"2024-04-26T21:23:58.000Z","dependencies_parsed_at":"2023-11-27T15:42:20.142Z","dependency_job_id":null,"html_url":"https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock","commit_stats":null,"previous_names":["kyopark2014/chatbot-based-on-bedrock-anthropic","kyopark2014/simple-chatbot-using-llm-based-on-amazon-bedrock"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyopark2014%2Fsimple-chatbot-using-LLM-based-on-amazon-bedrock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyopark2014%2Fsimple-chatbot-using-LLM-based-on-amazon-bedrock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyopark2014%2Fsimple-chatbot-using-LLM-based-on-amazon-bedrock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyopark2014%2Fsimple-chatbot-using-LLM-based-on-amazon-bedrock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kyopark2014","download_url":"https://codeload.github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248621275,"owners_count":21134793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bedrock","chatbot","large-language-models"],"created_at":"2025-02-05T04:52:25.515Z","updated_at":"2025-04-12T19:33:44.259Z","avatar_url":"https://github.com/kyopark2014.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Amazon Bedrock의 LLM을 이용한 Simple Chatbot 만들기\n\n여기서는 Amazon Bedrock의 LLM(Large language Model)을 이용하여 일상적인 대화 또는 질문/답변(Question/Answering)을 수행할 수 있는 챗봇을 구현합니다. 브라우저에서 chatbot으로 메시지를 전송하면, LLM을 통해 답변을 얻고 이를 화면에 보여줍니다. 입력한 모든 내용은 DynamoDB에 call log로 저장됩니다. 또한 파일 버튼을 선택하여, TXT, PDF, CSV와 같은 문서 파일을 Amazon S3로 업로드하고, 텍스트를 추출하여 문서 요약(Summarization) 기능을 사용할 수 있습니다.\n\nLLM 어플리케이션 개발을 위해 LangChain을 활용하였으며, Bedrock이 제공하는 LLM 모델을 확인하고, 필요시 변경할 수 있습니다. Chatbot API를 테스트 하기 위하여 Web Client를 제공합니다. AWS CDK를 이용하여 chatbot을 위한 인프라를 설치하면, ouput 화면에서 브라우저로 접속할 수 있는 URL을 알수 있습니다. Bedrock은 아직 Preview로 제공되므로, AWS를 통해 Preview Access 권한을 획득하여야 사용할 수 있습니다.\n\n\u003cimg src=\"https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/assets/52392004/a62d871e-ad88-400b-9d80-6cdf8b3d63a7\" width=\"800\"\u003e\n\n채팅을 위한 call flow는 아래와 같습니다.\n\n1) 사용자가 채팅창에서 질문(Question)을 입력합니다.\n2) 이것은 Chat API를 이용하여 lambda (chat)에 전달됩니다.\n3) lambda(chat)은 질문을 LLM에 전달합니다.\n4) 답변을 받으면 사용자에게 결과를 전달합니다.\n\n![seq-chat](./sequence/seq-chat.png)\n\n파일업로드 후에 문서 요약(Summerization)을 위한 call flow는 아래와 같습니다.\n\n1) 사용자가 파일 업로드를 요청합니다. 이때 사용하는 Upload API는 lambda (upload)에 전달되어 S3 presigned url을 생성하게 됩니다.\n2) 사용자가 presigned url로 문서를 업로드 하면 S3에 object로 저장됩니다.\n3) Chat API에서 request type을 \"document\"로 지정하면 lambda (chat)는 S3에서 object를 로드하여 텍스트를 추출합니다.\n4) 채팅창에 업로드한 문서의 요약(Summerization)을 보여지기 위해 summerization을 수행하고 그 결과를 사용자에게 전달합니다.\n\n![seq-upload](./sequence/seq-upload.png)\n\n\n\n## Bedrock 모델 정보 가져오기\n\nBedrock은 완전관리형 서비스로 Boto3을 이용하여 아래와 같이 접속합니다. \n\n```python\nimport boto3\nfrom langchain.llms.bedrock import Bedrock\n\nboto3_bedrock = boto3.client(\n    service_name='bedrock-runtime’,\n    region_name=bedrock_region,\n)\n```\n\n## LangChain \n\n아래와 같이 model id와 Bedrock client를 이용하여 LangChain을 정의합니다.\n\n```python\nfrom langchain.llms.bedrock import Bedrock\n\ndef get_parameter(modelId):\n    if modelId == 'amazon.titan-tg1-large' or modelId == 'amazon.titan-tg1-xlarge':\n    return {\n        \"maxTokenCount\": 1024,\n        \"stopSequences\": [],\n        \"temperature\": 0,\n        \"topP\": 0.9\n    }\n    elif modelId == 'anthropic.claude-v1' or modelId == 'anthropic.claude-v2':\n    return {\n        \"max_tokens_to_sample\": 1024,\n        \"temperature\": 0.1,\n        \"top_k\": 250,\n        \"top_p\": 1.0,\n        \"stop_sequences\": [HUMAN_PROMPT]\n    }\nparameters = get_parameter(modelId)\n\nllm = Bedrock(\n    model_id=modelId, \n    client=boto3_bedrock, \n    model_kwargs=parameters)\n```\n\n## 질문/답변하기 (Prompt)\n\nLangChang을 이용하여 아래와 같이 간단한 질문과 답변을 Prompt을 이용하여 구현할 수 있습니다. 아래에서 입력인 text prompt를 LangChain 인터페이스를 통해 요청하면 Bedrock의 LLM 모델을 통해 답변을 얻을 수 있습니다.\n\n```python\nHUMAN_PROMPT = \"\\n\\nHuman:\"\nAI_PROMPT = \"\\n\\nAssistant:\"\n\nmsg = llm(HUMAN_PROMPT+text+AI_PROMPT)\n```\n\n## Conversation\n\n채팅 이력(chat history)을 포함하여 대화를 할수 있게 하는 방식에는 [ConversationChain](https://api.python.langchain.com/en/latest/chains/langchain.chains.conversation.base.ConversationChain.html)을 이용하는 방법과 직접 [PromptTemplate](https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/)을 이용하는 방법이 있습니다. ConversationChain을 사용시 chat history를 Human/Assistanct로 지정하더라도 채팅중에 Human/AI로 전환되는 현상이 있어서(버그로 보임), PromptTemplate를 이용합니다.\n\n### ConversationChain\n\n아래와 같이 대화를 위한 prompt를 정의합니다. \n\n```python\ndef get_conversation_prompt(query):\n    # check korean\n    pattern_hangul = re.compile('[\\u3131-\\u3163\\uac00-\\ud7a3]+')\n    word_kor = pattern_hangul.search(str(query))\n    print('word_kor: ', word_kor)\n\n    if word_kor:    \n        condense_template = \"\"\"다음은 Human과 Assistant의 친근한 대화입니다. Assistant은 상황에 맞는 구체적인 세부 정보를 충분히 제공합니다. 아래 문맥(context)을 참조했음에도 답을 알 수 없다면, 솔직히 모른다고 말합니다.\n\n        Current conversation:\n        {history}\n        \n        Human: {input}\n        \n        Assistant:\n        \"\"\"\n    else:\n        condense_template = \"\"\"\\n\\nHuman: Using the following conversation, answer friendly for the newest question. If you don't know the answer, just say that you don't know, don't try to make up an answer. You will be acting as a thoughtful advisor.\n\n        {history}\n        \n        Human: {input}\n\n        Assistant:\n        \"\"\"\n    \n    return PromptTemplate.from_template(condense_template)\n```\n\n[ConversationBufferMemory](https://python.langchain.com/docs/modules/memory/types/buffer)을 이용하여 conversation을 정의하고 conversation.predict로 Bedrock으로 요청을 보낼 수 있습니다.\n\n```python\nfrom langchain.chains import ConversationChain\nfrom langchain.memory import ConversationBufferMemory\n\nchat_memory = ConversationBufferMemory(human_prefix='Human', ai_prefix='Assistant')\nconversation = ConversationChain(llm=llm, verbose=False, memory=chat_memory)\n\nconversation.prompt = get_conversation_prompt(text)\nmsg = conversation.predict(input = text)\n```\n\nhistory는 아래와 같이 확인할 수 있습니다.\n\n```python\nchats = chat_memory.load_memory_variables({})\nchat_history_all = chats['history']\nprint('chat_history_all: ', chat_history_all)\n```\n\n\n\n## 문서 요약하기 (Summerization)\n\n### 파일 읽어오기\n\nS3에서 아래와 같이 Object를 읽어옵니다.\n\n```python\ns3r = boto3.resource(\"s3\")\ndoc = s3r.Object(s3_bucket, s3_prefix + '/' + s3_file_name)\n```\n\npdf파일은 PyPDF2를 이용하여 S3에서 직접 읽어옵니다.\n\n```python\nimport PyPDF2\n\ncontents = doc.get()['Body'].read()\nreader = PyPDF2.PdfReader(BytesIO(contents))\n\nraw_text = []\nfor page in reader.pages:\n    raw_text.append(page.extract_text())\ncontents = '\\n'.join(raw_text)    \n```\n\n파일 확장자가 txt이라면 body에서 추출하여 사용합니다.\n```python\ncontents = doc.get()['Body'].read()\n```\n\n파일 확장자가 csv일 경우에는 아래처럼 읽어옵니다.\n\n```python\ndef load_csv_document(s3_file_name):\n    s3r = boto3.resource(\"s3\")\n    doc = s3r.Object(s3_bucket, s3_prefix+'/'+s3_file_name)\n\n    lines = doc.get()['Body'].read().decode('utf-8').split('\\n')   # read csv per line\n    print('lins: ', len(lines))\n        \n    columns = lines[0].split(',')  # get columns\n    #columns = [\"Category\", \"Information\"]  \n    #columns_to_metadata = [\"type\",\"Source\"]\n    print('columns: ', columns)\n    \n    docs = []\n    n = 0\n    for row in csv.DictReader(lines, delimiter=',',quotechar='\"'):\n        # print('row: ', row)\n        #to_metadata = {col: row[col] for col in columns_to_metadata if col in row}\n        values = {k: row[k] for k in columns if k in row}\n        content = \"\\n\".join(f\"{k.strip()}: {v.strip()}\" for k, v in values.items())\n        doc = Document(\n            page_content=content,\n            metadata={\n                'name': s3_file_name,\n                'row': n+1,\n            }\n            #metadata=to_metadata\n        )\n        docs.append(doc)\n        n = n+1\n    print('docs[0]: ', docs[0])\n\n    return docs\n\n```\n\n### 텍스트 나누기 \n\n문서가 긴 경우에 token 크기를 고려하여 아래와 같이 chunk들로 분리합니다. 이후 Document를 이용하여 앞에 3개의 chunk를 문서로 만듧니다.\n\n```python\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain.docstore.document import Document\n\ntext_splitter = RecursiveCharacterTextSplitter(chunk_size = 1000, chunk_overlap = 100)\ntexts = text_splitter.split_text(new_contents)\nprint('texts[0]: ', texts[0])\n\ndocs = [\n    Document(\n        page_content = t\n    ) for t in texts[: 3]\n]\n```\n\n### Template를 이용하여 요약하기\n\nTemplate를 정의하고 [load_summarize_chain](https://sj-langchain.readthedocs.io/en/latest/chains/langchain.chains.summarize.__init__.load_summarize_chain.html?highlight=load_summarize_chain)을 이용하여 summarization를 수행합니다.\n\n```python\nfrom langchain.prompts import PromptTemplate\nfrom langchain.chains.summarize import load_summarize_chain\n\ndef get_summary(texts):    \n    # check korean\n    pattern_hangul = re.compile('[\\u3131-\\u3163\\uac00-\\ud7a3]+') \n    word_kor = pattern_hangul.search(str(texts))\n    print('word_kor: ', word_kor)\n    \n    if word_kor:\n        #prompt_template = \"\"\"\\n\\nHuman: 다음 텍스트를 간결하게 요약하세오. 텍스트의 요점을 다루는 글머리 기호로 응답을 반환합니다.\n        prompt_template = \"\"\"\\n\\nHuman: 다음 텍스트를 요약해서 500자 이내로 설명하세오.\n\n        {text}\n        \n        Assistant:\"\"\"        \n    else:         \n        prompt_template = \"\"\"\\n\\nHuman: Write a concise summary of the following:\n\n        {text}\n        \n        Assistant:\"\"\"\n    \n    PROMPT = PromptTemplate(template=prompt_template, input_variables=[\"text\"])\n    chain = load_summarize_chain(llm, chain_type=\"stuff\", prompt=PROMPT)\n\n    docs = [\n        Document(\n            page_content=t\n        ) for t in texts[:3]\n    ]\n    summary = chain.run(docs)\n    print('summary: ', summary)\n\n    if summary == '':  # error notification\n        summary = 'Fail to summarize the document. Try agan...'\n        return summary\n    else:\n        # return summary[1:len(summary)-1]   \n        return summary\n```\n\n## IAM Role\n\nBedrock의 IAM Policy는 아래와 같습니다.\n\n```java\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Action\": [\n                \"bedrock:*\"\n            ],\n            \"Resource\": \"*\",\n            \"Effect\": \"Allow\",\n            \"Sid\": \"BedrockFullAccess\"\n        }\n    ]\n}\n```\n\n이때의 Trust relationship은 아래와 같습니다.\n\n```java\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"Service\": \"sagemaker.amazonaws.com\"\n            },\n            \"Action\": \"sts:AssumeRole\"\n        },\n        {\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"Service\": \"bedrock.amazonaws.com\"\n            },\n            \"Action\": \"sts:AssumeRole\"\n        }\n    ]\n}\n```\n\nLambda가 Bedrock에 대한 Role을 가지도록 아래와 같이 CDK에서 IAM Role을 생성할 수 있습니다.\n\n```python\nconst roleLambda = new iam.Role(this, \"api-role-lambda-chat\", {\n    roleName: \"api-role-lambda-chat-for-bedrock\",\n    assumedBy: new iam.CompositePrincipal(\n        new iam.ServicePrincipal(\"lambda.amazonaws.com\"),\n        new iam.ServicePrincipal(\"sagemaker.amazonaws.com\"),\n        new iam.ServicePrincipal(\"bedrock.amazonaws.com\")\n    )\n});\nroleLambda.addManagedPolicy({\n    managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole',\n});\n\nconst SageMakerPolicy = new iam.PolicyStatement({  // policy statement for sagemaker\n    actions: ['sagemaker:*'],\n    resources: ['*'],\n});\nconst BedrockPolicy = new iam.PolicyStatement({  // policy statement for sagemaker\n    actions: ['bedrock:*'],\n    resources: ['*'],\n});\nroleLambda.attachInlinePolicy( // add sagemaker policy\n    new iam.Policy(this, 'sagemaker-policy-lambda-chat-bedrock', {\n        statements: [SageMakerPolicy],\n    }),\n);\nroleLambda.attachInlinePolicy( // add bedrock policy\n    new iam.Policy(this, 'bedrock-policy-lambda-chat-bedrock', {\n        statements: [BedrockPolicy],\n    }),\n);    \n```\n\n## 실습하기\n\n### CDK를 이용한 인프라 설치\n\n[인프라 설치](https://github.com/kyopark2014/chatbot-based-on-bedrock-anthropic/blob/main/deployment.md)에 따라 CDK로 인프라 설치를 진행합니다. [CDK 구현 코드](./cdk-bedrock-simple-chatbot/README.md)에서는 Typescript로 인프라를 정의하는 방법에 대해 상세히 설명하고 있습니다.\n\n### 실행결과\n\n\"list models\"를 입력하면 아래와 같이 현재 지원되는 모델리스트를 보여줍니다. \n\n![image](https://github.com/kyopark2014/chatbot-based-on-bedrock-anthropic/assets/52392004/cc7b7c2d-9c11-4e0c-b09c-5fdb8459da0f)\n\n### Titan으로 간단한 질의하기\n\n아래와 같이 이메일 작성을 요청합니다.\n\n```text\nWrite an email from Bob, Customer Service Manager, to the customer \"John Doe\" \nwho provided negative feedback on the service provided by our customer support \nengineer\n```\n\n요청에 맞춰서 적절한 이메일 문장을 생성하였습니다.\n\n![image](https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/assets/52392004/c3d2eb31-28de-451e-9069-3b0400c36d1f)\n\n\n아래와 같이 코드 생성을 요청합니다.\n\n```text\nGenerate and return the code for each module using the programming language and programming framework requested in. Modify this code and return markdowns for each module using the suggestions in: Python Streamlit code for a banking app using DynamoDB\n```\n\n이때의 결과는 아래와 같습니다.\n\n![image](https://github.com/kyopark2014/chatbot-based-on-Falcon-FM/assets/52392004/ed53c663-e035-49dc-9b77-b54dae565cb7)\n\n\n### Claude에서 Conversation 활용하기\n\n\"서울을 여행하고 싶어. 무엇을 타고 여행하는것이 좋을까?\"라고 입력하면 서울의 정보를 알려줍니다.\n\n![image](https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/assets/52392004/67983108-42dc-4af4-a90e-be4474482cb5)\n\n대명사를 이용해 \"그럼 그 도시에서 지하철 요금은 얼마야?\"라고 문의하면 서울 지하철 요금을 알려줍니다. Conversation이 정상적으로 동작함을 알수 있습니다.\n\n![image](https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/assets/52392004/faa76655-e75b-440b-87f0-0382a2e3c9f5)\n\n서울, 지하철을 넣지 않고 \"그럼 환승도 가능해?\"로 물었을때 아래와 같이 이전 대화이력(chat history)을 이용하여 서울 지하철의 환승에 대해 설명하여 줍니다.\n\n![image](https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/assets/52392004/7d7bcabc-e0bd-472a-82ee-78f0a06698e8)\n\n\n\n## 브라우저에서 Chatbot 동작 시험시 주의할점\n\nChatbot API를 테스트하기 위해 제공하는 Web client는 일반적인 채팅 App처럼 세션 방식(web socket등)이 아니라 RESTful API를 사용합니다. 따라서 LLM에서 응답이 일정시간(30초)이상 지연되는 경우에 답변을 볼 수 없습니다. 이때 응답을 확인하기 위해서는 CloudWatch에서 [lambda-chat](./lambda-chat/lambda_function.py)의 로그를 확인하거나, DynamoDB에 저장된 call log를 확인합니다.\n\n\n## Debugging\n\n아래와 같이 [test.py](./lambda-chat/test.py)를 이용하여 local에서 컨테이너 이미지를 디버깅할 수 있습니다. 먼저 아래와 같이 이미지를 빌드합니다.\n\n```text\ndocker build -t lambda_function-test:v1 .\n```\n\nDocker를 실행합니다.\n```text\ndocker run -d -p 8080:8080 lambda_function-test:v1\n```\n\n아래와 같이 \"docker ps\"명령어로 Container ID를 확인 할 수 있습니다.\n```text\nCONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                    NAMES\n41e297948511   inference:v1   \"/lambda-entrypoint.…\"   6 seconds ago   Up 4 seconds   0.0.0.0:8080-\u003e8080/tcp   stupefied_carson\n```\n\n아래와 같이 Bash shell로 접속합니다.\n```text\ndocker exec -it  41e297948511 /bin/bash\n```\n\nContainer 접속 후 아래 명령어로 동작을 확인합니다.\n\n```text\ncd .. \u0026\u0026 python3 test.py\n```\n\n\u003c!--\n### TroubleShooting: Too many request\n\n현재 Bedrock은 Preview이어서, 너무 많은 요청을 하면 ThrottlingException이 발생합니다.\n\n```python\n[ERROR] ValueError: Error raised by bedrock service: An error occurred (ThrottlingException) when calling the InvokeModel operation (reached max retries: 4): Too many requests, please wait before trying again. You have sent too many requests.  Wait before trying again.\nTraceback (most recent call last):\n  File \"/var/task/lambda_function.py\", line 236, in lambda_handler\n    msg = get_answer_using_chat_history(text, chat_memory)\n  File \"/var/task/lambda_function.py\", line 121, in get_answer_using_chat_history\n    result = llm(CONDENSE_QUESTION_PROMPT.format(question=query, chat_history=chat_history))\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/base.py\", line 825, in __call__\n    self.generate(\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/base.py\", line 621, in generate\n    output = self._generate_helper(\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/base.py\", line 523, in _generate_helper\n    raise e\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/base.py\", line 510, in _generate_helper\n    self._generate(\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/base.py\", line 1000, in _generate\n    self._call(prompt, stop=stop, run_manager=run_manager, **kwargs)\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/bedrock.py\", line 217, in _call\n    text = self._prepare_input_and_invoke(prompt=prompt, stop=stop, **kwargs)\n  File \"/var/lang/lib/python3.11/site-packages/langchain/llms/bedrock.py\", line 150, in _prepare_input_and_invoke\n    raise ValueError(f\"Error raised by bedrock service: {e}\")\n```\n\n### DynamoDBChatMessageHistory\n\nLangChain의 DynamoDBChatMessageHistory을 이용해 [구현](https://github.com/kyopark2014/simple-chatbot-using-LLM-based-on-amazon-bedrock/blob/main/chat-history-dynamo.md)해 보았으나, 이전 채팅이력을 읽어올수 없는 구조여서 사용하지 않았습니다. DynamoDB에 저장할때에도 포맷을 변경할 수 없어서 사용성이 안좋습니다.\n--\u003e\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyopark2014%2Fsimple-chatbot-using-llm-based-on-amazon-bedrock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkyopark2014%2Fsimple-chatbot-using-llm-based-on-amazon-bedrock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyopark2014%2Fsimple-chatbot-using-llm-based-on-amazon-bedrock/lists"}