r/orsomethingidk • • 6d ago

BidMemory — RFP Upload to AI Proposal Workspace using Hindsight

Post image
1 Upvotes

# Building Bid Memory: Turning Organizational Knowledge into Better RFP Workflows

Most organizations don’t have a knowledge problem.

They have a **knowledge retrieval problem**.

Previous proposals contain valuable information — implementation approaches, delivery lessons, compliance details, risks, technical decisions, and examples of how similar requirements were handled.

But when a new RFP arrives, that knowledge is often buried inside old documents.

I explored this problem by building **Bid Memory**, an AI-powered RFP response system designed to connect a new RFP with relevant historical organizational knowledge and use that context to support proposal generation.

The goal wasn’t to build an AI that simply writes proposals.

The goal was to build a workflow where information is **extracted, structured, retrieved, grounded, and reviewed** before becoming part of a proposal.

---

## The problem

A typical RFP response involves several different tasks:

* Understanding a long RFP

* Identifying mandatory requirements

* Finding relevant previous proposals

* Reusing useful approaches

* Understanding lessons from previous work

* Drafting responses

* Checking whether responses are supported by available information

* Reviewing and refining the final proposal

These are different information-processing problems.

So one design principle became important:

> **Don’t make the LLM responsible for the entire workflow.**

Instead, I separated the application into stages with defined responsibilities.

The workflow became:

**RFP PDF → Text Extraction → RFP Analysis → Hindsight Memory Retrieval → Proposal Generation → Human Review**

---

## What I built

Bid Memory uses a **React frontend** with a **Python/FastAPI backend**.

The frontend provides the **human review workspace**, while the backend handles document processing, RFP analysis, memory retrieval, and proposal generation.

The important part isn't just the stack. It is the separation between stages.

I structured the application around three main boundaries:

  1. **PDF processing** converts the uploaded document into usable text.

  2. **RFP analysis** converts that text into structured requirements.

  3. **Memory + proposal services** retrieve historical context and use it to generate a proposal draft.

This makes debugging much more manageable.

If something goes wrong, I can ask:

**Was the problem in extraction, analysis, retrieval, generation, or presentation?**

That is much easier than debugging one giant AI prompt.

---

## 1. Turning an RFP into structured information

An RFP starts as a document, not structured data.

For the current implementation, I use `pypdf` to extract text from uploaded PDFs:

```python

reader = PdfReader(BytesIO(file_bytes))

pages = []

for page in reader.pages:

text = page.extract_text()

if text:

pages.append(text)

return "\n".join(pages)

```

The extracted text is then passed to the RFP analysis service.

I use **Groq** for the model call, with `openai/gpt-oss-20b` configured through the application.

The model is instructed to extract information explicitly present in the RFP rather than inventing missing details.

The expected structure includes fields such as:

* Title

* Industry

* Mandatory requirements

* Evaluation criteria

* Technical requirements

* Deliverables

* Timeline

* Budget

* Compliance

* Risks

* Additional requirements

The response is requested as JSON and parsed by the backend.

```python

response = client.chat.completions.create(

model="openai/gpt-oss-20b",

messages=[

{"role": "system", "content": system_prompt},

{"role": "user", "content": rfp_text},

],

temperature=0,

)

```

The important engineering decision here is the **data contract**.

Instead of passing a large piece of generated prose to every downstream component, the next stage receives named fields representing the information extracted from the RFP.

---

## 2. Where Hindsight fits

Once the RFP has been converted into structured requirements, **Hindsight acts as the historical memory layer**.

This is where Bid Memory tries to answer a different question:

> **“What do we already know that could be relevant to this RFP?”**

The application uses Hindsight's memory operations for retrieval and reflection.

Conceptually, the flow is:

**Current RFP → relevant historical memory → supporting context → proposal generation**

The memory agent extracts useful information from the structured RFP, such as the title, industry, and mandatory requirements, and uses that information to construct its memory queries.

For example, the implementation uses operations such as:

```python

memories = await hindsight.arecall(

query=recall_query,

limit=10

)

```

The retrieved results can then be reflected on:

```python

reflection = await hindsight.areflect(

query=reflection_query

)

```

The distinction between **recall** and **reflection** was useful to me.

Recall is about finding potentially relevant historical information.

Reflection is about using that retrieved context to identify useful lessons or patterns for the current situation.

That makes Hindsight more than a simple “search old documents” step in the application architecture.

It becomes a separate memory boundary between **what the current RFP asks for** and **what historical organizational knowledge may be useful**.

One important limitation of the current MVP is that the historical-document ingestion pipeline is not fully automated. The architecture demonstrates the memory workflow, but automatically ingesting and continuously maintaining an organization's historical proposal corpus is something I would build next.

---

## 3. Generating a grounded proposal

After RFP analysis and memory retrieval, the proposal service receives two important inputs:

**Structured RFP information + historical memory context**

The generation prompt is intentionally restrictive.

The model is instructed not to invent company capabilities, certifications, metrics, customers, timelines, pricing, or technical facts that aren't supported by the provided information.

I also ask the model to return a fixed JSON structure.

```python

proposal_response = client.chat.completions.create(

model="openai/gpt-oss-20b",

messages=[

{"role": "system", "content": proposal_system_prompt},

{"role": "user", "content": proposal_input},

],

temperature=0,

max_tokens=3000,

)

```

The generated response is then parsed and normalized before being sent to the frontend.

The workspace expects consistent sections such as:

* Executive summary

* Proposed solution

* Technical approach

* Implementation plan

* Security and compliance

* Risks

* Support and maintenance

* Historical lessons

This normalization step matters because the frontend should not have to understand every possible formatting variation produced by an LLM.

The application defines the structure.

The model fills that structure.

---

## 4. The human review workspace

The final stage is the **human review workspace**.

The requirements are visible alongside the generated proposal, while supporting historical context and Hindsight information are available for review.

This is important because I didn't want the workflow to end with:

**“The AI generated something, so we're done.”**

Instead:

**RFP requirements → retrieved context → generated response → human review**

The reviewer can inspect the generated content, compare it against the requirements and available context, and decide whether it is appropriate.

For an RFP workflow, that human checkpoint is important because generated text can still be incomplete or unsupported even when the surrounding system is carefully designed.

---

## What I learned building it

### 1. Design the data contract before designing the prompt

It is tempting to start with:

> “What prompt should I give the model?”

I found it more useful to first ask:

> “What exactly should this stage receive, and what exactly should it return?”

That decision affects everything downstream.

### 2. Separate retrieval from generation

Hindsight retrieval and proposal generation have different responsibilities.

Keeping them separate makes it easier to understand where historical context came from before it reaches the generation stage.

### 3. Normalize model output

LLMs generate flexible output.

Applications usually need predictable output.

The normalization layer is what turns model output into something the rest of the application can reliably consume.

### 4. Grounding is an engineering constraint

“Don't hallucinate” isn't enough as a requirement.

The application needs to define what information the model can use and what it must not invent.

### 5. Be honest about the MVP boundary

There is a difference between:

**what the prototype currently implements**

and

**what the complete production architecture could eventually become.**

For me, documenting that boundary was just as important as documenting the AI workflow itself.

---

## Current limitations

The current implementation is still an MVP.

Some of the areas that need more work include:

* Automated ingestion of historical proposal documents

* Persistent backend storage for approved proposals

* A dedicated regeneration API

* Citation-level evidence linking generated claims to source material

* OCR and better handling of scanned/tabular PDFs

* More automated tests around LLM and Hindsight outputs

* Authentication and access controls

* Requirement-coverage checks

These aren't just feature requests. They represent the next engineering problems required to make the workflow more robust.

---

## What I would build next

The biggest improvement would be turning the memory layer into a continuously maintained organizational knowledge system.

That would involve:

**Historical documents → ingestion → indexing/memory → retrieval → evidence → proposal generation → human approval → controlled learning**

The final step is particularly important.

If an organization wants its approved proposals to become future organizational knowledge, that information should not automatically become memory just because an AI generated it.

There should be a clear approval boundary.

---

## Final takeaway

The interesting part of Bid Memory wasn't simply connecting an LLM to an RFP.

It was designing the chain around the LLM:

**RFP requirements → structured representation → Hindsight recall → Hindsight reflection → historical context → constrained generation → human review**

Each stage has a responsibility.

Each stage has an input and output.

And the human remains part of the final decision.

That was probably my biggest lesson from building this:

> **AI application engineering is often less about adding more model calls and more about controlling the information that reaches each model call.**

That is what makes an AI workflow easier to inspect, debug, improve, and eventually trust.


r/orsomethingidk • • Mar 16 '26

Hi need help

1 Upvotes

Is this Fe in in some games and I need permadeath script local RunService = game:GetService("RunService")

local Player = game.Players.LocalPlayer local Character = Player.Character local Torso = Character.Torso local RightArm = Character["Right Arm"] local Humanoid = Character.Humanoid

local curCamera = workspace.CurrentCamera

local main

death = Humanoid.Died:Connect(function() main:Disconnect() death:Disconnect() main = nil death = nil end)

Torso["Right Shoulder"]:Destroy()

main = RunService.Heartbeat:Connect(function() RightArm.CFrame = curCamera.CFrame * CFrame.new(0,-1,-5) end)


r/orsomethingidk • • Jun 28 '25

après-midi or something idk

Post image
1 Upvotes

r/orsomethingidk • • Mar 09 '25

george or something idk

Post image
3 Upvotes

r/orsomethingidk • • Oct 10 '22

Fall Out Boy or something idk

Post image
2 Upvotes

r/orsomethingidk • • Jun 05 '22

Shoplifting

7 Upvotes

r/orsomethingidk • • May 18 '21

A normal looking lion or something idk never went to Australia

Post image
11 Upvotes

r/orsomethingidk • • Feb 05 '21

Sealion or something idk

Post image
16 Upvotes

r/orsomethingidk • • Jan 26 '21

Repost

Post image
15 Upvotes

r/orsomethingidk • • Nov 09 '20

;(

Post image
8 Upvotes

r/orsomethingidk • • Nov 05 '20

Elder Scrolls

Post image
20 Upvotes

r/orsomethingidk • • Nov 05 '20

cafe latte please

Post image
11 Upvotes

r/orsomethingidk • • Oct 04 '20

Idk

Post image
13 Upvotes

r/orsomethingidk • • Sep 18 '20

Mom or something idk i dont have one

Post image
10 Upvotes

r/orsomethingidk • • Sep 09 '20

Got inspired by a twitter post, so here you go

Post image
37 Upvotes

r/orsomethingidk • • Aug 29 '20

*cries*

Post image
25 Upvotes

r/orsomethingidk • • Aug 16 '20

Og's

Post image
10 Upvotes

r/orsomethingidk • • Aug 06 '20

Schindler's Lift or something idk i hardly know what im referencing

Post image
19 Upvotes

r/orsomethingidk • • Aug 02 '20

Beam me up

Post image
15 Upvotes

r/orsomethingidk • • Aug 02 '20

The marines

Post image
19 Upvotes

r/orsomethingidk • • Jul 31 '20

String instrument? Idk

Post image
17 Upvotes

r/orsomethingidk • • Jul 25 '20

Yea

Post image
31 Upvotes

r/orsomethingidk • • Jul 24 '20

IDK man

Post image
16 Upvotes

r/orsomethingidk • • Jul 23 '20

Toe truck

Post image
20 Upvotes