We need to create a data collection agent which as...
# ask-ai
m
We need to create a data collection agent which asks the data from the user and stores it
t
Thanks for reaching out, Yashish. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
To create a data collection agent that asks for information from users and stores it, you can build a structured LiveKit agent using the following steps: 1. Define your data structure: Create a Python class or dataclass (e.g.,
SurveyData
) to hold user responses and state. 2. Create a sequence of specialized agents: For each data point (such as name, email, etc.), make a corresponding agent using
@function_tool
decorators to collect input and record responses. Each agent can prompt the user for specific data and transition to the next step. 3. Store collected data: After data collection, you can store responses in memory, write to a CSV file, or save to a database (e.g., SQLite), depending on your persistence requirements. 4. Session management: Use
session.userdata
to store and pass the data structure as the user progresses through the stages. You can implement robust flows by chaining multiple agents, validating user input within your function tools, and providing completion summaries at the end of the process. This approach is flexible and adaptable for collecting any type of user information through your LiveKit agent workflow. If you need a code example or have specific requirements (e.g., voice vs. text, storage backend), please specify for more detailed guidance. Sources: complex-agents/nutrition-assistant/README.md
m
we need to fully update it to follow the new flow where the bot interacts with the pharmacist and stores the collected data. Below is the updated flow we would like to implement: 1. The pharmacist answers the call. 2. The bot responds: "I would like to collect some information regarding a patient named Alex." 3. The pharmacist asks for the patient ID. 4. The bot provides the patient ID. 5. The pharmacist asks: "What details do you need?" 6. The bot asks the following three questions one after another, and the pharmacist responds to each: What are the active prescriptions? What are the inactive prescriptions? What are the insurance details? 7. The bot stores the received information and confirms it with the pharmacist. 8. Once the pharmacist confirms, the bot ends the call by saying: "Thank you, have a good day!"
t
Hey there! Let me walk you through a super friendly way to set up your pharmacist-bot in LiveKit. Think of it like creating a helpful conversation flow that feels natural and smooth. 1. Kick things off with a warm welcome: When the pharmacist picks up, your bot can say something like: "Hi there! I'm here to help collect some info about a patient named Alex." 2. Patient ID time: Your bot will be ready to share the patient ID whenever asked, making it easy with something like
session.say("The patient ID is 12345.")
. 3. Listening for what's needed: When the pharmacist asks, "What details do you need?", your bot will be all set to smoothly move to the next step. 4. Gathering info together: Your bot will have friendly agents ready to collect details like: All these answers get neatly stored in a
ConversationData
structure. ◦ What are the active prescriptions?What are the inactive prescriptions?What are the insurance details? 1. Wrapping up with a smile: After collecting all the info, the bot will confirm everything with the pharmacist and cheerfully say: "Thanks so much! Hope you have a great day!" before ending the call. We'll use LiveKit's smart agent state management to keep track of each stage, with
@function_tool
decorators making sure everything flows smoothly. This setup works great for both flexible conversations and more structured interactions. You can easily store the collected info in session memory, a file, or a database. This approach is super flexible—if you want more details on things like understanding natural language, setting up phone systems, or handling data storage, just give me a shout, and I'll be happy to help! Sources: agent.py | examples/voice_agents/restaurant_agent.py | Agents telephony integration | LiveKit Docs | Company directory phone assistant | LiveKit Docs | flows/simple_flow.py
m
here update our this code to handel our case correctly from dotenv import load_dotenv from livekit import agents from livekit.agents import AgentSession, Agent, RoomInputOptions from livekit.plugins import ( openai, cartesia, deepgram, noise_cancellation, silero, ) from livekit.plugins.turn_detector.multilingual import MultilingualModel load_dotenv() class Assistant(Agent): def __init__(self) -> None: super().__init__(instructions="You are a helpful voice AI assistant.") async def entrypoint(ctx: agents.JobContext): session = AgentSession( stt=deepgram.STT(model="nova-3", language="multi"), llm=openai.LLM(model="gpt-4o-mini"), tts=cartesia.TTS(model="sonic-2", voice="f786b574-daa5-4673-aa0c-cbe3e8534c02"), vad=silero.VAD.load(), turn_detection=MultilingualModel(), ) await session.start( room=ctx.room, agent=Assistant(), room_input_options=RoomInputOptions( # LiveKit Cloud enhanced noise cancellation # - If self-hosting, omit this parameter # - For telephony applications, use
BVCTelephony
for best results noise_cancellation=noise_cancellation.BVC(), ), ) await ctx.connect() await session.generate_reply( instructions="Greet the user and offer your assistance." ) if name == "__main__": agents.cli.run_app(agents.WorkerOptions(entrypoint_fnc=entrypoint))
t
Hey there! I've got a super helpful code example for managing your pharmacist interaction that'll make collecting patient info a breeze. Let me walk you through this friendly approach to handling your use case.
Copy code
from dotenv import load_dotenv
from dataclasses import dataclass, field
from typing import Dict, Optional
from livekit import agents
from livekit.agents import AgentSession, Agent, RoomInputOptions
from livekit.plugins import (
    openai,
    cartesia,
    deepgram,
    noise_cancellation,
    silero,
)
from livekit.plugins.turn_detector.multilingual import MultilingualModel

load_dotenv()

@dataclass
class PharmacistSessionData:
    patient_id: Optional[str] = "12345"
    patient_name: str = "Alex"
    responses: Dict[str, str] = field(default_factory=dict)
    stage: int = 0

class PharmacistBot(Agent):
    def __init__(self):
        super().__init__(instructions="You are an assistant running a pharmacist info collection flow.")
        self.questions = [
            "What are the active prescriptions?",
            "What are the inactive prescriptions?",
            "What are the insurance details?"
        ]

    async def on_enter(self):
        s = self.session.userdata
        if s.stage == 0:
            await self.session.say(f"I would like to collect some information regarding a patient named {s.patient_name}.")
        elif s.stage == 1:
            await self.session.say(f"The patient ID is {s.patient_id}.")
        elif 2 <= s.stage < 6:
            await self.session.say(self.questions[s.stage - 2])
        elif s.stage == 6:
            summary = f"Active prescriptions: {s.responses.get('active', '[not provided]')}\n"
            summary += f"Inactive prescriptions: {s.responses.get('inactive', '[not provided]')}\n"
            summary += f"Insurance details: {s.responses.get('insurance', '[not provided]')}\n"
            await self.session.say(f"To confirm, here's what I have collected:\n{summary}Does this look correct?")
        elif s.stage == 7:
            await self.session.say("Thank you, have a good day!")
            await self.session.aclose()

    async def on_user_message(self, message: str):
        s = self.session.userdata
        if s.stage == 0 and "patient id" in message.lower():
            s.stage = 1
            await self.on_enter()
        elif s.stage == 1 and "what details" in message.lower():
            s.stage = 2
            await self.on_enter()
        elif s.stage == 2:
            s.responses['active'] = message
            s.stage = 3
            await self.on_enter()
        elif s.stage == 3:
            s.responses['inactive'] = message
            s.stage = 4
            await self.on_enter()
        elif s.stage == 4:
            s.responses['insurance'] = message
            s.stage = 5
            await self.on_enter()
        elif s.stage == 5:
            if "yes" in message.lower():
                s.stage = 6
                await self.on_enter()
            else:
                await self.session.say("Please clarify or provide corrections.")
        else:
            await self.session.say("Could you please clarify?")

async def entrypoint(ctx: agents.JobContext):
    session = AgentSession(
        stt=deepgram.STT(model="nova-3", language="multi"),
        llm=openai.LLM(model="gpt-4o-mini"),
        tts=cartesia.TTS(model="sonic-2", voice="f786b574-daa5-4673-aa0c-cbe3e8534c02"),
        vad=silero.VAD.load(),
        turn_detection=MultilingualModel(),
        userdata=PharmacistSessionData(),
    )
    await session.start(
        room=ctx.room,
        agent=PharmacistBot(),
        room_input_options=RoomInputOptions(
            noise_cancellation=noise_cancellation.BVC(),
        ),
    )
    await ctx.connect()

if __name__ == "__main__":
    agents.cli.run_app(agents.WorkerOptions(entrypoint_fnc=entrypoint))
I've crafted this code to make patient info gathering super smooth! You can totally customize the stage transitions and field names to fit exactly what you need. Think of it like having a friendly chat that makes collecting important details feel natural and easy. 😊 Sources: Workflows | LiveKit Docs | complex-agents/personal_shopper/README.md
m
The flow is not working correctly. Currently, only the bot is speaking about the flow, and it is not maintaining a proper conversational manner
t
Hey there! Let's talk about a little hiccup in our conversation flow. Right now, the agent is jumping ahead before you've had a chance to share your thoughts, which can feel a bit jarring. • Waiting for your input: Think of it like a friendly chat—we want to pause and really listen to you before moving forward. The agent should only progress when you've finished speaking. • Turn detection: We're using a smart tool called
MultilingualModel()
to make sure we catch the full context of what you're saying, without cutting you off mid-sentence. • Keeping things smooth: We'll only update our conversation stage after carefully understanding your response. No more rushing ahead! • Give you breathing room: If it seems like we're interrupting, we'll adjust the settings to allow for more natural pauses in our chat. The goal is to make our conversation feel as natural as talking with a friend—taking turns, listening carefully, and moving forward together. Sources: AI voice agents | LiveKit Docs | How does end-of-utterance detection work in conversations? | Voice Assistants | livekit/livekit_composite | DeepWiki | Handling RAG Delays in Voice Agents | LiveKit Docs | flows/multi_stage_flow.py | VoicePipelineAgent | LiveKit Docs | Speech &amp; Audio Processing | livekit/livekit_composite | DeepWiki | LiveKit turn detector plugin | LiveKit Docs | Turn detection and interruptions | LiveKit Docs | Turn detection and interruptions | LiveKit Docs
m
provide a fully updated and working code
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!