how to use function_tool arguments?
# ask-ai
b
how to use function_tool arguments?
t
Thanks for reaching out, mateuszkasprowicz. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
You're asking how to use
function_tool
arguments — I'll explain how to define and receive them and show short Python and Node.js examples. Key points • Arguments are defined by the function signature (Python) or a parameter schema (Node.js) and are passed from the LLM when it calls the tool. • Include
RunContext
(Python) or
{ ctx }
(Node.js) in the parameters if your tool needs access to session/agent state. • Describe each argument in the docstring (Python) or via Zod
.describe()
(Node.js) so the LLM knows what to pass. • For advanced usage, you can supply a raw JSON schema and receive a
raw_arguments
dict. Python example
Copy code
@function_tool()
async def lookup_weather(context: RunContext, location: str) -> dict[str, Any]:
    """Look up weather information.

    Args:
        location: The location to look up weather information for.
    """
    return {"weather": "sunny", "temperature_f": 70}
• The LLM will call
lookup_weather
and pass
location
as a string. Use
context
to access session or agent state. Raw-schema Python example
Copy code
@function_tool(raw_schema=raw_schema)
async def get_weather(raw_arguments: dict[str, object], context: RunContext):
    location = raw_arguments["location"]
    return f"The weather in {location} is ..."
Node.js (Zod) example
Copy code
const lookupWeather = llm.tool({
  description: "Look up weather information for a given location.",
  parameters: z.object({
    location: z.string().describe("The location to look up weather information for."),
  }),
  execute: async ({ location }, { ctx }) => {
    return { weather: "sunny", temperatureF: 70 };
  },
});
Error handling • Validate arguments inside the tool and raise a
ToolError
(Python) or throw an error (Node) to return meaningful feedback if input is invalid. Best practices • Keep parameter names clear and use types/type hints. • Mark required fields in schemas. • Put helpful descriptions in docstrings or Zod
.describe()
to improve the LLM's argument generation. • Use `RunContext`/`ctx` when you need agent/session data. If you want, tell me which language (Python or Node.js) and share the function signature you plan to expose — I can give a tailored example or a JSON schema for your tool. Sources: Agents v0.x migration guide - Python | LiveKit docs | Agents v0.x migration guide - Node.js | LiveKit Docs | Tool definition and use | LiveKit docs
b
so let's say I want to have a tool that analyzes current transcript and returns true or false - how would you implement?
t
You're asking how to implement a tool that analyzes the current transcript and returns true/false. Below are two concise implementations — Python and Node.js — plus notes on where the transcript comes from and simple variations. Tell me which language you want to use and whether to analyze all messages or only user messages. Python (LiveKit Agents)
Copy code
from livekit.agents import Agent, function_tool, RunContext
from livekit.agents.llm import ChatContext, ChatMessage

class MyAgent(Agent):
    @function_tool()
    async def transcript_contains_topic(self, context: RunContext, topic: str) -> bool:
        """Return True if `topic` appears in the current transcript."""
        chat_ctx: ChatContext = context.session.chat_ctx
        # Combine text from all ChatMessage entries (change filter to restrict to user messages)
        transcript = " ".join(
            (msg.text_content() or "") for msg in chat_ctx.messages if isinstance(msg, ChatMessage)
        ).lower()
        return topic.lower() in transcript
Node.js (Zod schema for the tool)
Copy code
import { z } from "zod";

const transcriptContainsTopic = llm.tool({
  description: "Return true if topic appears in the current transcript.",
  parameters: z.object({
    topic: z.string().describe("Topic to search for in the transcript"),
  }),
  execute: async ({ topic }, { ctx }) => {
    // ctx.session.chat_ctx.messages expected; adjust based on your runtime
    const messages = ctx.session.chat_ctx.messages || [];
    const transcript = messages.map(m => m.text || "").join(" ").toLowerCase();
    return transcript.includes(topic.toLowerCase());
  },
});
Notes and quick options • Access: Use
context.session.chat_ctx
(Python) or
ctx.session.chat_ctx
(Node) to read messages. • Filtering: Restrict to user messages by checking message role/type before joining. • Robustness: Replace simple substring check with regex, embeddings, or an LLM classifier for fuzzier matches. • Return: Return a boolean; the agent/LLM will receive it as true/false. Do you want the Node.js example adapted to only user messages, or a version that uses an LLM check instead of keyword matching? Sources: Agents and handoffs | LiveKit docs | Tool definition and use | LiveKit docs | Agent speech and audio | LiveKit docs
b
what if this not a programmatic thing to check but more of make LLM analyze if the performance of the candidate was good
t
You're asking how to use an LLM (not a simple keyword check) to evaluate candidate performance from the transcript. Below are a concise plan and runnable examples (Python and Node) that show how to pull the transcript from `RunContext`/`ctx`, prompt an LLM to produce a structured evaluation, and return that result to your agent. 1) Recommended approach (high level) • Pull the full transcript from the session chat context. • Create a clear evaluation prompt that asks the LLM to score or judge specific criteria (e.g., communication, problem-solving, clarity) and return a structured JSON result. • Validate and normalize the LLM output, then return it from the tool (structured object or simplified verdict). • Optionally refine by few-shot examples, rubric, or by running multiple passes (e.g., per-criterion prompts). 2) Python example (LLM-based evaluator)
Copy code
from livekit.agents import Agent, function_tool, RunContext

class EvalAgent(Agent):
    @function_tool()
    async def evaluate_candidate(self, context: RunContext, rubric: dict | None = None) -> dict:
        """Run an LLM-based evaluation over the current transcript and return structured results."""
        chat_ctx = context.session.chat_ctx
        transcript = " ".join((m.text_content() or "") for m in chat_ctx.messages).strip()

        # Build prompt (include rubric or default criteria)
        criteria = rubric or {
            "communication": "Clarity and conciseness",
            "technical": "Problem solving and technical correctness",
            "confidence": "Confidence and composure"
        }
        prompt = (
            "You are an objective interviewer evaluator. Given the transcript below, score each criterion 1-5 "
            f"and provide a short justification. Return a JSON object with keys: scores (map), comments (map), overall (string).\n\n"
            f"Criteria: {criteria}\n\nTranscript:\n{transcript}\n\nRespond only with valid JSON."
        )

        # Call the agent's LLM (pseudo-call; adapt to your LLM API)
        llm_response = await context.agent.llm.chat_prompt(prompt)  # adapt to your LLM call
        content = llm_response.message.content

        # Parse JSON safely
        import json, re
        try:
            json_text = re.search(r"\{.*\}", content, re.S).group(0)
            result = json.loads(json_text)
        except Exception:
            # fallback: wrap as minimal structure
            result = {"scores": {}, "comments": {}, "overall": content}

        return result
3) Node.js example (Zod tool + LLM call)
Copy code
import { z } from "zod";

const evaluateCandidate = llm.tool({
  description: "LLM-based evaluation of candidate performance from transcript.",
  parameters: z.object({
    rubric: z.record(z.string()).optional(),
  }),
  execute: async ({ rubric }, { ctx }) => {
    const messages = (ctx.session.chat_ctx?.messages ?? []).map(m => m.text || "").join(" ").trim();
    const criteria = rubric ?? {
      communication: "Clarity and conciseness",
      technical: "Problem solving and technical correctness",
      confidence: "Confidence and composure",
    };
    const prompt = `You are an objective interviewer evaluator. Given the transcript below, score each criterion 1-5 and provide a short justification. Return valid JSON with keys: scores, comments, overall.\n\nCriteria: ${JSON.stringify(criteria)}\n\nTranscript:\n${messages}\n\nRespond only with JSON.`;
    const resp = await ctx.agent.llm.chat({ input: prompt }); // adapt to your LLM method
    const content = resp.message.content;
    try {
      const jsonText = content.match(/\{[\s\S]*\}/)[0];
      return JSON.parse(jsonText);
    } catch {
      return { scores: {}, comments: {}, overall: content };
    }
  },
});
4) Practical tips • Provide a rubric and examples in the prompt to reduce variance. • Ask for numeric scores plus brief justifications to enable automation. • Validate LLM output (JSON schema) and fallback gracefully. • If you need higher reliability, run per-criterion prompts or ensemble multiple LLM prompts. • Consider privacy/consent for analyzing transcripts. Would you like a ready-to-use prompt template and a strict JSON schema for validation (I can provide both)?