You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ollama+LiteLLM+Autogen遇BadRequestError及角色分配异常

问题描述

我基于Ollama服务器搭配LiteLLM代理,用Autogen搭建多Agent群聊系统,涉及Agent如下:

  • User_Proxy:发起问题
  • SQL_Generator:生成SQL语句
  • SQL_Runner:执行SQL(工具调用)
  • Result_Validator:验证返回结果

具体问题

  1. 发言者分配错误:SQL_Runner从数据库返回数据前群聊正常,但后续本该由Result_Validator发言,却分配给了SQL_Generator——即使我已在系统消息中明确要求SQL_Runner将结果传递给Result_Validator。尝试设置autogen.GroupChat的speaker_selection_method为"round_robin",无效果。
  2. 角色非法报错:SQL_Runner执行工具调用后,SQL_Generator的角色仍被标记为tool,而非[system, user, assistant]三者之一,触发以下错误:
***** Response from calling tool (call_6493f510-d318-4e85-b552-8963bece5fcb) *****
[
    // 数据库返回的数据
]
**********************************************************************************
Next speaker: SQL_Generator

// 错误堆栈信息

openai.BadRequestError: Error code: 400 - {'error': {'message': 'invalid role: tool, role must be one of [system, user, assistant]', 'type': 'api_error', 'param': None, 'code': None}}

我猜测阻止Agent角色缓存可能解决问题,但不知道具体操作方式。

相关代码

LLM配置

llama3_config_list = [
    {
        "model": "llama3:latest",
        "base_url": f"{OLLAMA_BASE_URL}:{OLLAMA_PORT}/v1",
        "api_key": "ollama",
    }
]

litellm_config_list = [
    {
        "model": "NotRequired",
        "api_key": "NotRequired",
        "base_url": f"{LITELLM_BASE_URL}:{LITELLM_PORT}",
        "price": [0, 0],
    }
]

local_llm_config = {"config_list": litellm_config_list, "cache_seed": None}

群聊代码

user_proxy = autogen.UserProxyAgent(
    name=Role.USER_PROXY,
    system_message=Prompt.USER_PROXY,
    human_input_mode="NEVER",
    is_termination_msg=is_termination_msg,
    code_execution_config={"use_docker": False, "work_dir": "test"},
)

sql_generator = autogen.AssistantAgent(
    name=Role.SQL_GENERATOR,
    system_message=Prompt.SQL_GENERATOR,
    llm_config=get_custom_llm_config(config_list=llama3_config_list),
)

sql_runner = autogen.AssistantAgent(
    name=Role.SQL_RUNNER,
    system_message=Prompt.SQL_RUNNER,
    llm_config=local_llm_config,
)

@user_proxy.register_for_execution()
@sql_runner.register_for_llm(description="SQL query runner")
def run_sql(sql: Annotated[str, "SQL query string to run"]) -> str:
    with PostgresManager() as db:
        db.get_rds_connection()
        return db.run_sql(sql)

result_validator = autogen.AssistantAgent(
    name=Role.RESULT_VALIDATOR,
    system_message=Prompt.RESULT_VALIDATOR,
    llm_config=get_custom_llm_config(config_list=llama3_config_list)
)

groupchat = autogen.GroupChat(
    agents=[
        user_proxy,
        sql_generator,
        sql_runner,
        result_validator,
    ],
    messages=[],
)

manager = autogen.GroupChatManager(groupchat=groupchat)

user_proxy.initiate_chat(manager, message=question)

解决方案

修复发言者分配错误

默认发言者选择逻辑依赖LLM自主判断,工具调用后的消息格式可能干扰round_robin规则生效。可以自定义发言者选择函数,强制在SQL_Runner返回结果后切换到Result_Validator:

def custom_speaker_selection(last_message, groupchat):
    # 检查上一条消息是否是SQL_Runner执行工具后的结果
    if last_message.get("name") == Role.SQL_RUNNER and "tool_call" not in last_message:
        # 定位Result_Validator并返回
        for agent in groupchat.agents:
            if agent.name == Role.RESULT_VALIDATOR:
                return agent
    # 其他场景沿用round_robin逻辑
    return autogen.GroupChat.round_robin(last_message, groupchat)

# 创建GroupChat时指定自定义选择函数
groupchat = autogen.GroupChat(
    agents=[user_proxy, sql_generator, sql_runner, result_validator],
    messages=[],
    speaker_selection_method=custom_speaker_selection
)

修复角色为tool的错误

这个问题源于工具调用后的消息角色标记异常,或Agent历史消息中混入非法角色内容,可从以下几点处理:

  1. 修正工具调用后的消息角色
    Autogen中工具执行结果应由UserProxyAgent以user角色转发。确保run_sql函数返回值正常,同时给UserProxyAgent配置max_consecutive_auto_reply避免异常循环:
user_proxy = autogen.UserProxyAgent(
    # 原有配置...
    max_consecutive_auto_reply=3,
)
  1. 禁用Agent消息缓存
    确保所有AssistantAgent的llm_config都包含cache_seed=None,也可在工具调用后手动清理目标Agent的历史消息:
@user_proxy.register_for_execution()
@sql_runner.register_for_llm(description="SQL query runner")
def run_sql(sql: Annotated[str, "SQL query string to run"]) -> str:
    with PostgresManager() as db:
        db.get_rds_connection()
        result = db.run_sql(sql)
        # 清理SQL_Generator的历史消息,避免角色缓存
        sql_generator.reset()
        return result
  1. 过滤非法角色消息
    自定义GroupChat的消息添加逻辑,将非法的tool角色转为user角色并由UserProxyAgent转发:
class CustomGroupChat(autogen.GroupChat):
    def add_message(self, message, speaker):
        if isinstance(message, dict) and message.get("role") == "tool":
            message["role"] = "user"
            speaker = user_proxy
        super().add_message(message, speaker)

# 使用自定义GroupChat
groupchat = CustomGroupChat(
    agents=[user_proxy, sql_generator, sql_runner, result_validator],
    messages=[],
    speaker_selection_method=custom_speaker_selection
)
  1. 修正LiteLLM配置
    LiteLLM转发请求时可能因模型名配置错误导致角色处理异常,将litellm_config_list中的model改为实际使用的模型名:
litellm_config_list = [
    {
        "model": "llama3:latest",
        "api_key": "ollama",
        "base_url": f"{OLLAMA_BASE_URL}:{OLLAMA_PORT}/v1",
        "price": [0, 0],
    }
]

内容的提问来源于stack exchange,提问作者itsba2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:08:10