Skip to content

Commit 1108a01

Browse files
committed
placeholder
1 parent 1f91fb6 commit 1108a01

File tree

2 files changed

+219
-27
lines changed

2 files changed

+219
-27
lines changed
Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,56 @@
1-
# Voice transcript to blog post
1+
# Voice Transcript to Blog Post
22

33
I am providing you with a voice transcript intended to become a blog post about
44
code. Please organize the content into a clear and polished markdown document.
55
Follow these guidelines strictly:
66

7-
1. **Structure:**
8-
- Include a title as the only heading in the markdown file, using `#` (H1).
9-
- Do not add subheadings (no H2, H3, etc.).
7+
## 1. Structure
108

11-
2. **Editing Rules:**
12-
- Correct grammar and vocabulary while preserving my tone and voice as much
13-
as possible.
14-
- Reorganize and optimize the content to ensure clarity and flow, avoiding
15-
redundancy.
16-
- Do not invent or add content that isn't implied or directly stated in the
17-
transcript.
9+
- Include a title as the only heading in the markdown file, using `#` (H1).
10+
- Do not add subheadings (no H2, H3, etc.).
1811

19-
3. **Placeholders:**
20-
- If I mention a placeholder for code (e.g., “Insert a placeholder here for
21-
code”), include a clear markdown comment (e.g.,
22-
`<!-- Code placeholder: Add example here -->`) in the relevant part of the
23-
text.
12+
## 2. Editing Rules
2413

25-
4. **Conclusion:**
26-
- End the blog post with a simple, conversational concluding sentence. For
27-
example: “That's it. Let me know if you have any questions. Thanks for
28-
reading.” Do not add additional automated-sounding conclusions.
14+
- Correct grammar and vocabulary while preserving my tone and voice as much as
15+
possible.
16+
- Reorganize and optimize the content to ensure clarity and flow, avoiding
17+
redundancy.
18+
- Do not invent or add content that isn't implied or directly stated in the
19+
transcript.
2920

30-
5. **Markdown Format:**
31-
- Ensure the output is in valid markdown with clean formatting.
21+
## 3. Lists
3222

33-
Please focus on keeping the content organized, improving readability, and
34-
aligning with the tone and intent of my original voice transcript. Do not add
35-
any subheadings or embellishments beyond what is specified.
23+
- If the voice transcript contains a list, format it as a markdown list.
24+
- Do not overuse bold text. Only use it when absolutely necessary for emphasis.
25+
26+
## 4. Placeholders
27+
28+
- If a placeholder is mentioned (e.g., placeholder here for code”), include a
29+
clear markdown comment:
30+
```markdown
31+
<!-- Code placeholder: Add example here -->
32+
```
33+
- If a simple example can be inferred, provide a single-line code snippet along
34+
with the placeholder:
35+
```markdown
36+
<!-- Code placeholder: Add example here -->
37+
```
38+
```python
39+
print("Hello, world!")
40+
```
41+
42+
## 5. Conclusion
3643

37-
**Transcript:**\
38-
[Insert the transcript here]
44+
- End the blog post with a simple, conversational concluding sentence. Example:\
45+
_"That's it. Let me know if you have any questions. Thanks for reading."_
46+
- Do not add automated-sounding conclusions or summaries.
47+
48+
## 6. Markdown Output
49+
50+
- Ensure the output is valid markdown with clean formatting.
51+
- Do **not** include any additional text, explanations, or formatting outside of
52+
markdown.
53+
54+
Please focus on keeping the content organized, improving readability, and
55+
aligning with the tone and intent of my original voice transcript. Keep the
56+
casual and natural tone intact while refining the structure.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
## Using LLMs to Convert Natural Language Queries into Structured Queries
2+
3+
### Context
4+
5+
Over the past year, I have been working on building an application platform that
6+
supports searching through OpenStreetMap data via an API endpoint and an
7+
embedded JavaScript runtime into Golang.
8+
9+
The idea behind that interface is to minimize the amount of data and round trips
10+
that need to be done from a client interface. Client-side JavaScript can be
11+
passed to server-side JavaScript for a very subset use case, which is querying
12+
and collating geospatial points of interest from OpenStreetMap.
13+
14+
[Placeholder for a link to that blog post.]
15+
16+
I have documentation for my query language, but what I found was that it
17+
required a lot of domain knowledge related to how OpenStreetMap tags may be used
18+
to identify a place.
19+
20+
For example, an OpenStreetMap gas station could be marked as `store=convenience`
21+
or `amenity=gas` or might have neither or only one of them. Discovering those
22+
tags to help search led me to try to expose that information in different ways.
23+
24+
Initially, I thought about creating an endpoint that returns information about
25+
all the tags. However, I found that there was a lot of noise in the tags, making
26+
it difficult to present the data in a human-readable and usable way. There can
27+
be tens of thousands, if not hundreds of thousands, of tags with multiple values
28+
for each.
29+
30+
### Initial Approach
31+
32+
I wanted to take a different approach: Could I have something that converted a
33+
user's query, such as "grocery store," and mapped it to predefined tags?
34+
35+
I built an interface where I predetermined a categorization of tags, covering
36+
common amenities for real estate searches such as police stations, gas stations,
37+
schools, and hospitals.
38+
39+
[Placeholder for a link to that interface.]
40+
41+
This allowed users to input an address, which would use an element from the
42+
Mapbox SDK to return latitude and longitude. I could then use predefined
43+
categorizations to find nearby points of interest.
44+
45+
However, this approach was limited. It only allowed predefined categories to be
46+
shown, restricting the scope of discovery. For example, what if someone wanted
47+
to exclude mainstream coffee shops to find local businesses? This would require
48+
maintaining a list of coffee shops to exclude or providing an exclusion
49+
mechanism for users—making the interface complex.
50+
51+
### Experimenting with LLMs
52+
53+
Given these limitations, I explored the possibility of using a Large Language
54+
Model (LLM) to process natural language queries and convert them into structured
55+
queries.
56+
57+
I started by experimenting with ChatGPT, manually testing prompts. My initial
58+
prompt was:
59+
60+
> "You will be given a user query in natural language and return structured JSON
61+
> representing the OpenStreetMap tags that correspond to the query."
62+
63+
Example query:
64+
65+
> "Find me coffee shops in my neighborhood."
66+
67+
[Placeholder for what ChatGPT initially returned.]
68+
69+
The results were promising but lacked structure. So, I defined a schema for the
70+
expected JSON output and refined my prompt:
71+
72+
> "Given a user's query in natural language, return OpenStreetMap tags in a JSON
73+
> format. Here is an example of the expected output."
74+
75+
Example query:
76+
77+
> "What coffee shops are in my neighborhood?"
78+
79+
[Placeholder for expected JSON output.]
80+
81+
[Placeholder for an example with ChatGPT’s result.]
82+
83+
### Integrating LLMs into My Application
84+
85+
With structured JSON working, I incorporated it into my application—a text box
86+
where users could describe their desired neighborhood, and it would return
87+
points of interest on a map.
88+
89+
However, I encountered new challenges:
90+
91+
- **Scoping queries:** My database was structured by states and Canadian
92+
provinces. Users had to specify these areas, which broke the natural language
93+
flow.
94+
- **Teaching an LLM my custom query language:** My query language allowed
95+
substring matching, range limits, and directives to scope searches.
96+
97+
To address these issues, I documented my query language, detailing syntax and
98+
examples.
99+
100+
[Placeholder for link to query syntax documentation.]
101+
102+
I then asked ChatGPT to refine my prompt:
103+
104+
> "Here’s documentation on my query language. Help me write a prompt that
105+
> ensures you understand it."
106+
107+
[Placeholder for shortened example of refined prompt.]
108+
109+
### Enhancing Query Accuracy
110+
111+
To improve accuracy, I identified meaningful OpenStreetMap tags by researching
112+
community discussions and manually curating a list of about 50 high-value tags
113+
(e.g., shops, amenities, roads, schools, parks). I then asked ChatGPT:
114+
115+
> "Here's a list of 50 OpenStreetMap tags for describing a neighborhood. Can you
116+
> extend it for better specificity?"
117+
118+
It suggested 120 tags, of which 15 were incorrect. After review, I refined the
119+
list and incorporated it into the LLM prompt:
120+
121+
> "If looking for OpenStreetMap tags, use these as a guide, but feel free to use
122+
> others."
123+
124+
Testing showed that responses were now more specific. For example:
125+
126+
> "Find coffee shops that are not mainstream."
127+
128+
[Placeholder for resulting query JSON.]
129+
130+
### Handling Geographic Areas
131+
132+
To improve area selection, I extended the JSON output schema to include multiple
133+
areas. Instead of requiring users to select one state, I allowed descriptions
134+
like "Southwestern states" to infer multiple areas.
135+
136+
[Placeholder for a query that includes southwestern states.]
137+
138+
### Optimizing Performance
139+
140+
While my implementation worked, optimizations were necessary:
141+
142+
1. **Fine-Tuning the Model**
143+
- I converted example prompts and expected outputs into fine-tuning data.
144+
- I asked ChatGPT to generate additional examples, reviewed them, and removed
145+
incorrect ones.
146+
- I fine-tuned a GPT-4 model with 30+ examples to improve performance.
147+
- Results: A slight performance boost and more accurate outputs.
148+
149+
2. **Providing Output Prediction**
150+
- OpenAI's API allows defining an expected output structure.
151+
- I used this feature to ensure JSON output consistency.
152+
153+
[Placeholder for OpenAI API link about this feature.]
154+
155+
3. **Leveraging Prompt Caching**
156+
- OpenAI caches prompts for faster response times, reducing costs.
157+
- This ensured my long prompt wasn't reprocessed on every request.
158+
159+
4. **Limiting Token Usage**
160+
- I capped JSON output to 300 tokens and limited user input to 300
161+
characters.
162+
- This prevented excessive API costs and safeguarded against abuse.
163+
164+
### Conclusion
165+
166+
By integrating OpenStreetMap data with LLMs, I enabled users to query geospatial
167+
data using natural language. The system supports filtering, distance
168+
constraints, and negations, making searches more intuitive.
169+
170+
[Placeholder for a link to the neighborhood search demo.]
171+
172+
This approach remains **best effort**—not perfect, but continually improving. I
173+
plan to refine results through fine-tuning and ongoing user feedback to enhance
174+
accuracy and usability.

0 commit comments

Comments
 (0)