← All courses ← Course home

Lesson 03 of 05

Collect a weighted vote

Run several sessions, collect a typed approve or reject from each, and tally with weights you control.

Agent brief (llms.md)

A weighted vote is ordinary Swift. Each specialist session returns a structured choice. You multiply that choice by a weight you chose. You do not ask the model to count the votes. The model is a voter, not the tally clerk.

SessionsIndependent replies
WeightsYour numbers
TallyApprove or fail
import FoundationModels

@Generable
struct Vote {
    @Guide(description: "approve, reject, or abstain")
    var choice: String
    @Guide(description: "One short reason")
    var reason: String
}

struct Specialist {
    let name: String
    let weight: Double
    let session: LanguageModelSession
}

func collectVotes(specialists: [Specialist], prompt: String) async throws -> [String: Vote] {
    var votes: [String: Vote] = [:]
    try await withThrowingTaskGroup(of: (String, Vote).self) { group in
        for specialist in specialists {
            group.addTask {
                let reply = try await specialist.session.respond(
                    to: prompt,
                    generating: Vote.self
                )
                return (specialist.name, reply.content)
            }
        }
        for try await (name, vote) in group {
            votes[name] = vote
        }
    }
    return votes
}

func approved(specialists: [Specialist], votes: [String: Vote], threshold: Double) -> Bool {
    let total = specialists.reduce(0) { sum, item in
        let choice = votes[item.name]?.choice.lowercased()
        let point = choice == "approve" ? item.weight : 0
        return sum + point
    }
    return total >= threshold
}
Task groupSeveral respond calls
Vote structapprove or reject
ThresholdYour cutoff

Give specialists different instructions, not different secrets. A planner proposes. A policy reader checks a local rule file. A critic looks for missing user confirmation. Keep weights in your code or in a config file you ship. Do not let a model rewrite its own weight.

If two specialists share one session transcript, they are not independent. Create separate sessions, or use phone-a-friend child sessions that do not inherit the parent transcript.

Read Pause and resume long AI jobs, Stop prompt attacks and leaks, and Talk to tools with MCP if a long vote must checkpoint, or if voter prompts include untrusted text.

Rule. You assign weights. You tally. The model only casts a typed vote.

Next, add a judge and a path that stops the app and asks for help.

Key concepts

  • A typed vote carries a choice and a reason.
  • Each specialist has a name, a weight, and its own session.
  • Collect votes in a task group. Tally approve weights in app code.
  • A shared transcript between specialists breaks independence.

Takeaways

  • You assign weights and tally. The model only casts a typed vote.
  • Keep weights in your code or shipped config, not model-writable.
  • Create separate sessions for independent votes.