datawhalechina/hello-agents · error · ValueError

请先设置角色

Error message

请先设置角色

What it means

CharacterRoleplayAgent.send_message() raises ValueError('请先设置角色') when self.chat is still falsy. The conversation list is only created during character setup (the method that prints '成功初始化角色'), so this error means the caller invoked send_message before any character was configured — the roleplay loop's internal state machine was skipped. It is a pure ordering/state error, not an API or network problem.

Source

Thrown at Co-creation-projects/megg-ops-roleplay_agent/roleplay_agent.py:80

        
        # 初始化对话历史
        self.chat = [
            {"role": "system", "content": system_instruction},
            {"role": "assistant", "content": self.character_config['opening_line']}
        ]
        
        print(f"\n✅ 成功初始化角色: {self.character_config['name']} (来自 {self.character_config['source_material']})")
        print(f"💡 {self.character_config['name']}: {self.character_config['opening_line']}")
        print("\n" + "="*50)
        print("开始对话吧!输入 'quit' 或 'exit' 退出,输入 'new' 开始新角色。")
        print("="*50)

    def send_message(self, message):
        """
        发送消息给 AI 并获取响应
        """
        if not self.chat:
            raise ValueError("请先设置角色")
        
        # 添加用户消息到对话历史
        self.chat.append({"role": "user", "content": message})
        
        try:
            # 调用 API
            response = self.client.chat.completions.create(
                model=self.model_id,
                messages=self.chat,
                temperature=0.9,  # 增加创造性
                max_tokens=1024
            )
            
            # 获取响应内容
            response_text = response.choices[0].message.content
            # 添加到对话历史
            self.chat.append({"role": "assistant", "content": response_text})
            

View on GitHub (pinned to 606a07d341)

Solutions

  1. Call the character-setup flow first (the method that initializes self.character_config and self.chat — e.g. setup/opening printed with '✅ 成功初始化角色'), then send_message.
  2. If setup already ran, check it did not raise partway: wrap it in try/except and abort the turn instead of continuing to send_message.
  3. Add a ready check in your caller: if not getattr(agent, 'chat', None): agent.setup_character(...) before messaging.
  4. Make setup idempotent and re-callable after 'new' so state can never be chat-less while the loop keeps accepting input.

Example fix

# before
agent = CharacterRoleplayAgent()
reply = agent.send_message("hello")
# after
agent = CharacterRoleplayAgent()
agent.setup_character()  # or set_character(...) — initializes agent.chat
reply = agent.send_message("hello")
Defensive patterns

Strategy: validation

Validate before calling

def ensure_ready(agent) -> None:
    if not getattr(agent, "chat", None):
        raise RuntimeError("character not set — call setup/set character before messaging")

ensure_ready(agent)
agent.send_message("hello")

Type guard

from typing import Protocol

class ChatReady(Protocol):
    chat: list

def is_chat_ready(agent) -> bool:
    return bool(getattr(agent, "chat", None))

Try / catch

try:
    agent.send_message(msg)
except ValueError as e:
    if "请先设置角色" in str(e):
        agent.setup_character()  # recover once, then retry
        reply = agent.send_message(msg)
    else:
        raise

Prevention

When it happens

Trigger: Constructing CharacterRoleplayAgent() and immediately calling send_message('hi'); calling send_message after a 'new'/reset command cleared self.chat; an exception during character setup that left the agent half-initialized; automating the agent in a script that assumes a default character exists.

Common situations: Batch/script wrappers that skip the interactive character-selection prompt; a crash in setup_character swallowed by a broad except so the caller wrongly proceeds; REPL flow where the user types a message before choosing a character; tests that exercise send_message without the setup fixture.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/4a60f37726952934. Report an issue: GitHub.