Extracts structured key-value pairs from unstructured text, returning a map[string]string.
| Field | Type | Description |
|---|---|---|
Input |
*string |
Unstructured text to extract key-value pairs from |
| Field | Type | Description |
|---|---|---|
Result |
map[string]string |
Extracted key-value pairs |
Reasoning is captured by WithReasoningLog — no graph output needed.
| Key | Type | Default | Description |
|---|---|---|---|
operation |
string |
required | e.g. "extract name, email, and city from this contact info" |
max_retries |
string |
"3" | Number of retries on parse error |
String values only. All map values are strings. Use downstream ops like AIParseNumberOp or standard Go parsing to convert individual fields to numbers or booleans.
Name your keys explicitly. List the exact key names in the operation param. The model will use those as the map keys, making downstream key access predictable.
Extracts structured contact fields (name, email, phone, company) from a free-form message into a map.
package main
import (
"context"
"encoding/json"
"log"
"os"
"time"
"github.com/akennis/sparsi-go/library"
_ "github.com/akennis/dagor/operator/builtin"
"github.com/panjf2000/ants/v2"
"github.com/akennis/dagor"
"github.com/akennis/dagor/graph"
)
func main() {
message := "Hi, I'm Sarah Chen. You can reach me at sarah.chen@acme.com or call 555-0147. I work at Acme Corp."
library.RegisterConst("msg_val", message)
g, err := graph.NewBuilder("contact_extractor").
Vertex("src").Op("msg_val").
Output("Result", "msg_wire").
Vertex("extract").Op("AIExtractMapOp").
Params(map[string]string{
"operation": "extract the fields: name, email, phone, and company from this contact message",
}).
Input("Input", "msg_wire").
Output("Result", "contact_fields").
Build()
if err != nil {
log.Fatalf("build: %v", err)
}
pool, err := ants.NewPool(4)
if err != nil {
log.Fatalf("pool: %v", err)
}
defer pool.Release()
eng, err := dagor.NewEngine(g, pool)
if err != nil {
log.Fatalf("engine: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
if err := eng.Run(ctx); err != nil {
log.Fatalf("run: %v", err)
}
out := map[string]any{}
if raw, ok := eng.GetOutput("contact_fields"); ok {
out["fields"] = *raw.(*map[string]string)
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
enc.Encode(out)
}