Skip to contents

Agents talk over a shared transcript. At each turn the next speaker (chosen by turn_policy) receives the full dialogue so far, attributed by name, plus an instruction to answer in character; the reply is appended and the next turn begins. The conversation ends after max_turns utterances or when stop_when(transcript) returns TRUE.

Usage

conversation(
  agents,
  topic,
  opening = NULL,
  opening_by = "Facilitator",
  turn_policy = c("round_robin", "random", "moderator"),
  moderator = NULL,
  max_turns = 2L * length(agents),
  stop_when = NULL,
  instruction = NULL,
  msg_mode = NULL,
  quiet = FALSE,
  ...
)

Arguments

agents

A list of Agent objects (names must be unique).

topic

What the conversation is about; included in every speaker's instructions.

opening

Optional opening statement placed on the transcript before the first turn (attributed to opening_by).

opening_by

Name to attribute the opening to. Default "Facilitator".

turn_policy

One of "round_robin", "random", "moderator".

moderator

An Agent; required for the moderator policy.

max_turns

Total number of utterances to collect.

stop_when

Optional function(transcript_tibble) -> logical; checked after every utterance.

instruction

Extra instruction appended to every speaker's system message (e.g. "Answer in at most three sentences.").

msg_mode

Message construction for this run: "roleflip" (default) or "flat". NULL (the default) uses getOption("LLMRagent.msg_mode"), else "roleflip". An explicit value overrides the global option for this call only. See the Message construction section.

quiet

If FALSE (default), utterances print as they arrive.

...

Passed to each agent's underlying LLMR call.

Value

An object of class agent_conversation: a list with transcript (tibble: turn, speaker, text), topic, and agents (names).

Details

Turn policies:

  • "round_robin": agents speak in the order given, repeatedly.

  • "random": a random speaker each turn, never the same agent twice in a row. Set a seed first (e.g. set.seed(110)) for a reproducible order.

  • "moderator": after each utterance the moderator agent chooses who speaks next (a structured one-token decision), which lets the moderator shape the turn order at the cost of one extra model call per turn.

Replies are stateless (Agent's reply()): the shared transcript is the single source of truth, so the same agents can be reused across conversations without cross-contamination.

Message construction

By default each speaker sees the conversation role-flipped: its own prior turns are assistant messages and every other speaker's are labeled user messages (via LLMR::transcript_as_messages()), which marks what the model already said and reduces self-repetition. msg_mode = "flat" (or options(LLMRagent.msg_mode = "flat")) reverts to the legacy construction that pastes the whole attributed transcript into one user message – useful for reproducing pre-0.7.x runs. The same control applies to the presets debate(), focus_group(), interview(), and deliberate().

Examples

if (FALSE) { # \dontrun{
cfg <- LLMR::llm_config("groq", "openai/gpt-oss-20b", temperature = 0.8)
a <- agent("Rosa",  cfg, persona = "A pragmatic city planner.")
b <- agent("Hugo",  cfg, persona = "A skeptical economist.")
conv <- conversation(list(a, b),
                     topic = "Should the city pedestrianize its center?",
                     max_turns = 6)
conv$transcript
} # }