# Building ReAct RAG

**URL:** <https://forum.langchain.com/t/building-react-rag/436>\
**Category:** LangGraph\
**Tags:** python-help\
**Created:** [July 14, 2025, 11:03am UTC](https://forum.langchain.com/t/building-react-rag/436 "2025-07-14T11:03:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![JarredR092699](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jarredr092699/32/154_2.png) [@JarredR092699](https://forum.langchain.com/u/JarredR092699)\
**Post date:** [July 14, 2025, 11:03am UTC](https://forum.langchain.com/t/building-react-rag/436/1 "2025-07-14T11:03:09Z")

</div>

Hi all.

I have been experimenting with the prebuilt agents recently and tried to improve the efficiency of my RAG chatbot by making the retrieval part of tools that an LLM can use.

Is this best practice?

 ![Screenshot 2025-07-14 at 6.59.04 AM](https://canada1.discourse-cdn.com/flex007/uploads/langchain/original/1X/b0d60cd46c4830f5a1415a5f99ba8c70c91a8b5d.png)

I guess the way I compiled the workflow, I have two starts and ends haha.

My second question revolves around why my input value from the graph view is always {}. Even when declaring my state as messages, it shows up like this which makes it hard for me to run evals.

Appreciate any insight.

Thanks guys!

---

<div class="post-metadata">

**Author:** ![eyurtsev](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/eyurtsev/32/125_2.png) [@eyurtsev](https://forum.langchain.com/u/eyurtsev)\
**Post date:** [July 14, 2025, 6:52pm UTC](https://forum.langchain.com/t/building-react-rag/436/2 "2025-07-14T18:52:23Z")

</div>

You’re essentially building an **Agentic RAG** system, where the retrieval step is abstracted into tools the LLM can call. In this setup, the LLM acts as the agent and decides whether, when, and how to retrieve external information. This is a valid and increasingly popular approach, especially in cases where retrieval isn’t always necessary or when multiple queries might improve the result quality.

However, it’s not the only way to implement RAG. Other strategies include:

- **Single-step retrieval** , where retrieval is performed before the LLM sees any context and the results are injected directly into the prompt.
- **Orchestrated pipelines** , where retrieval and generation are clearly separated stages in a workflow.

### On “Best Practice”

“Best” depends on what **efficiency** means in your context. Are you optimizing for:

- **Latency** (response time)?
- **Cost** (number of tool calls)?
- **Accuracy or quality** of the final response?
- **Simplicity or maintainability** of your architecture?

For instance, Agentic RAG can support additional reasoning like validating retrieved content or retrying bad results, but it introduces complexity and potential cost. If you’re aiming for predictable cost and performance, a simpler, non-agentic RAG might suit better.

Also, **retrieval quality** matters greatly. Key factors include:

- Retrieval method (vector vs keyword search)
- Embedding model quality
- Chunking strategy and tokenizer behavior
- Scoring and filtering logic

These can dramatically impact downstream response quality, regardless of the RAG type.

---

<div class="post-metadata">

**Author:** ![atc](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/atc/32/1610_2.png) [@atc](https://forum.langchain.com/u/atc)\
**Post date:** [July 14, 2025, 10:30pm UTC](https://forum.langchain.com/t/building-react-rag/436/3 "2025-07-14T22:30:35Z")

</div>

@JarredR092699 for your question regarding why the input value in LangGraph Studio always shows {}, someone asked a similar question in the Slack community and I answered it [here](https://forum.langchain.com/t/supervisor-example-questions/273) (question #3). In short, the first node should accept a `BaseMessage` or some other type that can accept string as the input.

---

<div class="post-metadata">

**Author:** ![JarredR092699](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jarredr092699/32/154_2.png) [@JarredR092699](https://forum.langchain.com/u/JarredR092699)\
**Post date:** [July 15, 2025, 1:31am UTC](https://forum.langchain.com/t/building-react-rag/436/4 "2025-07-15T01:31:35Z")

</div>

im still confused because even when my state looks like this

```auto
class State(OverallState):
    messages: BaseMessage 

```

I get the {} JSON indicator

---

<div class="post-metadata">

**Author:** ![eyurtsev](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/eyurtsev/32/125_2.png) [@eyurtsev](https://forum.langchain.com/u/eyurtsev)\
**Post date:** [July 15, 2025, 1:50am UTC](https://forum.langchain.com/t/building-react-rag/436/5 "2025-07-15T01:50:13Z")

</div>

Try this:

```python
from langchain_core.messages import BaseMessage
from langgraph.graph.messages import add_messages

class MessagesState(TypedDict):
    messages: Annotated[list[BaseMessage], add_messages]

```

- Messages should be a list of messages
- You will likely want to specify the add\_messages [reducer](https://langchain-ai.github.io/langgraph/concepts/low_level/#reducers)

Studio is likely interpreting BaseMessage as an object and giving you an option of filling it in as a dict `{}`

---

<div class="post-metadata">

**Author:** ![atc](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/atc/32/1610_2.png) [@atc](https://forum.langchain.com/u/atc)\
**Post date:** [July 15, 2025, 3:37pm UTC](https://forum.langchain.com/t/building-react-rag/436/6 "2025-07-15T15:37:25Z")

</div>

Or I think you could just add a `List` to your `BaseMessage` like this:

```auto
class State(OverallState):
    messages: List[BaseMessage]
```
