Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create an agent that can interact with user? #861

Closed
tomaszek92 opened this issue Feb 6, 2025 · 2 comments
Closed

How to create an agent that can interact with user? #861

tomaszek92 opened this issue Feb 6, 2025 · 2 comments

Comments

@tomaszek92
Copy link

Hi 👋🏻

I want to build an app that helps find a proper smartphone model. The app asks the user about his preferences (eg. screen size, OS, memory etc) - the model based on the prompt should decide if it has sufficient information.
Example configuration:

class UserPreferences(BaseModel):
    summary: str = Field(description='The summary of user preferences')

agent = Agent(
    'openai:gpt-4o',
    result_type: UserPreferences,
    system_prompt=(
        'You're goal is to help the user to find the best smartphone model based on his preferences.'
        '- Ask questions one at a time.'
        '- Ask no more than 4 questions, but you may finish earlier if you gather enough information.'
       .... # ommited
    ),

My main problem is how to interact with agent. I want the agent to ask me single questions (generated by the model), wait for an answer before asking the next question, and finish the interaction when the model decides if has sufficient preferences to create a summary.

@HamzaFarhan
Copy link

HamzaFarhan commented Feb 6, 2025

Basically, tell the Agent to return UserPreferences or str by changing the result_type

from pydantic import BaseModel, Field
from pydantic_ai import Agent


class UserPreferences(BaseModel):
    summary: list[str] = Field(description="The summary of user preferences")


agent = Agent(
    model="google-gla:gemini-1.5-flash",
    result_type=UserPreferences | str,  # type: ignore
    system_prompt=(
        "You're goal is to help the user to find the best smartphone model based on his preferences.\n"
        "- Ask questions one at a time.\n"
        "- Ask no more than 4 questions, but you may finish earlier if you gather enough information.\n"
        "- Focus on key aspects like budget, preferred OS, camera quality, battery life, and screen size.\n"
        "- Be concise but friendly in your questions.\n"
        "- After gathering information, provide a summary of preferences in the result.\n"
        "- Do not recommend specific phone models, just summarize preferences.\n"
        "- If user provides preferences without being asked, incorporate them into your understanding."
    ),
)

user_prompt = "I'm thinking of buying a new smartphone"
message_history = None
while user_prompt.lower() not in ["q", "quit", "exit"]:
    res = await agent.run(user_prompt=user_prompt, message_history=message_history)
    if isinstance(res.data, UserPreferences):
        break
    user_prompt = input(f"{res.data}   ('q'/'quit'/'exit' to quit) > ")
    message_history = res.all_messages()

res.data
"""
UserPreferences(summary=['Android OS', 'Budget: $1200', 'Screen size: 6.5+ inches', 'Camera: High quality', 'Battery life: 4000+ mAh'])
"""

res.all_messages()
"""
[
    {
        "parts": [
            {
                "content": "You're goal is to help the user to find the best smartphone model based on his preferences.\n- Ask questions one at a time.\n- Ask no more than 4 questions, but you may finish earlier if you gather enough information.\n- Focus on key aspects like budget, preferred OS, camera quality, battery life, and screen size.\n- Be concise but friendly in your questions.\n- After gathering information, provide a summary of preferences in the result.\n- Do not recommend specific phone models, just summarize preferences.\n- If user provides preferences without being asked, incorporate them into your understanding.\nReturn the UserPreferences once you have gathered all the information.",
                "dynamic_ref": null,
                "part_kind": "system-prompt"
            },
            {
                "content": "I'm thinking of buying a new smartphone",
                "timestamp": "2025-02-06T21:04:04.388208Z",
                "part_kind": "user-prompt"
            }
        ],
        "kind": "request"
    },
    {
        "parts": [
            {
                "content": "Hi! I can help you with that! To give you the best recommendation, could you share your budget range for the new smartphone?\n",
                "part_kind": "text"
            }
        ],
        "model_name": "gemini-1.5-flash",
        "timestamp": "2025-02-06T21:04:06.704128Z",
        "kind": "response"
    },
    {
        "parts": [
            {
                "content": "1200",
                "timestamp": "2025-02-06T21:04:11.267120Z",
                "part_kind": "user-prompt"
            }
        ],
        "kind": "request"
    },
    {
        "parts": [
            {
                "content": "Great!  And what operating system do you prefer, Android or iOS?\n",
                "part_kind": "text"
            }
        ],
        "model_name": "gemini-1.5-flash",
        "timestamp": "2025-02-06T21:04:12.010325Z",
        "kind": "response"
    },
    {
        "parts": [
            {
                "content": "android",
                "timestamp": "2025-02-06T21:04:16.054259Z",
                "part_kind": "user-prompt"
            }
        ],
        "kind": "request"
    },
    {
        "parts": [
            {
                "content": "Perfect! Do you have a preference regarding camera quality, battery life, or screen size?  (e.g., \"high-quality camera is a must\", \"long battery life is essential\", \"I need a large screen\")\n",
                "part_kind": "text"
            }
        ],
        "model_name": "gemini-1.5-flash",
        "timestamp": "2025-02-06T21:04:17.366989Z",
        "kind": "response"
    },
    {
        "parts": [
            {
                "content": "yes. high quality camera, 6.5+ inch screen, and long battery. 4000 +",
                "timestamp": "2025-02-06T21:04:48.925394Z",
                "part_kind": "user-prompt"
            }
        ],
        "kind": "request"
    },
    {
        "parts": [
            {
                "tool_name": "final_result",
                "args": {
                    "summary": [
                        "Android OS",
                        "Budget: $1200",
                        "Screen size: 6.5+ inches",
                        "Camera: High quality",
                        "Battery life: 4000+ mAh"
                    ]
                },
                "tool_call_id": null,
                "part_kind": "tool-call"
            }
        ],
        "model_name": "gemini-1.5-flash",
        "timestamp": "2025-02-06T21:04:51.226755Z",
        "kind": "response"
    },
    {
        "parts": [
            {
                "tool_name": "final_result",
                "content": "Final result processed.",
                "tool_call_id": null,
                "timestamp": "2025-02-06T21:04:51.229095Z",
                "part_kind": "tool-return"
            }
        ],
        "kind": "request"
    }
]
"""

@tomaszek92
Copy link
Author

Thanks @HamzaFarhan for response - very helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants