大家好,我是程序员小策。
上周五下午,我正在调试一个 AI Agent 系统,这个 Agent 本该帮我自动分析代码仓库并生成技术文档。我满怀期待地点击"运行",结果它给我返回了一堆毫无逻辑的文本------一会儿在分析代码,一会儿又跑去写单元测试,最后还莫名其妙地删除了几个关键文件。
我盯着屏幕上的错误日志,陷入了沉思:为什么同样的 LLM 模型,别人家的 Agent 能优雅地完成任务,而我写的却像个失控的熊孩子?
答案藏在 Prompt Engineering 里。这不仅仅是"写几句话"那么简单,而是一门需要系统化思维和工程化实践的技艺。今天,我们就来聊聊如何通过高质量的 Prompt 设计,让你的 AI Agent 从"熊孩子"变成"靠谱助手"。
问题定义:为什么 Prompt 如此重要?
在 AI Agent 系统中,Prompt 就像是给 AI 下的"指令书"。一个模糊的指令,会让 AI 在执行过程中迷失方向;而一个清晰、结构化的指令,则能让 AI 精准地完成任务。
灵魂拷问:
你有没有遇到过这样的情况:明明把任务描述得很清楚,AI 却总是理解偏了?或者 AI 执行到一半突然"跑偏",去做了一些你根本没让它做的事情?又或者,你的 Agent 在处理复杂任务时,总是无法保持上下文一致性?
这些问题的根源,往往不在于 AI 模型本身的能力,而在于 Prompt 的设计是否足够专业。一个优秀的 Prompt,应该具备以下特征:
- 明确的任务边界:告诉 AI 该做什么,不该做什么
- 清晰的执行步骤:将复杂任务拆解为可执行的子步骤
- 完整的上下文信息:提供必要的背景知识和约束条件
- 结构化的输出格式:定义清晰的返回格式,便于后续处理
核心概念:Prompt Engineering 的工程化实践
Prompt Engineering 是指通过设计和优化提示词(Prompt),引导大语言模型(LLM)生成符合预期的输出的技术。它不仅涉及自然语言的表达技巧,更包含任务分解、上下文管理、工具调用编排等工程化实践。
如果把 AI Agent 比作一个厨师,那么 Prompt Engineering 就是给这个厨师写的"菜谱"。一个糟糕的菜谱可能写着"做一道好吃的菜",厨师只能一脸懵逼;而一个专业的菜谱会详细列出食材、步骤、火候、注意事项,让厨师能够精准地还原预期菜品。
在工程实践中,Prompt Engineering 的核心要素包括:
- 角色定义(Role Definition):明确 AI 的身份和能力边界
- 任务描述(Task Description):清晰说明要完成的目标
- 工具使用指南(Tool Usage Guide):告诉 AI 如何使用可用工具
- 约束条件(Constraints):设定不可逾越的边界
- 输出规范(Output Specification):定义返回数据的格式和结构
代码实现:从理论到实践
让我们通过一个实际的 MCP (Model Context Protocol) 工具管理案例,来看看专业的 Prompt 是如何设计的。以下代码来自一个生产级的 AI Agent 系统:
python
# 任务委派 Prompt 示例
ASSIGN_SUB_ASSISTANT_PROMPT = """
Delegate a task to a sub-assistant
## Args
- agent_identity (str): Sub-agent's name and role in format `name[role]`, e.g: `Alice[Coder]`
- system_prompt (str): System prompt that used to define Sub-agent's characteristics
- task_description (str): The final objective of the task
- instruction (str): Detailed instructions for the sub-agent
## Returns
- str: task id
## Note
- This tool creates a sub-agent with the same capabilities as you (include callable tools, available skills and so on)
- The sub-agent will autonomously work to complete the task
- Once the task is assigned, this tool returns immediately
## When to Use
Use this tool when:
1. The task may take a long time to complete
2. The user explicitly asks you to assign some work to another assistant
3. You are continuing a previous conversation with the sub-assistant (Use the same `agent_identity` in this case)
Typical scenarios:
1. Background processing
2. Delegating complex or time-consuming work
## When NOT to Use
Do NOT use this tool when:
1. The task is simple and can be completed directly
2. The user explicitly asks you to handle the task yourself
3. The task depends heavily on your current reasoning context
## Important Guidelines
How to Write the Task:
task_description:
Provide a concise description of the task's final goal. This description is visible to you and the user, but not to the sub-agent
- After assigning the task → add this description to your TODO list and mark TODO as **in progress**
- When the task is compeleted → mark TODO as **completed**
instruction:
The detailed instructions for the sub-agent
It should include:
- A detailed task goal
- task context
- workspace directory (create one if directory is not exist on disk)
- relevant information
- constraints (list clearly)
- expected output format (if any)
The instruction must be self-contained because the sub-agent does not have access to your conversation history or reasoning content
Do not reference previous messages such as "above", "earlier", or "previous analysis"
"""
这个 Prompt 展示了专业级 Prompt 设计的几个关键点:
- 结构化分区 :使用
## Args、## Returns、## Note等标题,让 AI 快速定位关键信息 - 明确的边界 :通过
When to Use和When NOT to Use两个部分,清晰定义了工具的适用场景 - 详细的指南 :
Important Guidelines部分提供了具体的操作建议,避免 AI 猜测
再来看一个文件操作的 Prompt 示例:
python
WRITE_WORKSPACE_FILE_PROMPT = """
Create a new file or rewrite a exist file inside sandbox workspace
## Args
- file_path (str): File path inside workspace
- content (str): File content
- exist_ok (bool): Overwrite entire file if the file is already exists
## Returns
- str: Success or error message
## Note
- If the file already exists and exist_ok is False, this tool will return an error message and do nothing
## Important Guidelines
- If you just want to create a new file, ensure the value of `exist_ok` is False
- If you want to overwrite an existing file with new content, ensure the value of `exist_ok` is True
"""
这个 Prompt 虽然简短,但包含了所有必要的信息:参数说明、返回值、注意事项和操作指南。更重要的是,它通过 exist_ok 参数的设计,避免了 AI 在文件操作时的常见错误。
边界陷阱:Prompt 设计中的常见坑
在实际工程中,Prompt 设计有几个常见的陷阱:
陷阱一:模糊的任务描述
python
# 错误示例
BAD_PROMPT = "请帮我分析这个代码仓库"
# 正确示例
GOOD_PROMPT = """
Analyze the code repository and generate a technical document
## Task Breakdown
1. Scan the directory structure and identify main modules
2. Analyze the core classes and their dependencies
3. Extract API endpoints and their request/response formats
4. Generate a markdown document with the following sections:
- Project Overview
- Architecture Design
- API Reference
- Deployment Guide
## Constraints
- Only analyze Python files (*.py)
- Skip test files and virtual environment directories
- Maximum document length: 5000 words
"""
陷阱二:缺少上下文信息
AI 没有你的记忆,它不知道之前的对话内容。因此,每个 Prompt 都应该是自包含的:
python
# 错误示例 - 依赖上下文
BAD_PROMPT = "继续上面的任务"
# 正确示例 - 自包含
GOOD_PROMPT = """
Continue the code analysis task
## Previous Context
- We have scanned the `/src` directory and found 15 Python files
- We identified 3 main modules: `auth`, `api`, `database`
- The next step is to analyze the `auth` module
## Current Task
Analyze the `auth` module:
1. List all classes and their responsibilities
2. Identify authentication mechanisms
3. Document the OAuth 2.0 flow implementation
"""
陷阱三:忽略错误处理
AI 在执行过程中可能会遇到各种异常情况,优秀的 Prompt 应该包含错误处理指南:
python
# 包含错误处理的 Prompt
FILE_OPERATION_PROMPT = """
Read a file from the workspace
## Args
- file_path (str): File path inside workspace
## Returns
- str: File content or error message
## Error Handling
If the file does not exist:
1. Return a clear error message: "File not found: {file_path}"
2. Suggest alternative file paths if similar files exist
3. Ask the user if they want to create the file
If the file is too large (>10MB):
1. Return a warning message
2. Suggest reading the file in chunks
3. Provide the first 100 lines as a preview
"""
分布式考量:多 Agent 协作中的 Prompt 设计
在分布式 AI Agent 系统中,Prompt 设计面临更大的挑战。多个 Agent 之间需要协调工作,而每个 Agent 都有自己的 Prompt。这时候,需要考虑以下几个问题:
问题一:任务分解与委派
当主 Agent 需要将任务委派给子 Agent 时,Prompt 必须清晰地定义子 Agent 的职责:
python
# 任务委派 Prompt(来自实际生产系统)
DELEGATION_PROMPT = """
You are a sub-agent specialized in code review
## Your Role
- Review Python code for potential bugs
- Check code style against PEP 8 standards
- Identify security vulnerabilities
## Your Tools
- `read_file`: Read file content
- `run_linter`: Execute pylint
- `run_tests`: Execute unit tests
## Your Constraints
- Only review files in the `/src` directory
- Do not modify any files
- Maximum review time: 5 minutes
## Expected Output
Return a JSON object:
{
"file_path": "path/to/file.py",
"issues": [
{
"line": 42,
"severity": "error",
"message": "Unused import 'numpy'"
}
],
"summary": "Found 3 issues in this file"
}
"""
问题二:上下文隔离与传递
在多 Agent 系统中,每个 Agent 都有独立的上下文。因此,Prompt 必须包含所有必要的信息:
python
# 上下文传递 Prompt
CONTEXT_TRANSFER_PROMPT = """
## Task Context
You are continuing a multi-step workflow
## Previous Steps Completed
1. ✅ Data collection: Gathered 1000 user records from database
2. ✅ Data cleaning: Removed 50 duplicate records
3. ⏳ Current step: Data analysis
## Your Task
Perform statistical analysis on the cleaned dataset:
- Calculate average user age
- Identify top 5 most common user actions
- Generate a distribution chart
## Available Resources
- Cleaned dataset: `/workspace/cleaned_data.csv`
- Analysis scripts: `/workspace/scripts/analyze.py`
## Output Requirements
Save results to `/workspace/analysis_results.json`
"""
问题三:生命周期管理
在 MCP (Model Context Protocol) 架构中,工具的生命周期管理至关重要。以下是一个生产级的 MCP 工具管理实现:
python
import asyncio
from contextlib import _AsyncGeneratorContextManager
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_core.tools.base import BaseTool
class MCPContextHolder:
"""管理 MCP 工具的生命周期"""
def __init__(
self,
mcp_id: str,
mcp_name: str,
lifecycle: str,
cm: _AsyncGeneratorContextManager,
):
self.mcp_id = mcp_id
self.mcp_name = mcp_name
self.lifecycle = lifecycle
self.cm = cm
self.session = None
self.tools: list[BaseTool] | None = None
self._queue: asyncio.Queue = asyncio.Queue()
self._worker_task: asyncio.Task | None = None
async def start(self):
"""启动 MCP 工具会话"""
if self._worker_task:
return
loop = asyncio.get_running_loop()
ready = loop.create_future()
self._worker_task = asyncio.create_task(
self._run(ready),
name=f"mcp-lifecycle-{self.mcp_name}",
)
await ready
async def _run(self, ready_future: asyncio.Future):
"""运行 MCP 工具的主循环"""
try:
self.session = await self.cm.__aenter__()
if not ready_future.done():
ready_future.set_result(True)
while True:
action, future = await self._queue.get()
if action == "close":
try:
await self.cm.__aexit__(None, None, None)
if not future.done():
future.set_result(True)
except Exception as e:
if not future.done():
future.set_exception(e)
break
except Exception as e:
if not ready_future.done():
ready_future.set_exception(e)
raise
finally:
self.session = None
self.tools = None
async def stop(self):
"""停止 MCP 工具会话"""
if not self._worker_task:
return
if self._worker_task.done():
try:
await self._worker_task
except Exception as e:
logger.error(
f"[MCPContextHolder.stop] "
f"Worker already failed for '{self.mcp_name}': {e}"
)
finally:
self._worker_task = None
self.session = None
self.tools = None
return
loop = asyncio.get_running_loop()
future = loop.create_future()
await self._queue.put(("close", future))
await future
try:
await self._worker_task
finally:
self._worker_task = None
self.session = None
self.tools = None
async def get_tools(self) -> list[BaseTool]:
"""获取 MCP 工具列表"""
if self.tools is None:
self.tools = await load_mcp_tools(self.session)
return self.tools
这段代码展示了如何管理 MCP 工具的生命周期,包括启动、运行、停止等操作。关键点在于:
- 异步生命周期管理 :使用
asyncio.Queue实现异步任务队列 - 会话保持 :通过
session属性保持与 MCP 服务器的连接 - 工具缓存 :使用
tools属性缓存已加载的工具,避免重复加载 - 优雅关闭 :通过
_queue机制实现优雅关闭,避免资源泄漏
对比表格:不同 Prompt 设计策略的权衡
| 设计策略 | 优点 | 缺点 | 适用场景 | 示例 |
|---|---|---|---|---|
| 结构化 Prompt | 清晰易读,AI 理解准确,易于维护 | 编写成本高,需要详细设计 | 生产级系统,复杂任务 | MCP 工具 Prompt |
| 自由文本 Prompt | 编写简单,灵活度高 | AI 理解偏差大,难以预测 | 简单任务,快速原型 | "帮我分析代码" |
| 模板化 Prompt | 可复用,标准化程度高 | 缺乏灵活性,需要参数填充 | 重复性任务,批量处理 | 文件操作 Prompt |
| Few-shot Prompt | 提供示例,学习效果好 | Token 消耗大,示例选择关键 | 需要特定格式的任务 | 代码生成 Prompt |
| Chain-of-Thought Prompt | 推理能力强,适合复杂任务 | 输出冗长,可能偏离主题 | 数学推理,逻辑分析 | 问题求解 Prompt |
从表格可以看出,结构化 Prompt 在生产环境中具有明显优势,虽然编写成本较高,但其准确性和可维护性使其成为企业级 AI Agent 系统的首选。
面试追问:深度考察 Prompt Engineering 能力
如果你在面试中被问到以下问题,该如何回答?
问题一:如何设计一个多轮对话的 Prompt?
关键点:
- 上下文管理 :使用
memory机制保存关键信息 - 状态追踪 :通过
todo list跟踪任务进度 - 错误恢复:设计重试机制和回滚策略
python
# 多轮对话 Prompt 设计
MEMORY_MANAGEMENT_PROMPT = """
Write / overwrite / delete a memory
## Args
- memories (list[Memory]): List of memory operations to perform in batch.
Each memory item must contain:
- title (str): Memory title, must not be empty.
- abstract (Optional[str]): Brief summary of the memory.
- content (str): Memory content. If empty or only whitespace, the memory will be deleted.
## When to Use This Tool
Use this tool in these scenarios:
1. When you are making an important decision
2. When defining constraints, rules, or policies that must be remembered
3. When you make a tool call, the summary or conclusion of the call result that must be remembered
4. When summarizing a important conclusion or observations that must be remembered
5. When you observe that a memo in your memory is outdated and should be deleted
## Important Guidelines
- Record only high-value, decision-level, conclusion-related information
- Do not restate the entire conversation
- Focus on what must be remembered for correct future behavior
- Avoid duplicating todo content
"""
问题二:如何处理 Prompt 的 Token 限制?
策略:
- 分层设计:将 Prompt 分为核心部分和扩展部分
- 动态加载:根据任务需要动态加载相关上下文
- 压缩技术:使用摘要和关键词提取减少 Token 消耗
- 分块处理:将大任务拆分为多个小任务
问题三:如何评估 Prompt 的质量?
评估维度:
- 准确性:AI 输出是否符合预期
- 一致性:多次执行是否产生相同结果
- 鲁棒性:对输入变化的适应能力
- 效率:Token 消耗和执行时间
总结:Prompt Engineering 的工程化思维
Prompt Engineering 不是简单的"写几句话",而是一门需要系统化思维的工程学科。通过本文的分析,我们可以总结出以下最佳实践:
- 结构化设计:使用清晰的分区和标题,让 AI 快速理解 Prompt 结构
- 明确边界 :通过
When to Use和When NOT to Use定义工具适用场景 - 自包含原则:每个 Prompt 都应该包含完整的上下文信息
- 错误处理:预设异常情况的处理策略
- 生命周期管理:在分布式系统中,合理管理工具和会话的生命周期
回到文章开头的场景,当我重新设计了 Agent 的 Prompt 后,它终于能够准确地完成任务:先扫描代码仓库,再分析核心模块,最后生成结构化的技术文档。整个过程中,Agent 不再"跑偏",而是严格按照 Prompt 中定义的步骤执行。
这就是 Prompt Engineering 的魅力------它让 AI 从"失控的熊孩子"变成了"靠谱的助手"。而这背后,是工程师对任务分解、上下文管理、工具编排的深刻理解。
下次当你面对一个"不听话"的 AI Agent 时,不妨先检查一下你的 Prompt 设计。也许,问题不在于 AI 的能力,而在于你给它的"菜谱"不够清晰。
参考资料:
- Model Context Protocol (MCP) 官方文档
- LangChain MCP Adapters 源码
- Prompt Engineering Guide (https://www.promptingguide.ai/)
相关文章推荐:
- Agent Harness:从裸调LLM到生产级Agent的工程实践(./Agent Harness:从裸调LLM到生产级Agent的工程实践.md)
- Context工程:从全量塞入到智能记忆管理------AI应用上下文窗口的生存法则
- 给AI写一份老厨师的菜谱:从传统文档到Skill知识体系