기존에는 Reason 과 Act를 별개로 연구해왔음


o: 관찰, a: 행동


Action 공간을 L(언어 공간)으로 확장: “Thought” or “Reasoning Trace”

HotPotQA, FEVER → Wikipedia 문서를 통해 추론하여 응답해야하는 과제
Thought(생각)-Action(행동)-Observation(관찰)
ReAct의 추론 형식 경로 예시를 만들어놓고, 무작위 샘플(HotpotQA 6개, FEVER 3개) 로 Few-shot

ReAct 내의 단계는 7단계, 5단계 이상 넘어가도 성능 향상을 발견하지 못함
CoT-SC (여러개의 CoT를 설정해 답을 내어 보고, 다수결로 답 결정)
ReAct
외부 지식 기반 → Fact
but 적절한 다음 행동 못찾고 루프에 빠져버리는 오류
유익하지 않은 검색하는 오류 (결국에 우리가 RAG에서 해결해야 할 문제가 아닐까..)

3,000개 예제만 학습. 62B 로도 540B 능가

AlfWorld(텍스트 기반 게임 형식 데이터셋), WebShop(원하는 스펙에 맞는 상품을 찾는 과제)
from langchain_community.vectorstores import Chroma
from langchain_community.document_loaders import PyPDFium2Loader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
embedding_function = OpenAIEmbeddings()
loader = PyPDFium2Loader("국가안전시스템 개편 종합대책 대국민 보고(12.31. 기준).pdf")
documents = loader.load()
documents
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30)
docs = text_splitter.split_documents(documents)
docs
db = Chroma.from_documents(docs, embedding_function)
from langchain_community.vectorstores import Chroma
from langchain.agents.agent_toolkits import create_retriever_tool
from langchain.agents import tool
chroma_retriever = db.as_retriever(search_type="mmr", search_kwargs={"k": 2})
retriever_tool = create_retriever_tool(
chroma_retriever,
name="doc_search",
description="답변을 위한 정보를 담은 문서를 찾아옵니다.",
)
@tool
def calculate_score(input: float) -> int:
'''Score committe counts'''
return float(input) * 10
tools = [retriever_tool, calculate_score]
# from langchain import hub
# prompt = hub.pull("hwchase17/react-json")
# prompt
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, PromptTemplate
prompt = ChatPromptTemplate(input_variables=['agent_scratchpad', 'input', 'tool_names', 'tools'], metadata={'lc_hub_owner': 'hwchase17', 'lc_hub_repo': 'react-json', 'lc_hub_commit_hash': '669cf4d6988c3b8994a8189edb3891e07948e1c0abfd500823914548c53afa7c'}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['tool_names', 'tools'], template='Answer the following questions as best you can in Korean. You have access to the following tools:\n\n{tools}\n\nThe way you use the tools is by specifying a json blob.\nSpecifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n\nThe only values that should be in the "action" field are: {tool_names}\n\nThe $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n\n```\n{{\n "action": $TOOL_NAME,\n "action_input": $INPUT\n}}\n```\n\nALWAYS use the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction:\n```\n$JSON_BLOB\n```\nObservation: the result of the action\n... (this Thought/Action/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin! Reminder to always use the exact characters `Final Answer` when responding.')), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], template='{input}\n\n{agent_scratchpad}'))])
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o", temperature=0.2)
from langchain.agents import AgentExecutor, create_react_agent
from langchain.agents.output_parsers import ReActJsonSingleInputOutputParser
from langchain.tools.render import render_text_description_and_args
runAgent = create_react_agent(
llm,
tools,
prompt,
tools_renderer=render_text_description_and_args,
output_parser=ReActJsonSingleInputOutputParser(),
)
# from langchain.agents import create_openai_functions_agent
# agent = create_openai_functions_agent(llm, tools, prompt)
# agent
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=runAgent, tools=tools, verbose=True, handle_parsing_errors=True)
response = agent_executor.invoke({"input": "119 구급 스마트시스템 개발·운영을 시작한 년도의 시군구 지역안전관리위원회 개최 횟수 점수는? "})
response