Skip to contents

FGAgent Class

FGAgent Class

Value

An R6 generator. FGAgent$new(id, agent_details, config, is_moderator = FALSE, .runner = NULL) returns an FGAgent; create_agents() and its relatives construct whole rosters.

Details

Represents an agent (participant or moderator) in a focus group simulation. Each agent has a unique ID, a persona, an LLM configuration, and methods to generate utterances and express a desire to speak.

Customizing Agents

FGAgent is designed to be flexible:

  • Per-Agent LLM Configuration: Each agent is initialized with its own llm_config (stored in the config field). This allows different agents to use different LLMs, temperatures, or even providers.

  • Persona Definition: The agent_details (containing demographics, survey_responses, direct_persona_description, and/or communication_style) are used to construct the persona_description and communication_style_instruction.

  • Subclassing: For advanced customization, inherit from FGAgent to override methods or add new fields.

Public fields

id

Character. Unique identifier for the agent.

persona_description

Character. Textual description of the agent's persona, derived from demographics, survey responses, or direct input.

communication_style_instruction

Character. A specific instruction about the agent's communication style, to be included in prompts.

config

An llm_config object (from the LLMR package) specifying the LLM provider, model, API key, and other parameters for this agent.

.runner

NULL or a function used instead of live model calls. It receives a data frame with config and messages list-columns and returns those rows with at least response_text.

is_moderator

Logical. TRUE if the agent is the moderator, FALSE otherwise.

history

List. A log of utterances made by this agent during the simulation.

tokens_sent_agent

Numeric. Tokens sent by this agent's calls, as reported; calls that reported no count add nothing.

tokens_received_agent

Numeric. Tokens received by this agent's calls, as reported.

tokens_total_agent

Numeric. Total tokens of this agent's calls: each call's reported total, or its sent and received counts when it reported no total.

usage_unknown_agent

Numeric. Number of this agent's calls whose usage was incomplete, so that the three token fields are lower bounds when it is positive; NA when that number cannot be determined.

role

Character. "moderator" or "participant" for convenience in reports.

demographics

Named list. Raw demographics used to build persona.

survey_responses

Named list. Raw survey responses used to build persona.

handle

Character or NULL. The label under which this agent appears in the discussion and by which it recognizes its own turns, set by FocusGroup from its handles; NULL outside a session, when id is used.

Methods


Method new()

Initialize a new FGAgent.

Usage

FGAgent$new(id, agent_details, config, is_moderator = FALSE, .runner = NULL)

Arguments

id

Character. A unique identifier for the agent.

agent_details

List. Contains information to build the agent's persona. Can include:

  • demographics: A named list of demographic attributes (e.g., list(age = 30, occupation = "teacher")).

  • survey_responses: A named list of survey questions and answers.

  • direct_persona_description: A character string to be used directly as the persona. Overrides demographics/survey if provided.

  • communication_style: A character string describing the agent's communication style (e.g., "analytical and direct", "empathetic and story-driven").

If is_moderator is TRUE and no specific details are provided, a default moderator persona is used.

config

An llm_config object from LLMR::llm_config(). It may be NULL only for an analysis-only agent that will not generate output.

is_moderator

Logical. TRUE if this agent is the moderator, FALSE otherwise.

.runner

NULL uses live LLMR calls; a function is used instead of live model calls.


Method generate_utterance()

Generate an utterance for the agent.

Usage

FGAgent$generate_utterance(
  topic,
  conversation_history_string,
  utterance_prompt_template,
  max_tokens_utterance = 150,
  current_moderator_question = "N/A",
  conversation_summary_so_far = "N/A",
  current_phase = "discussion",
  conversation_log = NULL,
  standing_rules = NULL,
  self_state = TRUE,
  call_params = NULL
)

Arguments

topic

Character. The current discussion topic.

conversation_history_string

Character. Formatted string of recent conversation history.

utterance_prompt_template

Character. The prompt template to use.

max_tokens_utterance

Integer. Maximum tokens for the generated utterance.

current_moderator_question

Character. The current question posed by the moderator.

conversation_summary_so_far

Character. A summary of earlier parts of the conversation.

current_phase

Character. The current phase of the focus group (e.g., "icebreaker", "exploration").

conversation_log

List or NULL. The structured conversation log, with speakers under the labels this agent is to see. When supplied (and the template is not a legacy flat template), the message is built role-flipped: this agent's own prior turns, those under its handle (or, without one, its id), become assistant messages and others' become labeled user messages. NULL keeps the legacy flat single-user-message construction. In a session, the flat message of a participant opens with the sentence that tells it its handle ("In this discussion you are P3.").

standing_rules

Character or NULL. The system-message standing rules (persona-anchoring, safety, etc.) for the role-flipped path; NULL uses a built-in default appropriate to the agent's role.

self_state

Logical. If TRUE (default), a compact "points you have already made" digest of the agent's own prior turns is added to the system message (participants only) to discourage self-repetition.

call_params

Optional named list of model parameters written over the agent's configuration for this utterance and its retry, such as list(reasoning_effort = "low").

Returns

A list with text (the generated utterance) and meta (a list of call metadata: response_id, finish_reason, sent_tokens, rec_tokens, total_tokens, usage_unknown, duration_s, provider, model, and metadata). The token counts cover the first call and, when the reply was incomplete, its retry; each is NA unless every one of those calls reported it, and usage_unknown counts the calls whose usage was incomplete. The other fields describe the final reply. A label the agent wrote for itself at the start of the reply, such as P3: or **MOD:**, is removed from text, and metadata then holds self_label_removed = TRUE; another speaker's label is kept. A short opening self-introduction ("As a retired nurse, ") is removed too, and metadata then holds preamble_removed = TRUE; a longer opening clause, or one that is part of the statement, is kept. The agent's token fields are updated even when the retry fails.


Method get_need_to_talk()

Get the agent's "desire to talk" score. This method queries the LLM to rate how strongly the agent feels the need to contribute to the discussion at the current moment.

Usage

FGAgent$get_need_to_talk(
  topic,
  conversation_history_string,
  desire_prompt_template,
  max_tokens_desire = 20,
  current_moderator_question = "N/A",
  last_speaker_id = "N/A",
  last_utterance_text = "N/A",
  conversation_log = NULL,
  max_tokens_retry = NULL,
  call_params = NULL
)

Arguments

topic

Character. The current discussion topic.

conversation_history_string

Character. Formatted string of recent conversation history.

desire_prompt_template

Character. The prompt template to use for this query.

max_tokens_desire

Integer. Maximum tokens for the LLM's response to the desire query.

current_moderator_question

Character. The current question posed by the moderator.

last_speaker_id

Character. The label of the agent who spoke last, as the agents see it.

last_utterance_text

Character. The text of the last utterance.

conversation_log

List or NULL. The structured conversation log, with speakers under the labels this agent is to see. When supplied (and the template is not a legacy flat template), desire scoring is role-flipped so the agent reads its own prior turns, those under its handle, as its own voice; NULL keeps the legacy flat construction.

max_tokens_retry

Integer or NULL. The budget of the one retry made when the first reply is empty or cut off; NULL uses 256. No retry is made when max_tokens_desire is already at least this large.

call_params

Optional named list of model parameters written over the agent's configuration for these calls, such as list(reasoning_effort = "low").

Returns

Numeric. A score from 0 (no desire) to 10 (very strong desire), read from the reply's final answer only: reasoning the provider returns separately, or that the model writes inside <think> tags or the gpt-oss channel markup, is never read. A reply that cannot be read as a score is an error; the usage of the calls made, including a retry, is recorded on the agent first. The configuration's temperature, when it sets one, is used; none is added when it does not.


Method answer_probe()

Answer a private question put by the researcher. The agent reads its persona, the standing rules, and the discussion so far, as for a turn, and the question as the closing instruction. The answer is returned, not logged, and is not added to history.

Usage

FGAgent$answer_probe(
  question,
  conversation_log,
  topic = NULL,
  template = "{{probe_question}}",
  max_tokens = NULL,
  conversation_summary = NULL,
  call_params = NULL,
  scale = NULL,
  reask_template = NULL
)

Arguments

question

Character. The question.

conversation_log

List. The discussion so far, with speakers under the labels this agent is to see.

topic

Character or NULL. The session topic, available to the template as {{topic}}.

template

Character. The instruction template; {{probe_question}} is replaced by the question.

max_tokens

Integer or NULL. The budget; NULL uses the configuration's limit, or 300 when it sets none.

conversation_summary

Character or NULL. A summary of earlier discussion to add to the system message.

call_params

Optional named list of model parameters written over the configuration for this call.

scale

Optional two whole numbers, c(lo, hi). When given, the answer is read as one number on that scale, and an answer from which none can be read is followed by one re-ask (see fg_probe()).

reask_template

Character or NULL. The re-ask, with placeholders {{lo}}, {{hi}}, and {{probe_question}}; NULL uses participant_probe_reask of get_default_prompt_templates().

Returns

A list with answer (the final answer, trimmed, or NA when the reply is empty after one retry with a larger budget), raw_text (the reply as returned), finish_reason, call_id (the call's row in the session's call record, or NA outside a session), value (the number read from the answer on scale, or NA), and attempts (the number of calls made). After a re-ask that returned text, answer, raw_text, finish_reason, and call_id describe the re-ask.


Method clone()

The objects of this class are cloneable with this method.

Usage

FGAgent$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples

cfg <- LLMR::llm_config("groq", "openai/gpt-oss-20b",
                        api_key = LLMR::llm_api_key_env("GROQ_API_KEY"))
a <- FGAgent$new(
  id = "P1",
  agent_details = list(direct_persona_description = "A retired teacher."),
  config = cfg)
a$persona_description
#> [1] "A retired teacher."