# `recognize`: find every name in the evidence and say what kind it is.

*names.json, a file the examples read*

```
{
  "version": 1,
  "recognize": {
    "kinds": {
      "person": null,
      "organization": null,
      "place": null
    },
    "relations": [
      {
        "name": "works_for",
        "source": "person",
        "target": "organization"
      },
      {
        "name": "based_in",
        "source": "organization",
        "target": "place"
      }
    ]
  }
}
```

*recognize finds three names. Each comes back with its kind and its strength.*

```
person="PER=Part of a person's name."
org="ORG=Part of the name of an organization:"
org+=" a company, band, team, agency, government"
org+=" body, or media outlet."
place="LOC=Part of the name of a place: a country,"
place+=" region, city, or geographic feature."
other="MISC=Part of another named entity: a"
other+=" nationality, an event, a product, or the"
other+=" name of a creative work."
text="Maria Chen joined Northwind Freight in Chicago"
text+=" last spring."
printf '%s' "$text" |
thinkthen recognize \
  --kind "$person" \
  --kind "$org" \
  --kind "$place" \
  --kind "$other" |
jq -c '.entities[] | [.text, .kind, .strength]'
```

*Output*

```
["Maria Chen","PER",0.9987]
["Northwind Freight","ORG",0.997]
["Chicago","LOC",1.0]
```

*exit 0*

You give it the evidence and the kinds of name you allow. You get back each name, its kind, where it sits, and a strength.

## Read the answer

With kinds, the model picks each name's kind from them. A name that is not in the evidence cannot come back. The number on a name is its strength. ThinkThen computes it, and it is not a probability. Your threshold decides which names you keep.

| Exit code | What it means |
| --- | --- |
| 0 | the run finished |
| 2 | usage or input error |
| 4 | the backend failed or refused, as it does for evidence over the size limit |
| 5 | a local failure |
| 70 | a defect in the tool |

## Call it from your language

The Bash example opens this page.

```
import thinkthen as tt

text = (
    "Maria Chen joined Northwind Freight "
    "in Chicago last spring."
)
kinds = {
    "PER": "Part of a person's name.",
    "ORG": (
        "Part of the name of an organization: a company, "
        "band, team, agency, government body, "
        "or media outlet."
    ),
    "LOC": "Part of the name of a place: a country, "
           "region, city, or geographic feature.",
    "MISC": (
        "Part of another named entity: a nationality, "
        "an event, a product, or the name of a "
        "creative work."
    ),
}
facts = tt.recognize(
    text,
    kinds=kinds,
).value
names = [(one.text, one.kind) for one in facts.entities]
assert names == [
    ("Maria Chen", "PER"),
    ("Northwind Freight", "ORG"),
    ("Chicago", "LOC"),
]
```

No Polars sample for `recognize`.

No pandas sample for `recognize`.

```
import assert from "node:assert/strict";
import * as tt from "thinkthen";

const text =
  "Maria Chen joined Northwind Freight, " +
  "a company in Chicago.";
const kinds = ["person", "organization", "place"];
const relations = {
  works_for: ["person", "organization"] as const,
  based_in: ["organization", "place"] as const,
};
const facts = (await tt.recognize(text, {
  kinds,
  relations,
})).value;
const names = facts.entities.map((one) => [
  one.text,
  one.kind,
]);
assert.deepEqual(names, [
  ["Maria Chen", "person"],
  ["Northwind Freight", "organization"],
  ["Chicago", "place"],
]);
const links = (facts.relations ?? []).map((one) => [
  one.relation,
  one.source.text,
  one.target.text,
]);
assert.deepEqual(links, [
  ["works_for", "Maria Chen", "Northwind Freight"],
  ["based_in", "Northwind Freight", "Chicago"],
]);
```

```
require "thinkthen"

text = "Maria Chen joined Northwind Freight, " \
  "a company in Chicago."
kinds = ["person", "organization", "place"]
relations = {
  works_for: ["person", "organization"],
  based_in: ["organization", "place"]
}
facts = ThinkThen.recognize(text, kinds:, relations:).value
names = facts.entities.map { |one| [one.text, one.kind] }
raise unless names == [
  ["Maria Chen", "person"],
  ["Northwind Freight", "organization"],
  ["Chicago", "place"]
]
links = facts.relations.map do |one|
  [one.relation, one.source.text, one.target.text]
end
raise unless links == [
  ["works_for", "Maria Chen", "Northwind Freight"],
  ["based_in", "Northwind Freight", "Chicago"]
]
```

```
library(thinkthen)

text <- paste0(
  "Maria Chen joined Northwind Freight, ",
  "a company in Chicago."
)
kinds <- c("person", "organization", "place")
rules <- c(
  "works_for=person:organization",
  "based_in=organization:place"
)
facts <- tt_recognize(
  text, kinds, relations = rules
)$value[[1]]
stopifnot(identical(
  facts$text,
  c("Maria Chen", "Northwind Freight", "Chicago")
))
stopifnot(identical(facts$kind, kinds))
links <- attr(facts, "relations")
stopifnot(identical(
  links$relation,
  c("works_for", "based_in")
))
stopifnot(identical(
  links$source,
  c("Maria Chen", "Northwind Freight")
))
stopifnot(identical(
  links$target,
  c("Northwind Freight", "Chicago")
))
```

```
use thinkthen::{Engine, Kind, Recognize, RelationRule};

let tt = Engine::from_env()?;
let text = concat!(
    "Maria Chen joined Northwind Freight, ",
    "a company in Chicago.",
);
let works_for = RelationRule::one_way(
    "works_for",
    "person",
    "organization",
)?;
let based_in = RelationRule::one_way(
    "based_in",
    "organization",
    "place",
)?;
let ask = Recognize::builder()
    .kind(Kind::new("person", None)?)?
    .kind(Kind::new("organization", None)?)?
    .kind(Kind::new("place", None)?)?
    .relation(works_for)?
    .relation(based_in)?
    .build()?;
let facts = tt.recognize(&ask, text)?.into_value();

let names: Vec<_> = facts
    .entities()
    .iter()
    .map(|one| (one.text(), one.kind()))
    .collect();
let expected = [
    ("Maria Chen", "person"),
    ("Northwind Freight", "organization"),
    ("Chicago", "place"),
];
assert_eq!(names, expected);

let links: Vec<_> = facts
    .relations()
    .unwrap_or_default()
    .iter()
    .map(|one| {
        let source = one.source().text();
        let target = one.target().text();
        (one.relation(), source, target)
    })
    .collect();
let expected = [
    ("works_for", "Maria Chen", "Northwind Freight"),
    ("based_in", "Northwind Freight", "Chicago"),
];
assert_eq!(links, expected);
```

Put this code inside `fn main() -> Result<(), Box<dyn std::error::Error>>` and end it with `Ok(())`. `main` returns a `Result`, so `?` compiles.

```
#include <assert.h>
#include <string.h>
#include <thinkthen.h>

thinkthen_engine *tt = thinkthen_engine_new();
assert(tt);

const char *text =
    "Maria Chen joined Northwind Freight, "
    "a company in Chicago.";
const char *spec =
    "{\"version\": 1, \"recognize\": {"
    "\"kinds\": {\"person\": null, "
    "\"organization\": null, \"place\": null}, "
    "\"relations\": ["
    "{\"name\": \"works_for\", \"source\": \"person\", "
    "\"target\": \"organization\"}, "
    "{\"name\": \"based_in\", "
    "\"source\": \"organization\", "
    "\"target\": \"place\"}]}}";
char *facts;
size_t facts_len;
int rc = thinkthen_recognize(
    tt,
    spec,
    text,
    strlen(text),
    &facts,
    &facts_len
);
assert(rc == THINKTHEN_OK);
assert(strstr(facts, "\"Maria Chen\""));
assert(strstr(facts, "\"Northwind Freight\""));
assert(strstr(facts, "\"Chicago\""));
assert(strstr(facts, "\"works_for\""));
assert(strstr(facts, "\"based_in\""));
thinkthen_free_string(facts);
thinkthen_engine_free(tt);
```

Keep the `#include` lines on top. Put the rest inside `int main(void)` and end it with `return 0;`.

No C++ sample for `recognize`.

No Objective-C sample for `recognize`.

No COBOL sample for `recognize`.

No Ada sample for `recognize`.

No Java sample for `recognize`.

No Kotlin sample for `recognize`.

No Scala sample for `recognize`.

No C# sample for `recognize`.

No Go sample for `recognize`.

No Swift sample for `recognize`.

No Zig sample for `recognize`.

No PHP sample for `recognize`.

No Dart sample for `recognize`.

```
LOAD './thinkthen.duckdb_extension';

CREATE TABLE tickets AS FROM (VALUES
    (1, 'Maria Chen joined Northwind Freight, ' ||
        'a company in Chicago.')
) t(id, body);

SELECT id, entity.text, entity.kind
FROM (
    SELECT
        id,
        unnest(thinkthen_recognize(
            body,
            ['person', 'organization', 'place']
        )) AS entity
    FROM tickets
);

SELECT id, link.relation, link.source, link.target
FROM (
    SELECT id, unnest(thinkthen_relations(
        body, '@names.json'
    )) AS link
    FROM tickets
);
```

*What DuckDB printed*

```
id|text|kind
1|Maria Chen|person
1|Northwind Freight|organization
1|Chicago|place
id|relation|source|target
1|works_for|Maria Chen|Northwind Freight
1|based_in|Northwind Freight|Chicago
```

```
.load ./thinkthen

CREATE TABLE tickets(id INTEGER, body TEXT);
INSERT INTO tickets VALUES (
    1,
    'Maria Chen joined Northwind Freight, ' ||
    'a company in Chicago.'
);

SELECT t.id, entity.text, entity.kind
FROM
    tickets t,
    thinkthen_recognize(
        t.body,
        'person,organization,place'
    ) entity;

WITH found AS (
    SELECT
        id,
        thinkthen_relations(body, '@names.json')
            AS links_found
    FROM tickets)
SELECT found.id, link.value ->> 'relation' AS relation,
    link.value ->> '$.source.text' AS source,
    link.value ->> '$.target.text' AS target
FROM
    found,
    json_each(found.links_found, '$.relations') AS link;
```

*What SQLite printed*

```
1|Maria Chen|person
1|Northwind Freight|organization
1|Chicago|place
1|works_for|Maria Chen|Northwind Freight
1|based_in|Northwind Freight|Chicago
```

```
CREATE TABLE tickets (id int, body text);
INSERT INTO tickets VALUES (
    1,
    'Maria Chen joined Northwind Freight, ' ||
    'a company in Chicago.'
);

SELECT t.id, entity.text, entity.kind
FROM tickets t, LATERAL thinkthen_recognize(
    t.body,
    ARRAY['person', 'organization', 'place']
) entity;

SELECT t.id, link.relation, link.source_text,
    link.target_text
FROM tickets t, LATERAL thinkthen_relations(
    t.body,
    '@names.json'
) link;
```

*What PostgreSQL printed*

```
 id |       text        |     kind     
----+-------------------+--------------
  1 | Maria Chen        | person
  1 | Northwind Freight | organization
  1 | Chicago           | place
(3 rows)

 id | relation  |    source_text    |    target_text    
----+-----------+-------------------+-------------------
  1 | works_for | Maria Chen        | Northwind Freight
  1 | based_in  | Northwind Freight | Chicago
(2 rows)
```

[Arguments, options, and more examples](/reference/functions/recognize/)

Watch `recognize` answer questions about Beatles songs: [recognize labels things it finds.](/learn/beatles-bench/recognize/)

On GitHub: [github.com/botassembly/thinkthen](https://github.com/botassembly/thinkthen)
