提示工程与 Agent 编排:从单轮对话到复杂任务执行的架构演进
一、引言:范式跃迁的内在逻辑

2022年至2026年间,大语言模型应用开发经历了一场从“提示工程”到“上下文工程”再到“Harness工程”的三阶段演进。这场演进的本质,是从优化单次模型调用的输入,升级为设计模型外围的工程化运行框架——包括执行环境、工具接口、上下文管理、任务编排、可观测性与治理。
如果说提示工程阶段,开发者扮演的是“咒语师”——通过精雕细琢每一行指令来引导模型输出;那么Agent编排阶段,开发者则升级为“指挥官”——需要设计系统架构、编排工具调用、管理多Agent协作。本文将聚焦这一演进的核心命题:如何将单轮对话扩展为可执行、可控制、可追踪的复杂任务流程,并通过代码示例展示具体的工程实践。
二、从静态提示到结构化提示工程
2.1 提示工程的局限
传统提示工程的核心问题是“一次性输入-输出”:开发者将所有任务描述、约束条件、示例一次性塞入上下文窗口,模型在单次推理中完成全部输出。这种模式在简单问答场景中尚可胜任,但面对需要多步推理、工具调用、动态决策的复杂任务时,暴露出三大缺陷:上下文窗口限制导致信息丢失、单次推理缺乏修正机制、静态提示难以应对动态需求。
2.2 结构化提示词设计
进入Agent编排时代,提示词本身也需要结构化。核心思路是将提示词拆解为三个层次:
- 系统提示词:角色定位、任务描述、输出格式约束
- 工具定义:可用工具的语义契约(名称、描述、参数Schema)
- 动态上下文:检索到的外部知识、对话记忆、任务状态
以下是一个结构化提示词模板的示例,用于指导Agent进行多工具调用:
SYSTEM_PROMPT_TEMPLATE = """
你是一个智能助手,可以通过调用工具完成复杂任务。
## 可用工具
{tools_description}
## 输出格式
你必须以JSON格式输出,包含以下字段之一:
- 如果需要调用工具:{{"action": "工具名称", "args": {{"参数名": "参数值"}}}}
- 如果任务已完成:{{"final": "最终回答"}}
## 任务
{user_query}
## 约束
1. 每次只能调用一个工具
2. 调用工具后,根据观察结果决定下一步
3. 不要编造信息,所有事实必须来自工具返回结果
"""
结构化提示词的价值在于:它为模型提供了明确的“行为契约”,使输出可解析、可验证,为后续的工具调用循环奠定基础。
三、核心架构:工具调用循环与ReAct模式
3.1 ReAct:推理与行动的闭环
ReAct(Reason + Act)是Agent编排最基础的执行模式。其核心循环为:思考(Thought)→ 行动(Action)→ 观察(Observation)→ 思考…… 。模型不再是“一次性输出答案”,而是在每一步中决定是调用工具还是给出最终回答。

以下是一个ReAct Agent的简化实现(Python),展示了工具调用循环的核心逻辑:
import json
from typing import List, Dict, Any
from openai import OpenAI
class ReActAgent:
def __init__(self, tools: List[Dict[str, Any]], system_prompt: str):
self.tools = tools
self.system_prompt = system_prompt
self.client = OpenAI()
self.max_steps = 10
def run(self, query: str) -> str:
messages = [
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": query}
]
for step in range(self.max_steps):
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
response_format={"type": "json_object"}
)
output = json.loads(response.choices[0].message.content)
# 检查是否完成
if "final" in output:
return output["final"]
# 执行工具调用
if "action" in output:
tool_name = output["action"]
tool_args = output.get("args", {})
# 查找并执行工具
tool_result = self._call_tool(tool_name, tool_args)
# 将观察结果追加到对话历史
messages.append({"role": "assistant", "content": response.choices[0].message.content})
messages.append({"role": "user", "content": f"Observation: {tool_result}"})
return "任务超出最大步数限制"
def _call_tool(self, name: str, args: Dict) -> str:
# 根据工具名称路由到具体实现
for tool in self.tools:
if tool["name"] == name:
return tool["handler"](**args)
return f"Error: 未找到工具 {name}"
3.2 工具定义的标准化
为了让模型正确调用工具,需要将工具以“语义契约”的形式告知模型。OpenAI Agents SDK和MCP协议都采用了类似的工具描述方式:
# 工具定义示例:查询天气
weather_tool = {
"name": "get_weather",
"description": "查询指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海'"
}
},
"required": ["city"]
},
"handler": lambda city: f"{city}今日天气:晴,25°C" # 实际实现会调用API
}
工具定义的标准化使得模型与外部系统的交互变得可预测、可审计,是Agent编排从“Demo”走向“生产”的关键基础设施。
四、复杂任务编排:从单Agent到多Agent协作
4.1 提示链:单Agent的结构化推理
当任务具有明确的步骤依赖关系时,可以采用**提示链(Prompt Chaining)**模式:每一步的输出成为下一步的输入,通过结构化的进展建立分析深度。
以下是一个金融分析提示链的实现片段,展示了如何将“提取指标→基准分析→生成评论”三步串联:
from agent_framework.foundry import FoundryChatClient
import json
def execute_analysis_chain(financial_text: str):
# Step 1: 提取关键财务指标
extract_prompt = f"""
从以下SEC文件中提取关键财务指标,返回JSON格式:
{financial_text}
输出格式: {{"revenue": xxx, "operating_margin": xxx, "debt_to_equity": xxx}}
"""
metrics = json.loads(chat_client.complete(extract_prompt))
# Step 2: 基准分析(依赖Step 1的输出)
benchmark_prompt = f"""
将以下指标与行业平均水平对比:
{json.dumps(metrics)}
返回百分位排名和行业上下文。
"""
benchmark = chat_client.complete(benchmark_prompt)
# Step 3: 生成投资评论(依赖Step 2的输出)
comment_prompt = f"""
基于以下基准分析,生成专业的投资评论:
{benchmark}
要求:客观、有数据支撑、包含风险提示。
"""
return chat_client.complete(comment_prompt)
提示链的核心优势在于:每个步骤只需处理特定的上下文,降低了单次推理的复杂度,提高了输出的一致性。
4.2 多Agent协作:Agent-as-Tool模式
对于更复杂的任务,单个Agent难以同时掌握多个领域的专业知识。多Agent协作通过将任务分配给多个专家Agent,各自处理后再汇总结果,实现了“1+1>2”的效果。
OpenAI Agents SDK推荐的“Agent-as-Tool”模式,是由一个中心Agent将其他专家Agent作为工具调用,保持单一控制流的同时实现并行执行:
from agents import Agent, function_tool, Runner
# 定义三个专家Agent(简化为函数工具)
@function_tool
async def fundamental_analysis(company: str) -> str:
"""基本面分析:评估公司财务状况、管理层质量"""
return f"{company}基本面分析结果:营收增长15%,利润率稳步提升..."
@function_tool
async def macro_analysis(query: str) -> str:
"""宏观经济分析:评估利率、通胀、政策环境"""
return "当前宏观环境:利率处于下行周期,通胀可控..."
@function_tool
async def quantitative_analysis(symbol: str) -> str:
"""量化分析:技术指标、动量因子、估值模型"""
return f"{symbol}量化信号:RSI=65,处于中性偏强区间..."
# 中心编排Agent
portfolio_manager = Agent(
name="Portfolio Manager",
instructions="""
你是一位投资组合经理。接到用户的投资研究请求后:
1. 并行调用三个专家工具:fundamental_analysis、macro_analysis、quantitative_analysis
2. 综合三个专家的输出,生成一份完整的投资备忘录
3. 备忘录需包含风险提示和投资建议
""",
tools=[fundamental_analysis, macro_analysis, quantitative_analysis],
model_settings={"parallel_tool_calls": True} # 关键:允许并行调用
)
# 执行
result = await Runner.run(portfolio_manager, "分析GOOGL的投资价值")
这种架构的核心优势在于模块化:每个专家Agent可以独立迭代优化,中心Agent只负责编排和综合,系统可扩展性极强。
4.3 分支链:基于条件路由的动态决策
在某些场景中,任务路径取决于中间步骤的输出。**分支链(Branching Chain)**模式允许根据前一步的结果动态选择后续执行路径:
def execute_branching_chain(financial_metrics: dict):
# Step 1: 分类
classification = classify_company(financial_metrics)
# Step 2: 根据分类路由到不同分支
if classification == "GROWTH_DRIVEN":
return valuation_dcf_branch(financial_metrics) # 折现现金流
elif classification == "MATURE_EARNINGS":
return valuation_multiples_branch(financial_metrics) # 可比倍数
else:
return valuation_asset_branch(financial_metrics) # 资产估值
分支链使得Agent编排能够适应输入数据的多样性,而不是对所有场景套用同一套流程。
五、工程实践:落地MCP与Skill驱动架构
5.1 MCP:工具接口标准化
MCP(Model Context Protocol)为Agent与外部工具之间的通信提供了标准协议。通过MCP,工具以统一的方式暴露给模型,模型无需关心工具的具体实现细节。
以下是一个MCP Server的简化实现,封装了公共假日查询API:
from mcp.server import Server, Tool
import httpx
@mcp.tool()
async def is_public_holiday(country_code: str, date: str) -> bool:
"""
查询指定国家在指定日期是否为公共假日。
Args:
country_code: ISO国家代码,如'US'、'CN'
date: 日期,格式'YYYY-MM-DD'
Returns:
是否为公共假日
"""
async with httpx.AsyncClient() as client:
response = await client.get(
f"https://date.nager.at/api/v3/PublicHoliday/{date}/{country_code}"
)
return response.status_code == 200
MCP的核心价值在于解耦:工具开发者只需关注工具本身的实现,Agent开发者只需关注工具的语义契约,两者通过标准协议对接,互不干扰。
5.2 Skill:自然语言编写的“程序”
Skill是比普通提示词更高层次的抽象——它不是一次性的指令,而是用自然语言编写的、带执行逻辑的“程序”,明确告诉模型“按什么步骤组合哪些工具”。
以下是一个值班假日检查Skill的示例(Markdown格式):
# Skill: 值班假日检查
## 目的
判断当前值班工程师所在国家今天是否有公共假日,若有则列出其名下的高优先级问题。
## 可用工具
- get_current_oncall: 获取当前值班工程师信息
- is_public_holiday: 查询指定国家在指定日期是否为公共假日
- list_open_issues: 列出工程师名下的开放问题
## 执行步骤
1. 调用 get_current_oncall 获取值班工程师姓名和所在国家
2. 调用 is_public_holiday,传入国家代码和今天日期,判断是否为假日
3. 如果是假日,调用 list_open_issues,筛选P0/P1级别问题
4. 汇总结果,按指定模板输出
## 输出模板
值班正常/需备班:[姓名]([国家]),今天是[工作日/假日]。[若为假日,列出P0/P1问题]
Skill的本质是将Agent的“工作流”从代码中抽离出来,用自然语言编写,这使得非技术人员也能参与Agent行为的调优,同时也让Agent的行为更加透明、可审计。
六、效果优化与性能治理
6.1 上下文衰减的对抗策略
在长周期任务中,上下文信息会随交互轮次增加而“腐烂”——早期信息被遗忘,逻辑出现断裂。应对策略包括:
- 结构化记忆管理:区分短期记忆(当前对话窗口)、长期记忆(向量数据库存储)、工作记忆(任务相关的知识图谱)
- 里程碑检查点:在关键步骤固化阶段性成果到长期记忆
- 主动澄清机制:当检测到上下文歧义时,Agent主动发起澄清对话
6.2 可观测性:Agent运行的“黑匣子”
Harness工程将“可观测性”视为独立架构层,要求捕获每一次工具调用、每一轮推理的轨迹、成本和失败信号。OpenAI Agents SDK提供了Traces功能,可实时监控Agent的每一步决策:
from agents import add_trace_processor, trace
# 开启链路追踪
add_trace_processor(BatchTraceProcessor(FileSpanExporter()))
with trace("investment_analysis"):
result = await Runner.run(portfolio_manager, query)
# 所有工具调用、Agent决策、耗时都会被记录

可观测性不仅是调试工具,更是持续优化的数据基础——通过分析失败模式,可以针对性地调整提示词、工具定义或编排逻辑。
七、结语
从提示工程到Agent编排的演进,本质上是AI应用从**“提示词调优”走向“系统工程”**的过程。开发者不再只是思考“怎么写提示词”,而是需要设计整个执行框架:工具如何定义和调用?上下文如何管理和注入?多Agent如何协作?任务如何追踪和验证?
这一转变也意味着开发者的角色升级——从“咒语师”变为“指挥官”,从“单次对话的设计者”变为“复杂任务系统的架构师”。掌握Agent编排能力,已成为AI应用开发者的核心竞争力。
更多推荐


所有评论(0)