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

如何让Langchain Structured_Chat_Zero_Shot_Description Agent调用自定义工具?

问题原因分析
  • 结构化输出格式不匹配:Structured_Chat_Zero_Shot_Description Agent要求模型输出严格的JSON格式工具调用指令,若prompt未明确指定格式要求,或工具参数schema定义模糊,模型可能仅输出自然语言描述的调用指令,而非可被Agent解析执行的结构化内容。
  • Agent配置缺失:未正确设置stop序列或prompt模板,导致模型输出内容无法被Agent正确截断和解析;未启用verbose模式,无法排查中间步骤的格式错误。
  • 工具定义不规范:若工具未使用StructuredTool定义清晰的参数schema,模型无法准确识别工具所需参数,生成的调用指令不符合Agent执行要求。
解决办法

1. 规范工具定义(使用StructuredTool)

通过StructuredTool结合Pydantic模型明确定义工具参数schema,确保模型能准确识别参数要求:

from langchain.tools import StructuredTool
from pydantic import BaseModel, Field
import json

# 写票工具参数定义
class WriteTicketArgs(BaseModel):
    summary: str = Field(description="工单摘要,需简洁明了描述问题")
    description: str = Field(description="工单详细内容,包含问题背景、影响范围、临时措施等")

def generate_jira_ticket(summary: str, description: str) -> str:
    # 生成合规Jira工单JSON的逻辑
    ticket_json = {
        "fields": {
            "summary": summary,
            "description": description,
            "project": {"key": "PROJ"},
            "issuetype": {"name": "Bug"}
        }
    }
    return json.dumps(ticket_json)

CustomJiraTicketWriting = StructuredTool.from_function(
    func=generate_jira_ticket,
    args_schema=WriteTicketArgs,
    name="CustomJiraTicketWriting",
    description="生成符合Jira API格式的工单JSON字符串,必须传入summary和description参数"
)

# 提交工具参数定义
class PostTicketArgs(BaseModel):
    ticket_json: str = Field(description="已生成的Jira工单JSON字符串")

def post_jira_ticket(ticket_json: str) -> str:
    # 提交工单到Jira的逻辑
    # 示例:调用Jira API提交
    # response = requests.post(JIRA_API_URL, json=json.loads(ticket_json), headers=JIRA_HEADERS)
    return "工单提交成功,工单ID: PROJ-123"

CustomJiraTicketPOST = StructuredTool.from_function(
    func=post_jira_ticket,
    args_schema=PostTicketArgs,
    name="CustomJiraTicketPOST",
    description="将生成的Jira工单JSON提交到Jira系统,必须传入ticket_json参数"
)

2. 配置正确的Agent Prompt与Stop序列

使用StructuredChatPromptTemplate明确指定工具调用的JSON格式,同时设置正确的stop序列确保模型输出被正确截断:

from langchain.agents import StructuredChatZeroShotAgent, AgentExecutor
from langchain.memory import ConversationBufferMemory
from langchain.prompts import StructuredChatPromptTemplate, MessagesPlaceholder
from langchain.chat_models import ChatOpenAI

# 初始化大模型(需支持结构化输出,如gpt-3.5-turbo-1106/gpt-4)
llm = ChatOpenAI(model_name="gpt-3.5-turbo-1106", temperature=0)

# 定义系统提示词,明确执行步骤和格式要求
system_prompt = """你需要按照以下流程处理Jira工单请求:
1. 首先调用CustomJiraTicketWriting工具生成合规的工单JSON
2. 然后将生成的JSON作为参数,调用CustomJiraTicketPOST工具提交工单

可用工具列表:
{tools}

工具调用必须严格遵循以下JSON格式,不要输出任何额外内容:
```json
{{"action": "<工具名称>", "action_input": {{<参数键值对>}}}}

开始处理用户请求:"""

构建Prompt模板

prompt = StructuredChatPromptTemplate.from_messages(
[
("system", system_prompt),
MessagesPlaceholder(variable_name="chat_history"),
("user", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
]
)

初始化Agent

agent = StructuredChatZeroShotAgent(
llm=llm,
tools=[CustomJiraTicketWriting, CustomJiraTicketPOST],
prompt=prompt,
stop=["\nObservation:"] # 关键:设置stop序列,截断模型多余输出
)

配置内存与执行器

memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
agent_executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=[CustomJiraTicketWriting, CustomJiraTicketPOST],
memory=memory,
verbose=True # 启用verbose模式,便于排查中间步骤
)

测试运行

result = agent_executor.run("帮我创建一个Jira工单:摘要为'登录页加载缓慢',描述为'用户反馈登录页加载时长超过5秒,影响新用户注册转化率'")
print(result)

## 3. 关键检查点
- **大模型兼容性**:确保使用的大模型支持结构化输出(如OpenAI的gpt-3.5-turbo-1106及以上版本),旧版本模型可能无法稳定生成合规JSON。
- **Verbose日志排查**:启用`verbose=True`后,查看Agent的中间输出,确认模型是否生成了正确的JSON格式调用指令。若输出为自然语言描述,需进一步优化prompt中的格式示例,增强约束性。
- **工具返回值格式**:工具的返回值需为字符串类型,便于Agent识别并传递给下一个工具。

内容的提问来源于stack exchange,提问作者Joffrey Lemery
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:13:26