Skip to content
TutujinAPI

Social science text analysis and qualitative coding

The dependable way to analyze social science text with an LLM is to treat it as a coder working from a codebook: researchers write the codebook, the model codes segment by segment and quotes the words behind each code, and code checks that every quote really is in the source. A sample is then coded independently by people and by a second model to measure agreement, and researchers settle the disagreements. Large corpora such as social media posts get sentiment and topic labels the same way, and an embedding model clusters them to explore themes. For 40 interviews, 8,000 open survey answers and 100,000 social media posts a month, at live prices in each model’s cheapest group, model costs are about ¥124 a month.

Prices updated Nov 13, 2026, 6:13 PM

Monthly cost estimate

Assumptions: 40 interviews a month split into 1,200 segments, each with about 2,500 input tokens (about 1,800 for the codebook, 700 for the text) and 250 output tokens; 8,000 open survey answers at about 2,000 input and 120 output tokens each; 100,000 social media posts labeled for sentiment and topic at about 500 input and 40 output tokens each; 20% of the interview segments and open answers (1,840) coded independently by the second model; and 100,000 posts embedded at about 120 tokens each.

¥124.3per month

  • Interview coding¥5.38
  • Open-answer coding¥24.37
  • Social media sentiment and topics¥82.88
  • Agreement sample (second coder)¥8.56
  • Post embedding and clustering¥3.12
See the usage assumed

The business problem

Interview transcripts, open survey answers and social media posts easily run to hundreds of thousands of words per project. Coding them segment by segment by hand takes weeks, and several coders need repeated calibration.

Asking a model to "summarize the themes" is fast, but the result cannot be checked: which criteria, which words, and whether it would change on another run are all unclear, which does not hold up in peer review.

It works better when the model follows the codebook strictly: researchers set the codebook, the model picks codes only from it and quotes the source, code checks every quote, a sample is compared with human coding, and researchers own the disagreements and the interpretation.

Informed consent, ethics review, de-identification and whether data may be sent to a third-party model service are for researchers and their institutions to decide under their own rules; we make no promises about them. Under the platform’s default settings, usage logs do not record request or response content; to generate a reply, requests are forwarded to the model service behind the group you choose.

Recommended models

Recommended models are picked from the live catalog; prices are each model's cheapest group, updated Nov 13, 2026, 6:13 PM. Click a model to see every group's price.

  • Primary coding model

    input ¥1.12 / output ¥6.72 per 1M tokensChina Models group

    Handles all the text: codes interviews and open answers segment by segment against the codebook, and labels sentiment and topics on social media posts. The codebook sits in the system prompt of every request, so input far exceeds output and the input price matters most. Which model to keep is decided by the agreement check on a sample.

  • Second coder (another vendor’s model)

    input ¥1.5 / output ¥9 per 1M tokensStandard group

    Codes only the agreement sample, independently and without seeing the primary codes. A model from another vendor makes it easier to tell disagreements caused by unclear code definitions from one model’s own bias; its codes go to researchers together with the human coding.

  • Theme exploration (Embeddings)

    input ¥0.26 / output ¥0.26 per 1M tokensStandard group

    Turns open answers and posts into vectors for clustering, finding similar statements and removing duplicates, so researchers can see what the corpus talks about before writing the codebook. Clusters are leads; naming and keeping themes is the researchers’ call.

Reference architecture

  1. 1

    Prepare and de-identify

    Transcribe interview recordings first, then split them into paragraphs labeled with participant and paragraph numbers such as INT07-P012. Remove names, organizations, contact details and other identifying information before sending, and keep the raw data local.

  2. 2

    Write the codebook

    Give every code a definition, when it applies and when it does not, and one or two examples from the data. Clustering the corpus can suggest candidate themes, but researchers decide the codebook and give it a version number.

  3. 3

    Code segment by segment

    Put the codebook in the system prompt, set temperature 0 and ask for JSON with the codes and the words behind each. Code checks that every code is in the codebook and every quote appears word for word in the segment; anything else goes to a person.

  4. 4

    Check agreement

    Draw a random sample of segments, for example 10% to 20%, have people and a second model code it independently, and compute Cohen’s kappa or Krippendorff’s alpha per code. Codes with large disagreement usually have unclear definitions: revise the codebook and recode. Set the threshold by the conventions of your field.

  5. 5

    Sentiment and topics

    For large corpora such as social media posts, label each item from a fixed set of sentiment labels and topics, as in the data labeling solution; add embedding clusters to see the distribution of topics, and read a few source texts from each cluster.

  6. 6

    Back to the source

    Every code in the results keeps its paragraph number and quote, and you cite the quote, never the model’s paraphrase. Record the codebook version, prompts, model IDs, call dates and agreement results in an analysis log so the methods section reports them accurately.

Cost estimate

Assumptions: 40 interviews a month split into 1,200 segments, each with about 2,500 input tokens (about 1,800 for the codebook, 700 for the text) and 250 output tokens; 8,000 open survey answers at about 2,000 input and 120 output tokens each; 100,000 social media posts labeled for sentiment and topic at about 500 input and 40 output tokens each; 20% of the interview segments and open answers (1,840) coded independently by the second model; and 100,000 posts embedded at about 120 tokens each.

ItemModelUsage assumedCost
Interview codingqwen3.5-plus1,200 × (2,500 input + 250 output tokens)¥5.38
Open-answer codingqwen3.5-plus8,000 × (2,000 input + 120 output tokens)¥24.37
Social media sentiment and topicsqwen3.5-plus100,000 × (500 input + 40 output tokens)¥82.88
Agreement sample (second coder)gpt-5.4-mini1,840 × (2,200 input + 150 output tokens)¥8.56
Post embedding and clusteringtext-embedding-3-large100,000 × 120 input tokens¥3.12
Total (per month)¥124.3

Calculated from live prices in each model's cheapest group, updated Nov 13, 2026, 6:13 PM.

Model usage only: human coding and transcription are not included (for transcription, see the speech solution). A longer codebook means more input tokens per item; when the codebook stays the same and the model supports context caching, cached input is billed at the lower cache-read price and the real bill is lower. Twice the corpus means roughly twice the matching line.

Sample code

The model may only pick codes from the codebook and must quote the source; code drops codes outside the codebook and quotes that do not match the text, counting them for review, then computes Cohen’s kappa between the model and people, and between the two models, on the same sample.

Sample code (Python, codebook coding with quote checks and agreement)
import json
import os

from openai import OpenAI

client = OpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"], max_retries=3)

CODEBOOK = {  # written and versioned by the research team
    "COST": "Money, prices or affordability given as a reason for a decision.",
    "TRUST": "Trust or distrust in an institution, a platform or a person.",
    "FAMILY": "Family members influence or take part in the decision.",
}
SYSTEM = (
    "You are a qualitative coder. Apply only these codes, as defined:\n"
    + "\n".join(f"{code}: {definition}" for code, definition in CODEBOOK.items())
    + "\nFor every code that applies, copy the exact words of the segment that justify it. "
    'Reply with JSON only: {"codes": [{"code": "COST", "quote": "exact words"}]}, or {"codes": []} if none apply.'
)


def code_segment(segment, model="qwen3.5-plus"):
    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "system", "content": SYSTEM}, {"role": "user", "content": segment["text"]}],
        temperature=0,
    )
    raw = resp.choices[0].message.content
    found = json.loads(raw[raw.find("{"): raw.rfind("}") + 1]).get("codes", [])
    # keep a code only if it is in the codebook and its quote appears word for word in the segment
    kept = [c for c in found if c.get("code") in CODEBOOK and c.get("quote") and c["quote"] in segment["text"]]
    return {"id": segment["id"], "model": resp.model, "codes": sorted({c["code"] for c in kept}),
            "quotes": kept, "to_check": len(found) - len(kept)}


def cohen_kappa(a, b):
    """Agreement of two coders on one code; a and b are 0/1 lists over the same segments."""
    n = len(a)
    observed = sum(x == y for x, y in zip(a, b)) / n
    pa, pb = sum(a) / n, sum(b) / n
    expected = pa * pb + (1 - pa) * (1 - pb)
    return float("nan") if expected == 1 else (observed - expected) / (1 - expected)


# the agreement sample: a few hundred segments in practice, de-identified before sending
sample = [
    {"id": "INT07-P012", "text": "My mother said the rent there was too high, so we stayed where we were."},
    {"id": "INT11-P003", "text": "I never believed what the agency told us about the subsidy."},
]
human = {"INT07-P012": {"COST", "FAMILY"}, "INT11-P003": {"TRUST"}}  # coded without seeing the model output
first = [code_segment(s) for s in sample]
second = [code_segment(s, model="gpt-5.4-mini") for s in sample]

for code in CODEBOOK:
    m1 = [int(code in r["codes"]) for r in first]
    m2 = [int(code in r["codes"]) for r in second]
    h = [int(code in human[r["id"]]) for r in first]
    print(code, "model vs human:", round(cohen_kappa(m1, h), 2), "| model vs second model:", round(cohen_kappa(m1, m2), 2))
# Exploring themes first: embed answers or posts with text-embedding-3-large and cluster the vectors.

Try this with one key

Sign up, create an API key in the console, and put your base_url and key into the code above. For company purchasing or invoices, add our WeChat support JsnonoChat.

Tutujin support WeChat QR code
WeChatJsnonoChat

Scan the code or search the WeChat ID to add us

FAQ

Can an LLM replace human coders?

It cannot replace the researchers’ judgment. A model is good at a large first pass of coding against a clear codebook; deciding the codebook, settling disagreements and interpreting the results stay with the researchers. Report in the paper how the model was used, which model, and the agreement results.

How do I measure agreement between model and human coding?

Draw a random sample, have people code it without seeing the model’s output, and compute Cohen’s kappa (two coders) or Krippendorff’s alpha (several coders or missing values) per code. Low agreement usually points to an unclear definition: revise the codebook and test again, with a threshold set by the conventions of your field.

Interview data is private. Can I send it to a model?

Whether you may depends on your consent forms, the scope of your ethics approval and your institution’s data rules, so it is the researcher’s decision; we cannot make compliance promises for you. Technically, remove names, organizations, contact details and other identifiers first and send only the passages the analysis needs; if the source of the line matters, choose groups labeled Official.

What does it cost per month?

For 40 interviews, 8,000 open answers and 100,000 social media posts a month, the cheapest groups come to about ¥124. The length of the codebook and the number of posts matter most.

Does this work for English or other languages?

Yes, with the same workflow. Ideally the codebook is in the language of the data; when quotes need translating into the language of your paper, see the translation solution, and keep the original as the authoritative text.

Can sentiment and topic labels go straight into my conclusions?

Treat them as descriptive leads: read source texts behind every sentiment label and topic to confirm what they mean for your research question before writing them into conclusions.