Modify TypeScript LangChain agent configuration and behavior. Use when: (1) User wants to change agent settings, (2) Add/remove tools, (3) Update system prompt, (4) Change model parameters.
65
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./agent-langchain-ts/.claude/skills/modify-agent/SKILL.md| File | Purpose | When to Edit |
|---|---|---|
src/agent.ts | Agent logic, tools, prompt | Change agent behavior |
src/tools.ts | Tool definitions | Add/remove tools |
src/mcp-servers.ts | MCP server connections | Add Databricks resources |
app.yaml | Runtime configuration | Env vars, resources |
databricks.yml | Bundle resources | Permissions, targets |
.env | Local environment | Local development |
| File | Purpose |
|---|---|
src/framework/server.ts | Express server, request routing |
src/framework/tracing.ts | MLflow/OTel tracing setup |
src/framework/routes/invocations.ts | Responses API SSE streaming |
| Directory | Contents |
|---|---|
tests/ | ✏️ Agent unit & integration tests — add yours here |
tests/e2e/ | ✏️ End-to-end tests against deployed app |
tests/framework/ | Framework tests — no need to modify |
tests/e2e/framework/ | Framework e2e tests — no need to modify |
In .env (local):
DATABRICKS_MODEL=databricks-gpt-5-2In app.yaml (deployed):
env:
- name: DATABRICKS_MODEL
value: "databricks-gpt-5-2"Available models:
databricks-claude-sonnet-4-5databricks-gpt-5-2databricks-meta-llama-3-3-70b-instructEdit src/agent.ts:
const DEFAULT_SYSTEM_PROMPT = `You are a helpful AI assistant specialized in [YOUR DOMAIN].
Your key capabilities:
- [Capability 1]
- [Capability 2]
When answering:
- [Instruction 1]
- [Instruction 2]
Be concise but thorough.`;Or pass custom prompt when creating agent:
const agent = await createAgent({
systemPrompt: "Your custom instructions here...",
});Temperature (0.0 = deterministic, 1.0 = creative):
.env:
TEMPERATURE=0.7app.yaml:
env:
- name: TEMPERATURE
value: "0.7"Max Tokens:
.env:
MAX_TOKENS=4000app.yaml:
env:
- name: MAX_TOKENS
value: "4000"Use Responses API (for citations, reasoning):
.env:
USE_RESPONSES_API=trueEdit src/tools.ts:
import { tool } from "@langchain/core/tools";
import { z } from "zod";
export const myCustomTool = tool(
async ({ param1, param2 }) => {
// Tool logic here
return `Result: ${param1} and ${param2}`;
},
{
name: "my_custom_tool",
description: "Description of what this tool does",
schema: z.object({
param1: z.string().describe("Description of param1"),
param2: z.number().describe("Description of param2"),
}),
}
);Add to tool list:
export function getBasicTools() {
return [
weatherTool,
calculatorTool,
timeTool,
myCustomTool, // Add here
];
}For adding MCP tools (SQL, Vector Search, Genie, UC Functions), see the add-tools skill.
MCP tools are configured in src/mcp-servers.ts with required permissions in databricks.yml.
Edit src/tools.ts:
export function getBasicTools() {
return [
weatherTool,
// calculatorTool, // Commented out to disable
timeTool,
];
}Or filter tools:
export function getBasicTools() {
const allTools = [weatherTool, calculatorTool, timeTool];
return allTools.filter(t => t.name !== "calculator");
}The agent uses standard LangGraph createReactAgent API in src/agent.ts:
import { createReactAgent } from "@langchain/langgraph/prebuilt";
export async function createAgent(config: AgentConfig = {}) {
// Create chat model
const model = new ChatDatabricks({
model: modelName,
useResponsesApi,
temperature,
maxTokens,
});
// Load tools (basic + MCP if configured)
const tools = await getAllTools(mcpServers);
// Create agent using standard LangGraph API
const agent = createReactAgent({
llm: model,
tools,
});
return new StandardAgent(agent, systemPrompt);
}The LangGraph agent automatically handles:
Edit src/framework/server.ts:
// New endpoint example
app.post("/api/evaluate", async (req: Request, res: Response) => {
const { input, expected } = req.body;
const response = await invokeAgent(agent, input);
// Custom evaluation logic
const score = calculateScore(response.output, expected);
res.json({
input,
output: response.output,
expected,
score,
});
});Edit src/framework/tracing.ts or initialize with custom config in src/framework/server.ts:
const tracing = initializeMLflowTracing({
serviceName: "my-custom-service",
experimentId: process.env.MLFLOW_EXPERIMENT_ID,
useBatchProcessor: false, // Use simple processor for debugging
});.env:
PORT=3001app.yaml:
env:
- name: PORT
value: "3001"Edit src/server.ts to customize streaming behavior:
if (stream) {
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
res.setHeader("X-Accel-Buffering", "no"); // Disable buffering
// Custom streaming logic
try {
for await (const chunk of streamAgent(agent, userInput, chatHistory)) {
// Add custom formatting
const formatted = {
chunk,
timestamp: Date.now(),
};
res.write(`data: ${JSON.stringify(formatted)}\n\n`);
}
res.write(`data: ${JSON.stringify({ done: true })}\n\n`);
res.end();
} catch (error) {
// Handle errors
}
}After modifying agent:
# Test locally
npm run dev
# Run tests
npm test
# Build to check for TypeScript errors
npm run buildSee the deploy skill for complete deployment instructions.
For advanced LangChain patterns (custom chains, stateful agents, RAG), see:
Use DatabricksVectorSearch from @databricks/langchainjs. See LangChain Vector Store docs.
Define interfaces for agent inputs/outputs:
interface AgentInput {
messages: AgentMessage[];
config?: AgentConfig;
}
interface AgentOutput {
message: AgentMessage;
intermediateSteps?: ToolStep[];
metadata?: Record<string, any>;
}Keep modules focused:
src/agent.ts: Agent logic onlysrc/tools.ts: Tool definitions onlysrc/framework/server.ts: API routes onlysrc/framework/tracing.ts: Tracing setup onlyAlways handle promises properly:
// Good
try {
const result = await agent.invoke(input);
return result;
} catch (error) {
console.error("Agent error:", error);
throw error;
}
// Bad
agent.invoke(input).then(result => {
// ...
});The agent already includes comprehensive logging in src/agent.ts:
// Tool execution logging (already included)
console.log(`✅ Agent initialized with ${tools.length} tool(s)`);
console.log(` Tools: ${tools.map((t) => t.name).join(", ")}`);
// Add more logging in streamEvents() method
if (event.event === "on_tool_start") {
console.log(`[Tool] Calling ${event.name} with:`, event.data?.input);
}console.log("Agent input:", input);
console.log("Tool calls:", response.intermediateSteps);
console.log("Final output:", response.output);Check for type errors:
npx tsc --noEmitfdc1b49
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.