| Windows Live Ag... 的个人资料Windows Live Agents照片日志列表 | 帮助 |
|
3月27日 Logging Topics and CategoriesOne of the most powerful parts of the BuddyScript platform is its extensible reporting suite. This article will describe how to log data relating to what your agent is saying, in a form that can be displayed in the Usage Reporting tab of the web console.
Category and topic logging is something that has been used for agent projects developed "internally," but the code to do this was never exposed to partners in the libraries that ship with the platform. This is likely to change in future releases, but in the meantime feel free to implement the code here.
A topicis a routine with user input, agent output. For example, we may have a routine that associates matching for "how are you" to various outputs saying "I'm doing fine." This is a topic.
A category is a grouping of topics, often associated with a single DDL file. For example, we might have a category for all the topics that handle queries relating to the agent as a person, like "how are you", "where did you come from", etc.
When we associate a title to a topic, we can log that title and keep a tally of how many users hit that topic. When we associate a topic to a category, we can also tally how many times users hit that category. Thus, we will have data relating to where user queries are matching the most, at two levels of granularity.
To get this working, we need to:
1. Define categories 2. Assign topics to categories 3. Log the topics and categories
Here is an example of how to do this:
Say we have a domain for English conversational routines, Topics/EN-US/Conversation.ddl.
At the top of the Topics/EN-US/Conversation.ddl, we add this:
{category="Conversation (English)" label="CategoryDefinition"} + _ignore_me do nothing
This defines a new category called “Conversation (English)”. Next, we need to associate routines to this category. Here is an existing routine:
{label="? Hi" uid="MyAgent-1195066867"} ? Hi - Hi! - Hello there! - Hi there. - Greetings! nop - How are you? - What's new with you? - How are things? insist - Good to know.<br/> - Interesting.<br/> - Glad I asked.<br/> - Really? <br/>
The key-value pairs between brackets ("label" and "uid") were automatically generated by the KMS as part of its tracking mechanism. If they are not present, don't worry about it.
Add this (the order of key-value pairs doesn’t matter):
{category="Conversation (English)" title="Hi" label="? Hi" uid="MyAgent-1195066867"}
Still, we are just labeling the routine, and nothing will happen unless we log it. The platform will automatically do some simple logging, but we should override that to use categories. Look at this part of the libaries, in Required/ABProcs:
######################################## ## ## ABPostQueryLog ## ## This procedure is called at the end of a user query ## and can be overriden to log specific information. ## ########################################
procedure ABPostQueryLog() SYS.Log.ScriptFile[SYS.History[0].Match.ScriptFile]++
processing ABPostQueryLog post-process call ABPostQueryLog()
So, if we just want to know what file is being hit, right now that is being logged as “ScriptFile”, which we could add to usage_config.xml and show in Usage Reporting in the console. However, a better approach is to define categories for every ddl, and assign titles and categories for each topic in the ddl. Then we can override the logging behavior like so:
### Logging
variable G_LAST_LOGGED_QR_RECEPTION_TIME=0
procedure LogCategory(CATEGORY) SYS.Log.Categories[CATEGORY]++
procedure LogTopic(TOPIC_TITLE) SYS.Log.Topics[TOPIC_TITLE]++
procedure PerformTopicLogging() if G_LAST_LOGGED_QR_RECEPTION_TIME == SYS.History[0].Execution.QRReceptionTime exit G_LAST_LOGGED_QR_RECEPTION_TIME = SYS.History[0].Execution.QRReceptionTime if SYS.History[0].Match.RoutineId == "" exit TOPIC_TO_LOG = "" CATEGORY_TO_LOG = "" ROUTINE_ID = SYS.History[0].Match.RoutineId if !ROUTINE_ID exit TOPIC_KEYS = GetRoutineKeys(ROUTINE_ID) if Exist(TOPIC_KEYS["menu"]) exit if !Exist(TOPIC_KEYS["title"]) exit TOPIC_TO_LOG = TOPIC_KEYS["title"] if !Exist(TOPIC_KEYS["category"]) CATEGORY_TO_LOG = "undefined" else CATEGORY_TO_LOG = TOPIC_KEYS["category"] call LogTopic(TOPIC_TO_LOG) call LogCategory(CATEGORY_TO_LOG)
procedure overrides ABPostQueryLog() call PerformTopicLogging()
Note that all we are really doing is piggy-backing on the existing logging mechanism, using it to write the values associated with the “title” and “category” keys for each routine the agent matches to. These values are written to the SYS.Log variable, a special object used for logging. Anything written to SYS.Log is fair game to show in the reporting console, but to do so, we also need to make alterations to the usage_config.xml file, to accommodate SYS.Log.Categories and SYS.Log.Topics and specify how the data should appear. Editing the usage_config.xml file is beyond the scope of the article and will be covered later, so let the WLA team know if you need help setting it up. 3月21日 Data Consumption in BuddyscriptAn important component in creating a good agent is to access and display rich content. Often, this content comes from sources such as data feeds, flat files, SQL databases, or SOAP/RES methods.
There are two common components in Buddyscript that is needed to access, store and retrieve data. They are datatables and datasources.
Datatables are two-dimensional arrays of data that is preloaded into memory. For those of you familiar with SQL databases, these are tables that are pinned in memory. The common sources where datatables are loaded from are from a hard coded list, tab-delimited flat files, SQL tables, or an external source that can return back an array of data.
The datatable statement looks like this:
datatable tablename [propertyoptions] load column1 [, column2...] from source retrievalmethod
For example, to load from a hard-coded list, the statement might look something like this:
datatable MovieGenreTable load GenreCode {index="exact"}, GenreName {index="exact"} from 1, Action 2, Adventure 3, Comedy
This loads a datatable called MovieGenreTable with 3 rows of two columns, GenreCode and GenreName. Both columns are indexed, using an 'exact' index. From the BuddyScript documentation, the types of indexes you can use are as follows:
• exact: the two entries need to be exactly equal. => "exact" = "exact" but "Exact" != "exact" • case-insensitive: the two entries can have different case => "exact" = "eXaCt" but "exact" != "exact?" • thawed: the "thawed" version of the two entries need to be equal => "that's exact" = "$$ThaT %% S&&ExAcT!!", "François" = "fRAncois". This is because the thawed version of both "That's exact!" and of "$$ThaT %% S&&ExAcT??" is "that s exact".
It's slightly faster to access a column indexed as exact, than a column indexed as case-insensitive. thawed indexed columns are the slowest.
To load from a tab-delimited file would look like this:
datatable CitiesMetaTiered load value*, score from file Data/CitiesMetaTiered.txt
This loads a datatable called CitiesMetaTiered into a two column table, the columns being value and score. The file has two columns separated by a tab. The table never expires from memory. The asterisk after the column (as in value*) is a shortcut for an index, with the property of exact.
Accessing the datatable
The way to access the datatable is as follows:
list of variables = get column1, [column2, ...] in datatableName [where columnX is value [and columnY is value2...]] [limit startIndex, count]
Note that this syntax looks fairly similar to the SQL SELECT statement.
For example, using the above datatable definitions, to retrieve data from the datatable called CitiesMetaTiered, a typical statement might look like this:
SEARCHVAR = 'x' V, S = get value, score in CitiesMetaTiered where value is SEARCHVAR limit 1
This will put into the variables V and S the value and score content in the CitiesMetaTiered datatable where the value is 'x'. It will put into the variable the first row that it finds.
Datasources
Datasources are a way to define how data looks when retrieved from an external source. The most useful and common ways to use a datasource is to define a web data feed page, a datatable, or a SQL data table.
For example, to define a web datafeed page, an example might look like this:
datasource dsProductRecall() => ititle, idescription, ipubDate, ilink http http://www.cpsc.gov/cpscpub/prerel/prerelhousehold.xml simple xml channel // title // description // link // language // lastBuildDate // webMaster item {loop="content"} title description pubDate link // guid
This looks at an XML feed called http://www.cpsc.gov/cpscpub/prerel/prerelhousehold.xml.
The XML has master information and item repeating information. The datasource captures node information into the output variables. The output variables are strictly positional based on what is captured from the feed.
The indentation in the datasource definition has to match the same parent-child level of the web page. The {loop="content"} indicates that the variable and all the children variables will repeat and the content put into an array. The // are comment statements, in this particular case, some variables are commented out because the code has no use for the particular data.
In some instances, you would use a datasource instead of a datatable. For example, if you only need part of a table in memory at any one time, it is much better to use a datasource than a datatable.
Here is an example of a datasource that loads from a datatable.
datasource DatGetAllCityInfo(ZIP) => city, state, region, country table get city, state, region, country in CombinedGeography where id is ZIP
This datasource takes in a parameter called ZIP, and will output 4 columns, city, state, region, and country. It gets its output from a datatable, getting city, state, region, country from the datatable called CombinedGeography, and filters for those values in the id column where it is equal to the passed-in value called ZIP.
You can then access a datasource just like a function. For example, using basic Buddyscript syntax:
? What products have been recalled lately? TITLE, DESCRIPTION, PUBDATE, LINK = dsProductRecall() show 5 * Here are the results for product recalls : - TITLE, DESCRIPTION, PUBDATE, LINK
you can also access the datasource function with the OBJ <= datasourcename() statement. This puts the data into an object. When there are multiple rows of data you can indent a block below the datasource call and the block will be looped on. This will give you better display control over each line.
By Carl Moy 3月3日 Tracking ClickThroughsMany clients want to see how much traffic their agent is pushing back to their client’s website. By integrating ClickThrough tracking in your agent, you will be able to track Clicks and Impressions. Impressions are how many times a URL is presented to the user. Clicks are how many times a URL is clicked on by the user.
In order to track ClickThroughs in your project, we must wrap a redirect URL around the real URL. You will need to contact the Agents team to set up a redirect URL for you. Please note that your Agents contact does not personally set up the redirect URL—they must send a request to the Hosting Department. Redirect URL requests can take several days. The Project Manager will send you the redirect URL and you will add the following to your project: 1. Include the following package in a central file, such as YourProject/Shared/YourProject.pkg. This package includes all of the procedures and functions needed to track clicks and impressions in your agent.
lib:/Shared/Utilities/ClickThroughUtilities
2. Override the following function in the same file as above and return the redirect URL your PM sends you. function overrides GetClickThroughBaseUrl() return "http://zz.rdir.us"
When you want to track a URL in your project, you will use the following function: Click ClickThroughLink(“URL”, "here", " ---> ", "TEXT") URL will be replaced with the URL you want to track. TEXT will be what you want displayed in the Usage Reports. For example, if you are tracking the URL http://movies.msn.com/, you will include the following code: Click ClickThroughLink(“http://movies.msn.com/”, "here", " ---> ", "MSN Movies") In the agent output, it will display like so: Click here ---> http://zz.rdir.us/ct?K/0 The Agents team will set up the Usage Reporting site so you can view ClickThrough tracking. There will be a high level graph, displaying Total Clicks, Impressions, etc.:
There will also be separate sections for Impression and Click breakdowns. For example:
|
|
|