add structured output
This commit is contained in:
parent
244ad91cb2
commit
3cfca905c9
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Structured Output Demo
|
||||||
|
|
||||||
|
A minimal demo application showing how to use PocketFlow to extract structured data from a resume using direct prompting and YAML formatting.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Extracts structured data using prompt engineering
|
||||||
|
- Validates output structure before processing
|
||||||
|
|
||||||
|
## Run It
|
||||||
|
|
||||||
|
1. Make sure your OpenAI API key is set:
|
||||||
|
```bash
|
||||||
|
export OPENAI_API_KEY="your-api-key-here"
|
||||||
|
```
|
||||||
|
Alternatively, you can edit the `utils.py` file to include your API key directly.
|
||||||
|
|
||||||
|
2. Edit data.txt with the resume you want to parse (a sample resume is already included)
|
||||||
|
|
||||||
|
3. Install requirements and run the application:
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
parser[ResumeParserNode]
|
||||||
|
```
|
||||||
|
|
||||||
|
The Resume Parser application uses a single node that:
|
||||||
|
1. Takes resume text from the shared state (loaded from data.txt)
|
||||||
|
2. Sends the resume to an LLM with a prompt that requests YAML formatted output
|
||||||
|
3. Extracts and validates the structured YAML data
|
||||||
|
4. Outputs the structured result
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- [`main.py`](./main.py): Implementation of the ResumeParserNode
|
||||||
|
- [`utils.py`](./utils.py): LLM utilities
|
||||||
|
- [`data.txt`](./data.txt): Sample resume text file
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
=== STRUCTURED RESUME DATA ===
|
||||||
|
|
||||||
|
name: John Smith
|
||||||
|
email: johnsmtih1983@gnail.com
|
||||||
|
experience:
|
||||||
|
- title: Sales Manager
|
||||||
|
company: ABC Corporation
|
||||||
|
- title: Assistant Manager
|
||||||
|
company: XYZ Industries
|
||||||
|
- title: Customer Service Representative
|
||||||
|
company: Fast Solutions Inc
|
||||||
|
skills:
|
||||||
|
- Microsoft Office: Excel, Word, PowerPoint (Advanced)
|
||||||
|
- Customer relationship management (CRM) software
|
||||||
|
- Team leadership & management
|
||||||
|
- Project management
|
||||||
|
- Public speaking
|
||||||
|
- Time management
|
||||||
|
|
||||||
|
============================
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
# JOHN SMTIH
|
||||||
|
|
||||||
|
**Email:** johnsmtih1983@gnail.com
|
||||||
|
**Phone:** (555) 123-4556
|
||||||
|
**Address:** 123 Main st, Anytown, USA
|
||||||
|
|
||||||
|
## PROFFESIONAL SUMMARY
|
||||||
|
|
||||||
|
Dedicated and hardworking professional with over 10 years of exprience in business manegement. Known for finding creatve solutions to complex problems and excelent communication skills. Seeking new opportunites to leverage my expertise in a dynamic environment.
|
||||||
|
|
||||||
|
## WORK EXPERENCE
|
||||||
|
|
||||||
|
### SALES MANAGER
|
||||||
|
**ABC Corportaion** | Anytown, USA | June 2018 - Present
|
||||||
|
- Oversee a team of 12 sales represenatives and achieve quarterly targets
|
||||||
|
- Increased departmnet revenue by 24% in fiscal year 2019-2020
|
||||||
|
- Implemneted new CRM system that improved efficiency by 15%
|
||||||
|
- Collabarate with Marketing team on product launch campaigns
|
||||||
|
- Developed training materials for new hiers
|
||||||
|
|
||||||
|
### ASST. MANAGER
|
||||||
|
**XYZ Industries** | Somewhere Else, USA | March 2015 - may 2018
|
||||||
|
- Assisted the Regional Manager in daily operations and reporting
|
||||||
|
- managed inventory and vendor relations
|
||||||
|
- Trained and mentored junior staff members
|
||||||
|
- Recieved "Employee of the Month" award 4 times
|
||||||
|
|
||||||
|
### CUSTOMER SERVICE REPRESENTATIVE
|
||||||
|
**Fast Solutions Inc** | Another City, USA | January 2010 - February 2015
|
||||||
|
* Responded to customer inquiries via phone email, and in-person
|
||||||
|
* Resolved customer complaints and escalated issues when necessary
|
||||||
|
* Maintained a 95% customer satsfaction rating
|
||||||
|
|
||||||
|
|
||||||
|
## EDUCATIONS
|
||||||
|
|
||||||
|
**Bachelor of Buisness Administration**
|
||||||
|
University of Somewhere | 2006 - 2010
|
||||||
|
GPA: 3.6/4.0
|
||||||
|
|
||||||
|
**Assosiate Degree in Communications**
|
||||||
|
Community College | 2004-2006
|
||||||
|
|
||||||
|
## SKILSS
|
||||||
|
|
||||||
|
- Microsoft Office: *Excel, Word, Powerpoint* (Advanced)
|
||||||
|
- Customer relationship management (CRM) software
|
||||||
|
- Team leadership & managment
|
||||||
|
- Project management
|
||||||
|
- Public speking
|
||||||
|
- Time managemant
|
||||||
|
|
||||||
|
## REFERENCES
|
||||||
|
|
||||||
|
Available upon reqeust
|
||||||
|
|
||||||
|
### OTHER ACTVITIES
|
||||||
|
- Volunteer at the local food bank (2016-present)
|
||||||
|
- Member of Toastmasters International
|
||||||
|
- Enjoy hiking and photografy
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
from pocketflow import Node, Flow
|
||||||
|
from utils import call_llm
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
class ResumeParserNode(Node):
|
||||||
|
def prep(self, shared):
|
||||||
|
"""Return resume text from shared state"""
|
||||||
|
return shared["resume_text"]
|
||||||
|
|
||||||
|
def exec(self, resume_text):
|
||||||
|
"""Extract structured data from resume using prompt engineering"""
|
||||||
|
prompt = f"""
|
||||||
|
Please extract the following information from this resume and format it as YAML:
|
||||||
|
- name
|
||||||
|
- email
|
||||||
|
- experience (list of positions with title and company)
|
||||||
|
- skills (list of skills)
|
||||||
|
|
||||||
|
{resume_text}
|
||||||
|
|
||||||
|
Now, output:
|
||||||
|
```yaml
|
||||||
|
name: John Doe
|
||||||
|
email: john@example.com
|
||||||
|
experience:
|
||||||
|
- title: Software Engineer
|
||||||
|
company: Tech Company
|
||||||
|
- title: Developer
|
||||||
|
company: Another Company
|
||||||
|
skills:
|
||||||
|
- Python
|
||||||
|
- JavaScript
|
||||||
|
- HTML/CSS
|
||||||
|
```"""
|
||||||
|
|
||||||
|
response = call_llm(prompt)
|
||||||
|
|
||||||
|
# Extract YAML content from markdown code blocks
|
||||||
|
yaml_str = response.split("```yaml")[1].split("```")[0].strip()
|
||||||
|
structured_result = yaml.safe_load(yaml_str)
|
||||||
|
|
||||||
|
# Validate structure
|
||||||
|
assert "name" in structured_result
|
||||||
|
assert "experience" in structured_result
|
||||||
|
assert isinstance(structured_result["experience"], list)
|
||||||
|
assert "skills" in structured_result
|
||||||
|
assert isinstance(structured_result["skills"], list)
|
||||||
|
|
||||||
|
return structured_result
|
||||||
|
|
||||||
|
def post(self, shared, prep_res, exec_res):
|
||||||
|
"""Store and display structured resume data in YAML"""
|
||||||
|
shared["structured_data"] = exec_res
|
||||||
|
|
||||||
|
# Print structured data in YAML format
|
||||||
|
print("\n=== STRUCTURED RESUME DATA ===\n")
|
||||||
|
print(yaml.dump(exec_res, sort_keys=False))
|
||||||
|
print("\n============================\n")
|
||||||
|
|
||||||
|
print("✅ Extracted basic resume information")
|
||||||
|
|
||||||
|
# Create and run the flow
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=== Simple Resume Parser - YAML Output ===\n")
|
||||||
|
|
||||||
|
# Read resume text from file
|
||||||
|
shared = {}
|
||||||
|
with open('data.txt', 'r') as file:
|
||||||
|
resume_text = file.read()
|
||||||
|
shared["resume_text"] = resume_text
|
||||||
|
|
||||||
|
|
||||||
|
flow = Flow(start=ResumeParserNode())
|
||||||
|
flow.run(shared)
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
pocketflow>=0.0.1
|
||||||
|
openai>=1.0.0
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import os
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
def call_llm(prompt):
|
||||||
|
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "your-api-key"))
|
||||||
|
r = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=[{"role": "user", "content": prompt}]
|
||||||
|
)
|
||||||
|
return r.choices[0].message.content
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(call_llm("Tell me a short joke"))
|
||||||
Loading…
Reference in New Issue