← Library AI AI-Powered

AIExtractMapOp

Extracts structured key-value pairs from unstructured text, returning a map[string]string.

Inputs

Field Type Description
Input *string Unstructured text to extract key-value pairs from

Outputs

Field Type Description
Result map[string]string Extracted key-value pairs

Reasoning is captured by WithReasoningLog — no graph output needed.

Params

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

Typical Use Cases

  • Contact info extraction (name, email, phone, city)
  • Form field extraction from free-text submissions
  • Structured attribute extraction from product descriptions
  • Parsing configuration values from prose documentation

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.

Complete Runnable Example

Extracts structured contact fields (name, email, phone, company) from a free-form message into a map.

main.go
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)
}